import 'package:e_receipt_mobile/domain/entities/login_user.dart'; import 'package:e_receipt_mobile/presentation/auth/logout_view_model.dart'; import 'package:e_receipt_mobile/presentation/home/home_pagination_providers.dart'; import 'package:e_receipt_mobile/presentation/home/merchant_paging_view_model.dart'; import 'package:e_receipt_mobile/presentation/home/widgets/home_drawer.dart'; import 'package:e_receipt_mobile/presentation/home/widgets/merchant_header.dart'; import 'package:e_receipt_mobile/presentation/home/widgets/merchant_list_view.dart'; import 'package:e_receipt_mobile/presentation/terminal/terminal_selection_screen.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; class HomeScreen extends ConsumerWidget { const HomeScreen({required this.user, super.key}); final LoginUser user; @override Widget build(BuildContext context, WidgetRef ref) { final pagingState = ref.watch(merchantPagingViewModelProvider); final pagingViewModel = ref.read(merchantPagingViewModelProvider.notifier); final logoutState = ref.watch(logoutViewModelProvider); final colorScheme = Theme.of(context).colorScheme; final query = ref.watch(merchantSearchQueryProvider); return Scaffold( appBar: AppBar( title: const Text('Merchants'), actions: [ IconButton( tooltip: 'Refresh', onPressed: pagingState.isLoading ? null : () => pagingViewModel.refresh(), icon: const Icon(Icons.refresh), ), ], ), drawer: HomeDrawer( user: user, onLogout: () async { if (logoutState.isLoading) { return; } final shouldLogout = await showDialog( context: context, builder: (context) { return AlertDialog( title: const Text('Logout'), content: const Text('Are you sure you want to logout?'), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(false), child: const Text('Cancel'), ), TextButton( onPressed: () => Navigator.of(context).pop(true), child: const Text('Logout'), ), ], ); }, ); if (shouldLogout != true || !context.mounted) { return; } Navigator.of(context).pop(); // close drawer ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Signed out'), behavior: SnackBarBehavior.floating, ), ); await ref.read(logoutViewModelProvider.notifier).logout(); }, ), body: pagingState.isLoading && pagingState.items.isEmpty ? const Center(child: CircularProgressIndicator()) : pagingState.errorMessage != null && pagingState.items.isEmpty ? Center( child: Padding( padding: EdgeInsets.fromLTRB( 24, 24, 24, MediaQuery.viewPaddingOf(context).bottom + 24, ), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon( Icons.wifi_off_outlined, size: 56, color: colorScheme.onSurfaceVariant, ), const SizedBox(height: 12), Text( 'Failed to load merchants', style: Theme.of(context).textTheme.titleMedium, textAlign: TextAlign.center, ), const SizedBox(height: 6), Text( pagingState.errorMessage!, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: colorScheme.onSurfaceVariant, ), textAlign: TextAlign.center, ), const SizedBox(height: 14), FilledButton.tonal( onPressed: pagingViewModel.refresh, child: const Text('Try again'), ), ], ), ), ) : Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ MerchantHeader( loadedCount: pagingState.items.length, query: query, onQueryChanged: (value) { ref.read(merchantSearchQueryProvider.notifier).state = value; pagingViewModel.setSearchTerm(value); }, onClear: () { ref.read(merchantSearchQueryProvider.notifier).state = ''; pagingViewModel.setSearchTerm(''); }, ), Expanded( child: MerchantListView( merchants: pagingState.items, hasMore: pagingState.hasMore, isLoadingMore: pagingState.isLoadingMore, onRefresh: pagingViewModel.refresh, onMerchantTap: (merchant) { final id = merchant.id; if (id == null) { return; } _openTerminalSelection(context, id, merchant.name ?? '-'); }, onLoadMore: pagingViewModel.loadMore, onEndReached: pagingViewModel.loadMore, ), ), if (pagingState.errorMessage != null && pagingState.items.isNotEmpty) Padding( padding: EdgeInsets.fromLTRB( 16, 8, 16, MediaQuery.viewPaddingOf(context).bottom + 8, ), child: Material( color: colorScheme.errorContainer, borderRadius: BorderRadius.circular(16), child: Padding( padding: const EdgeInsets.all(12), child: Row( children: [ Icon( Icons.error_outline, color: colorScheme.onErrorContainer, ), const SizedBox(width: 10), Expanded( child: Text( pagingState.errorMessage!, style: Theme.of(context).textTheme.bodyMedium ?.copyWith( color: colorScheme.onErrorContainer, ), ), ), const SizedBox(width: 8), TextButton( onPressed: pagingViewModel.loadMore, child: const Text('Retry'), ), ], ), ), ), ), ], ), ); } void _openTerminalSelection( BuildContext context, String merchantId, String merchantName, ) { Navigator.of(context).push( MaterialPageRoute( builder: (_) => TerminalSelectionScreen( merchantId: merchantId, merchantName: merchantName, ), ), ); } }