import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../core/auth/auth_provider.dart'; import '../../../core/router/app_router.dart'; import '../../../core/theme/app_colors.dart'; import '../../../core/widgets/empty_state.dart'; import '../../../core/widgets/machine_widgets.dart'; import '../../establishments/data/establishment_repository.dart'; import '../../establishments/domain/establishment.dart'; import '../../wash/data/wash_repository.dart'; /// Tableau de bord — vue d'ensemble inspirée WashOnline, plus moderne. class HomeScreen extends ConsumerWidget { const HomeScreen({super.key}); @override Widget build(BuildContext context, WidgetRef ref) { final establishmentsAsync = ref.watch(establishmentsProvider); final washesAsync = ref.watch(washesProvider); final user = ref.watch(authProvider).user; return establishmentsAsync.when( loading: () => const Center(child: CircularProgressIndicator()), error: (error, _) => EmptyState( icon: Icons.cloud_off_outlined, title: 'Connexion impossible', subtitle: 'Vérifiez que l\'API est démarrée\net que vous êtes sur le même réseau.', actionLabel: 'Réessayer', onAction: () => ref.invalidate(establishmentsProvider), ), data: (establishments) { if (establishments.isEmpty) { return const EmptyState( icon: Icons.storefront_outlined, title: 'Aucune laverie', subtitle: 'Aucun établissement disponible pour le moment.', ); } final activeWash = washesAsync.maybeWhen( data: (washes) { for (final wash in washes) { if (wash.status == 'running' || wash.status == 'pending_start' || wash.status == 'active') { return wash; } } return null; }, orElse: () => null, ); return RefreshIndicator( onRefresh: () async { ref.invalidate(establishmentsProvider); ref.invalidate(washesProvider); }, child: ListView( padding: const EdgeInsets.fromLTRB(16, 8, 16, 24), children: [ Text( user?.firstName != null ? 'Bonjour ${user!.firstName} 👋' : 'Bienvenue', style: Theme.of(context).textTheme.headlineMedium?.copyWith(fontSize: 20), ), const SizedBox(height: 4), Text( 'Votre laverie, dans votre poche.', style: Theme.of(context).textTheme.bodyMedium, ), const SizedBox(height: 16), const QuickActionsRow(), if (activeWash != null) ...[ const SizedBox(height: 16), ActiveWashBanner( machineName: activeWash.machineName, onTap: () => context.go(AppRoutes.washes), ), ], const SizedBox(height: 24), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Mes laveries', style: Theme.of(context).textTheme.titleMedium), Text( '${establishments.length}', style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: AppColors.primary, fontWeight: FontWeight.w600, ), ), ], ), const SizedBox(height: 10), ...establishments.map( (establishment) => Padding( padding: const EdgeInsets.only(bottom: 10), child: _EstablishmentCard( establishment: establishment, onTap: () => context.push('/establishments/${establishment.uuid}'), ), ), ), ], ), ); }, ); } } class _EstablishmentCard extends StatelessWidget { const _EstablishmentCard({ required this.establishment, required this.onTap, }); final Establishment establishment; final VoidCallback onTap; @override Widget build(BuildContext context) { return Card( clipBehavior: Clip.antiAlias, child: InkWell( onTap: onTap, child: Padding( padding: const EdgeInsets.all(16), child: Row( children: [ Container( width: 48, height: 48, decoration: BoxDecoration( gradient: AppColors.gradientPrimary, borderRadius: BorderRadius.circular(12), ), child: const Icon(Icons.storefront_rounded, color: Colors.white), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(establishment.name, style: Theme.of(context).textTheme.titleMedium), const SizedBox(height: 2), Text( establishment.fullAddress, maxLines: 2, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.bodyMedium, ), const SizedBox(height: 8), Row( children: [ Icon(Icons.grid_view_rounded, size: 14, color: AppColors.primary.withValues(alpha: 0.8)), const SizedBox(width: 4), const Text( 'Voir les machines', style: TextStyle( color: AppColors.primary, fontSize: 12, fontWeight: FontWeight.w600, ), ), ], ), ], ), ), const Icon(Icons.chevron_right, color: AppColors.textSecondary), ], ), ), ), ); } }