fix(calendar): 월별 방문 카테고리 집계 반영
This commit is contained in:
@@ -22,6 +22,12 @@ class VisitStatistics extends ConsumerWidget {
|
||||
month: selectedMonth.month,
|
||||
)),
|
||||
);
|
||||
final monthlyCategoryStatsAsync = ref.watch(
|
||||
monthlyCategoryVisitStatsProvider((
|
||||
year: selectedMonth.year,
|
||||
month: selectedMonth.month,
|
||||
)),
|
||||
);
|
||||
|
||||
// 자주 방문한 맛집
|
||||
final frequentRestaurantsAsync = ref.watch(frequentRestaurantsProvider);
|
||||
@@ -34,7 +40,11 @@ class VisitStatistics extends ConsumerWidget {
|
||||
child: Column(
|
||||
children: [
|
||||
// 이번 달 통계
|
||||
_buildMonthlyStats(monthlyStatsAsync, isDark),
|
||||
_buildMonthlyStats(
|
||||
monthlyStatsAsync,
|
||||
monthlyCategoryStatsAsync,
|
||||
isDark,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
const NativeAdPlaceholder(height: 360),
|
||||
@@ -53,6 +63,7 @@ class VisitStatistics extends ConsumerWidget {
|
||||
|
||||
Widget _buildMonthlyStats(
|
||||
AsyncValue<Map<String, int>> statsAsync,
|
||||
AsyncValue<Map<String, int>> categoryStatsAsync,
|
||||
bool isDark,
|
||||
) {
|
||||
return Card(
|
||||
@@ -75,9 +86,17 @@ class VisitStatistics extends ConsumerWidget {
|
||||
0,
|
||||
(sum, count) => sum + count,
|
||||
);
|
||||
final categoryCounts =
|
||||
stats.entries.where((e) => !e.key.contains('/')).toList()
|
||||
final categoryCounts = categoryStatsAsync.maybeWhen(
|
||||
data: (data) {
|
||||
final entries = data.entries.toList()
|
||||
..sort((a, b) => b.value.compareTo(a.value));
|
||||
return entries;
|
||||
},
|
||||
orElse: () => <MapEntry<String, int>>[],
|
||||
);
|
||||
final topCategory = categoryCounts.isNotEmpty
|
||||
? categoryCounts.first
|
||||
: null;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
@@ -89,12 +108,21 @@ class VisitStatistics extends ConsumerWidget {
|
||||
isDark: isDark,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
if (categoryCounts.isNotEmpty) ...[
|
||||
if (topCategory != null) ...[
|
||||
_buildStatItem(
|
||||
icon: Icons.favorite,
|
||||
label: '가장 많이 간 카테고리',
|
||||
value:
|
||||
'${categoryCounts.first.key} (${categoryCounts.first.value}회)',
|
||||
value: '${topCategory.key} (${topCategory.value}회)',
|
||||
color: AppColors.lightSecondary,
|
||||
isDark: isDark,
|
||||
),
|
||||
] else ...[
|
||||
_buildStatItem(
|
||||
icon: Icons.favorite_border,
|
||||
label: '가장 많이 간 카테고리',
|
||||
value: categoryStatsAsync.isLoading
|
||||
? '집계 중...'
|
||||
: '데이터 없음',
|
||||
color: AppColors.lightSecondary,
|
||||
isDark: isDark,
|
||||
),
|
||||
|
||||
@@ -35,6 +35,34 @@ final monthlyVisitStatsProvider =
|
||||
return repository.getMonthlyVisitStats(params.year, params.month);
|
||||
});
|
||||
|
||||
/// 월별 카테고리별 방문 통계 Provider
|
||||
final monthlyCategoryVisitStatsProvider =
|
||||
FutureProvider.family<Map<String, int>, ({int year, int month})>((
|
||||
ref,
|
||||
params,
|
||||
) async {
|
||||
final repository = ref.watch(visitRepositoryProvider);
|
||||
final restaurants = await ref.watch(restaurantListProvider.future);
|
||||
|
||||
final records = await repository.getVisitRecordsByDateRange(
|
||||
startDate: DateTime(params.year, params.month, 1),
|
||||
endDate: DateTime(params.year, params.month + 1, 0),
|
||||
);
|
||||
|
||||
final categoryCount = <String, int>{};
|
||||
for (final record in records) {
|
||||
final restaurant = restaurants
|
||||
.where((r) => r.id == record.restaurantId)
|
||||
.firstOrNull;
|
||||
if (restaurant == null) continue;
|
||||
|
||||
categoryCount[restaurant.category] =
|
||||
(categoryCount[restaurant.category] ?? 0) + 1;
|
||||
}
|
||||
|
||||
return categoryCount;
|
||||
});
|
||||
|
||||
/// 방문 기록 관리 StateNotifier
|
||||
class VisitNotifier extends StateNotifier<AsyncValue<void>> {
|
||||
final VisitRepository _repository;
|
||||
|
||||
Reference in New Issue
Block a user