feat(debug): add preview toggles and auto-close ads

- 기록/통계 탭에 디버그 토글 배너 추가 및 테스트 데이터 주입 로직 상태화\n- 리스트 공유 화면에 디버그 프리뷰 토글, 광고 관문, 디버그 전송 흐름 반영\n- 모의 전면 광고는 대기 시간 종료 시 자동 완료되도록 변경\n- AGENTS.md에 코멘트는 한국어로 작성 규칙 명시\n\n테스트: flutter analyze; flutter test
This commit is contained in:
JiWoong Sul
2025-12-02 15:24:34 +09:00
parent 69902bbc30
commit df4c34194c
7 changed files with 801 additions and 34 deletions

View File

@@ -1,3 +1,4 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:table_calendar/table_calendar.dart';
@@ -6,10 +7,12 @@ import '../../../core/constants/app_typography.dart';
import '../../../domain/entities/recommendation_record.dart';
import '../../../domain/entities/visit_record.dart';
import '../../providers/recommendation_provider.dart';
import '../../providers/debug_test_data_provider.dart';
import '../../providers/visit_provider.dart';
import 'widgets/visit_record_card.dart';
import 'widgets/recommendation_record_card.dart';
import 'widgets/visit_statistics.dart';
import 'widgets/debug_test_data_banner.dart';
class CalendarScreen extends ConsumerStatefulWidget {
const CalendarScreen({super.key});
@@ -32,6 +35,11 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen>
_selectedDay = DateTime.now();
_focusedDay = DateTime.now();
_tabController = TabController(length: 2, vsync: this);
if (kDebugMode) {
Future.microtask(
() => ref.read(debugTestDataNotifierProvider.notifier).initialize(),
);
}
}
@override
@@ -100,6 +108,10 @@ class _CalendarScreenState extends ConsumerState<CalendarScreen>
return Column(
children: [
if (kDebugMode)
const DebugTestDataBanner(
margin: EdgeInsets.fromLTRB(16, 16, 16, 8),
),
// 캘린더
Card(
margin: const EdgeInsets.all(16),

View File

@@ -0,0 +1,92 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lunchpick/core/constants/app_colors.dart';
import 'package:lunchpick/core/constants/app_typography.dart';
import 'package:lunchpick/presentation/providers/debug_test_data_provider.dart';
class DebugTestDataBanner extends ConsumerWidget {
final EdgeInsetsGeometry? margin;
const DebugTestDataBanner({super.key, this.margin});
@override
Widget build(BuildContext context, WidgetRef ref) {
if (!kDebugMode) {
return const SizedBox.shrink();
}
final isDark = Theme.of(context).brightness == Brightness.dark;
final state = ref.watch(debugTestDataNotifierProvider);
final notifier = ref.read(debugTestDataNotifierProvider.notifier);
return Card(
margin: margin ?? const EdgeInsets.all(16),
color: isDark ? AppColors.darkSurface : AppColors.lightSurface,
elevation: 1,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
padding: const EdgeInsets.all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Icon(
Icons.science_outlined,
color: AppColors.lightPrimary,
size: 20,
),
const SizedBox(width: 8),
Text(
'테스트 데이터 미리보기',
style: AppTypography.body1(
isDark,
).copyWith(fontWeight: FontWeight.w600),
),
const Spacer(),
if (state.isProcessing)
const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2),
),
const SizedBox(width: 8),
Switch.adaptive(
value: state.isEnabled,
onChanged: state.isProcessing
? null
: (value) async {
if (value) {
await notifier.enableTestData();
} else {
await notifier.disableTestData();
}
},
activeColor: AppColors.lightPrimary,
),
],
),
const SizedBox(height: 8),
Text(
state.isEnabled
? '디버그 빌드에서만 적용됩니다. 기록/통계 UI를 테스트용 데이터로 확인하세요.'
: '디버그 빌드에서만 사용 가능합니다. 스위치를 켜면 추천·방문 기록이 자동으로 채워집니다.',
style: AppTypography.caption(isDark),
),
if (state.errorMessage != null) ...[
const SizedBox(height: 6),
Text(
state.errorMessage!,
style: AppTypography.caption(isDark).copyWith(
color: AppColors.lightError,
fontWeight: FontWeight.w600,
),
),
],
],
),
),
);
}
}

View File

@@ -1,9 +1,11 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lunchpick/core/constants/app_colors.dart';
import 'package:lunchpick/core/constants/app_typography.dart';
import 'package:lunchpick/presentation/providers/visit_provider.dart';
import 'package:lunchpick/presentation/providers/restaurant_provider.dart';
import 'package:lunchpick/presentation/pages/calendar/widgets/debug_test_data_banner.dart';
class VisitStatistics extends ConsumerWidget {
final DateTime selectedMonth;
@@ -32,6 +34,10 @@ class VisitStatistics extends ConsumerWidget {
padding: const EdgeInsets.all(16),
child: Column(
children: [
if (kDebugMode) ...[
const DebugTestDataBanner(margin: EdgeInsets.zero),
const SizedBox(height: 12),
],
// 이번 달 통계
_buildMonthlyStats(monthlyStatsAsync, isDark),
const SizedBox(height: 16),
@@ -130,7 +136,7 @@ class VisitStatistics extends ConsumerWidget {
: stats.values.reduce((a, b) => a > b ? a : b);
return SizedBox(
height: 120,
height: 140,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.end,