diff --git a/lib/presentation/pages/calendar/widgets/recommendation_record_card.dart b/lib/presentation/pages/calendar/widgets/recommendation_record_card.dart index eaeb740..f04c221 100644 --- a/lib/presentation/pages/calendar/widgets/recommendation_record_card.dart +++ b/lib/presentation/pages/calendar/widgets/recommendation_record_card.dart @@ -10,11 +10,15 @@ class RecommendationRecordCard extends ConsumerWidget { final VoidCallback onConfirmVisit; final VoidCallback onDelete; + /// 카드 전체 탭(tap) 시 실행할 콜백. + final VoidCallback? onTap; + const RecommendationRecordCard({ super.key, required this.recommendation, required this.onConfirmVisit, required this.onDelete, + this.onTap, }); String _formatTime(DateTime dateTime) { @@ -43,130 +47,137 @@ class RecommendationRecordCard extends ConsumerWidget { shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), - child: Padding( - padding: const EdgeInsets.all(16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Container( - width: 40, - height: 40, - decoration: BoxDecoration( - color: Colors.orange.withValues(alpha: 0.1), - shape: BoxShape.circle, + child: InkWell( + onTap: onTap, + borderRadius: BorderRadius.circular(12), + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Container( + width: 40, + height: 40, + decoration: BoxDecoration( + color: Colors.orange.withValues(alpha: 0.1), + shape: BoxShape.circle, + ), + child: const Icon( + Icons.whatshot, + color: Colors.orange, + size: 24, + ), ), - child: const Icon( - Icons.whatshot, - color: Colors.orange, - size: 24, - ), - ), - const SizedBox(width: 16), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - restaurant.name, - style: AppTypography.body1( - isDark, - ).copyWith(fontWeight: FontWeight.bold), - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - const SizedBox(height: 4), - Row( - children: [ - Icon( - Icons.category_outlined, - size: 14, - color: isDark - ? AppColors.darkTextSecondary - : AppColors.lightTextSecondary, - ), - const SizedBox(width: 4), - Text( - restaurant.category, - style: AppTypography.caption(isDark), - ), - const SizedBox(width: 8), - Icon( - Icons.access_time, - size: 14, - color: isDark - ? AppColors.darkTextSecondary - : AppColors.lightTextSecondary, - ), - const SizedBox(width: 4), - Text( - _formatTime(recommendation.recommendationDate), - style: AppTypography.caption(isDark), - ), - ], - ), - const SizedBox(height: 8), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Icon( - Icons.info_outline, - size: 16, - color: Colors.orange, - ), - const SizedBox(width: 6), - Expanded( - child: Text( - '추천만 받은 상태입니다. 방문 후 확인을 눌러 주세요.', - style: AppTypography.caption(isDark).copyWith( - color: Colors.orange, - fontWeight: FontWeight.w600, - ), - softWrap: true, - maxLines: 3, - overflow: TextOverflow.visible, + const SizedBox(width: 16), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + restaurant.name, + style: AppTypography.body1( + isDark, + ).copyWith(fontWeight: FontWeight.bold), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + const SizedBox(height: 4), + Row( + children: [ + Icon( + Icons.category_outlined, + size: 14, + color: isDark + ? AppColors.darkTextSecondary + : AppColors.lightTextSecondary, ), - ), - ], - ), - ], + const SizedBox(width: 4), + Text( + restaurant.category, + style: AppTypography.caption(isDark), + ), + const SizedBox(width: 8), + Icon( + Icons.access_time, + size: 14, + color: isDark + ? AppColors.darkTextSecondary + : AppColors.lightTextSecondary, + ), + const SizedBox(width: 4), + Text( + _formatTime( + recommendation.recommendationDate, + ), + style: AppTypography.caption(isDark), + ), + ], + ), + const SizedBox(height: 8), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Icon( + Icons.info_outline, + size: 16, + color: Colors.orange, + ), + const SizedBox(width: 6), + Expanded( + child: Text( + '추천만 받은 상태입니다. 방문 후 확인을 눌러 주세요.', + style: AppTypography.caption(isDark) + .copyWith( + color: Colors.orange, + fontWeight: FontWeight.w600, + ), + softWrap: true, + maxLines: 3, + overflow: TextOverflow.visible, + ), + ), + ], + ), + ], + ), ), - ), - const SizedBox(width: 12), - ElevatedButton( - onPressed: onConfirmVisit, - style: ElevatedButton.styleFrom( - backgroundColor: AppColors.lightPrimary, - foregroundColor: Colors.white, - padding: const EdgeInsets.symmetric(horizontal: 12), - minimumSize: const Size(0, 40), + const SizedBox(width: 12), + ElevatedButton( + onPressed: onConfirmVisit, + style: ElevatedButton.styleFrom( + backgroundColor: AppColors.lightPrimary, + foregroundColor: Colors.white, + padding: const EdgeInsets.symmetric(horizontal: 12), + minimumSize: const Size(0, 40), + ), + child: const Text('방문 확인'), ), - child: const Text('방문 확인'), - ), - ], - ), - const SizedBox(height: 10), - Container( - height: 1, - color: isDark - ? AppColors.darkDivider - : AppColors.lightDivider, - ), - Align( - alignment: Alignment.centerRight, - child: TextButton( - onPressed: onDelete, - style: TextButton.styleFrom( - foregroundColor: Colors.redAccent, - padding: const EdgeInsets.only(top: 6), - minimumSize: const Size(0, 32), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, - ), - child: const Text('삭제'), + ], ), - ), - ], + const SizedBox(height: 10), + Container( + height: 1, + color: isDark + ? AppColors.darkDivider + : AppColors.lightDivider, + ), + Align( + alignment: Alignment.centerRight, + child: TextButton( + onPressed: onDelete, + style: TextButton.styleFrom( + foregroundColor: Colors.redAccent, + padding: const EdgeInsets.only(top: 6), + minimumSize: const Size(0, 32), + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + child: const Text('삭제'), + ), + ), + ], + ), ), ), ); diff --git a/lib/presentation/pages/splash/splash_screen.dart b/lib/presentation/pages/splash/splash_screen.dart index 796422e..7c8f705 100644 --- a/lib/presentation/pages/splash/splash_screen.dart +++ b/lib/presentation/pages/splash/splash_screen.dart @@ -247,13 +247,18 @@ class _SplashScreenState extends State } void _navigateToHome() { + // 권한 요청이 지연되어도 스플래시(Splash) 화면이 멈추지 않도록 최대 5초만 대기한다. + final permissionFuture = _ensurePermissions().timeout( + const Duration(seconds: 5), + onTimeout: () {}, + ); + Future.wait([ - _ensurePermissions(), + permissionFuture, Future.delayed(AppConstants.splashAnimationDuration), - ]).then((_) { - if (mounted) { - context.go('/home'); - } + ]).whenComplete(() { + if (!mounted) return; + context.go('/home'); }); }