/// Page: Home Page /// /// Main dashboard screen of the Worker app. /// Displays member card, promotions, and quick action sections. library; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:worker/core/router/app_router.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/home/presentation/providers/member_card_provider.dart'; import 'package:worker/features/home/presentation/providers/promotions_provider.dart'; import 'package:worker/features/home/presentation/widgets/member_card_widget.dart'; import 'package:worker/features/home/presentation/widgets/promotion_slider.dart'; import 'package:worker/features/home/presentation/widgets/quick_action_section.dart'; import 'package:worker/generated/l10n/app_localizations.dart'; /// Home Page /// /// Main entry point of the app after login. /// Shows: /// - Member card (Diamond/Platinum/Gold) /// - Promotional banners /// - Quick action sections /// - Bottom navigation /// - Floating action button (Chat) class HomePage extends ConsumerWidget { const HomePage({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final l10n = AppLocalizations.of(context); // Watch member card state final memberCardAsync = ref.watch(memberCardProvider); // Watch promotions state final promotionsAsync = ref.watch(promotionsProvider); return Scaffold( backgroundColor: const Color(0xFFF4F6F8), // --background-gray from CSS body: CustomScrollView( slivers: [ // Add top padding for status bar SliverPadding( padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top), ), // Member Card Section SliverToBoxAdapter( child: memberCardAsync.when( data: (memberCard) => MemberCardWidget(memberCard: memberCard), loading: () => Container( margin: const EdgeInsets.all(16), height: 200, decoration: BoxDecoration( color: AppColors.grey100, borderRadius: BorderRadius.circular(16), ), child: const Center(child: CircularProgressIndicator()), ), error: (error, stack) => Container( margin: const EdgeInsets.all(16), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppColors.danger.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(16), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon( Icons.error_outline, color: AppColors.danger, size: 48, ), const SizedBox(height: 8), Text( l10n.error, style: const TextStyle( color: AppColors.danger, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 4), Text( error.toString(), style: const TextStyle( color: AppColors.grey500, fontSize: 12, ), textAlign: TextAlign.center, ), ], ), ), ), ), // Promotions Section SliverToBoxAdapter( child: promotionsAsync.when( data: (promotions) => promotions.isNotEmpty ? PromotionSlider( promotions: promotions, onPromotionTap: (promotion) { // TODO: Navigate to promotion details ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( '${l10n.viewDetails}: ${promotion.title}', ), ), ); }, ) : const SizedBox.shrink(), loading: () => const Padding( padding: EdgeInsets.all(16), child: Center(child: CircularProgressIndicator()), ), error: (error, stack) => const SizedBox.shrink(), ), ), // Quick Action Sections SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Column( children: [ // Products & Cart Section QuickActionSection( title: 'Sản phẩm & Giỏ hàng', actions: [ QuickAction( icon: Icons.grid_view, label: 'Sản phẩm', onTap: () => context.pushNamed(RouteNames.products), ), QuickAction( icon: Icons.shopping_cart, label: 'Giỏ hàng', badge: '3', onTap: () => _showComingSoon(context, 'Giỏ hàng', l10n), ), QuickAction( icon: Icons.favorite, label: 'Yêu thích', onTap: () => _showComingSoon(context, 'Yêu thích', l10n), ), ], ), // Loyalty Section QuickActionSection( title: 'Khách hàng thân thiết', actions: [ QuickAction( icon: Icons.add_circle_outline, label: 'Ghi nhận điểm', onTap: () => _showComingSoon(context, 'Ghi nhận điểm', l10n), ), QuickAction( icon: Icons.card_giftcard, label: 'Đổi quà', onTap: () => _showComingSoon(context, 'Đổi quà', l10n), ), QuickAction( icon: Icons.history, label: 'Lịch sử điểm', onTap: () => _showComingSoon(context, 'Lịch sử điểm', l10n), ), ], ), // Orders & Payments Section QuickActionSection( title: 'Đơn hàng & thanh toán', actions: [ QuickAction( icon: Icons.description, label: 'Yêu cầu báo giá', onTap: () => _showComingSoon(context, 'Yêu cầu báo giá', l10n), ), QuickAction( icon: Icons.inventory_2, label: 'Đơn hàng', onTap: () => _showComingSoon(context, 'Đơn hàng', l10n), ), QuickAction( icon: Icons.receipt_long, label: 'Thanh toán', onTap: () => _showComingSoon(context, 'Thanh toán', l10n), ), ], ), // Sample Houses & News Section QuickActionSection( title: 'Nhà mẫu, dự án & tin tức', actions: [ QuickAction( icon: Icons.home_work, label: 'Nhà mẫu', onTap: () => _showComingSoon(context, 'Nhà mẫu', l10n), ), QuickAction( icon: Icons.business, label: 'Đăng ký dự án', onTap: () => _showComingSoon(context, 'Đăng ký dự án', l10n), ), QuickAction( icon: Icons.article, label: 'Tin tức', onTap: () => _showComingSoon(context, 'Tin tức', l10n), ), ], ), // Bottom Padding (for FAB and bottom nav clearance) const SizedBox(height: 100), ], ), ), ), ], ), // Floating Action Button (Chat) - positioned like HTML: bottom: 90px floatingActionButton: Padding( padding: const EdgeInsets.only(bottom: 20), // 90px - 70px (bottom nav) child: FloatingActionButton( onPressed: () => _showComingSoon(context, l10n.chat, l10n), backgroundColor: AppColors.accentCyan, elevation: 8, child: const Icon(Icons.chat_bubble, size: 24, color: Colors.white), ), ), // Bottom Navigation Bar bottomNavigationBar: Container( decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withValues(alpha: 0.05), blurRadius: 10, offset: const Offset(0, -2), ), ], ), child: SafeArea( child: SizedBox( height: 70, child: BottomNavigationBar( type: BottomNavigationBarType.fixed, backgroundColor: Colors.white, selectedItemColor: AppColors.primaryBlue, unselectedItemColor: const Color(0xFF666666), selectedFontSize: 11, unselectedFontSize: 11, iconSize: 24, currentIndex: 0, elevation: 0, items: [ BottomNavigationBarItem( icon: const Icon(Icons.home), label: 'Trang chủ', ), BottomNavigationBarItem( icon: const Icon(Icons.loyalty), label: 'Hội viên', ), BottomNavigationBarItem( icon: const Icon(Icons.local_offer), label: 'Khuyến mãi', ), BottomNavigationBarItem( icon: Stack( clipBehavior: Clip.none, children: [ const Icon(Icons.notifications), Positioned( top: -4, right: -4, child: Container( padding: const EdgeInsets.symmetric( horizontal: 6, vertical: 2, ), decoration: BoxDecoration( color: AppColors.danger, borderRadius: BorderRadius.circular(12), ), constraints: const BoxConstraints( minWidth: 20, minHeight: 20, ), child: const Text( '5', style: TextStyle( color: Colors.white, fontSize: 11, fontWeight: FontWeight.w700, ), textAlign: TextAlign.center, ), ), ), ], ), label: 'Thông báo', ), BottomNavigationBarItem( icon: const Icon(Icons.account_circle), label: 'Cài đặt', ), ], onTap: (index) { // TODO: Implement navigation final labels = [ 'Trang chủ', 'Hội viên', 'Khuyến mãi', 'Thông báo', 'Cài đặt', ]; _showComingSoon(context, labels[index], l10n); }, ), ), ), ), ); } /// Show coming soon message void _showComingSoon( BuildContext context, String feature, AppLocalizations l10n, ) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('$feature - ${l10n.comingSoon}'), duration: const Duration(seconds: 1), ), ); } }