import 'package:flutter/material.dart'; import '../services/produit_repository.dart'; import '../theme.dart'; import 'home_shell.dart'; /// Écran affiché au lancement pendant la connexion au serveur. /// Évite l'écran blanc : on voit le loader et l'étape en cours, et en cas /// d'échec on peut réessayer ou continuer avec les données hors ligne. class DemarrageScreen extends StatefulWidget { const DemarrageScreen({super.key}); @override State createState() => _DemarrageScreenState(); } class _DemarrageScreenState extends State { bool _fini = false; @override void initState() { super.initState(); _lancer(); } Future _lancer() async { final repo = ProduitRepository.instance; await repo.initialiser(); if (!mounted) return; // Serveur joignable (ou cache déjà rempli) : on entre directement dans l'app. if (repo.connecte || repo.charge) { setState(() => _fini = true); } else { setState(() {}); // affiche l'erreur + bouton Réessayer } } Future _reessayer() async { await ProduitRepository.instance.charger(); if (!mounted) return; final repo = ProduitRepository.instance; if (repo.connecte || repo.charge) setState(() => _fini = true); } @override Widget build(BuildContext context) { if (_fini) return const HomeShell(); final repo = ProduitRepository.instance; return Scaffold( body: SafeArea( child: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 420), child: Padding( padding: const EdgeInsets.symmetric(horizontal: 32), child: ListenableBuilder( listenable: repo, builder: (context, _) { final echec = !repo.enCours && repo.erreur != null; return Column( mainAxisSize: MainAxisSize.min, children: [ Icon( echec ? Icons.cloud_off_rounded : Icons.storefront_rounded, size: 56, color: echec ? const Color(0xFFB26B00) : AppTheme.accent, ), const SizedBox(height: 20), const Text( 'Gestion Prix', style: TextStyle( fontSize: 26, fontWeight: FontWeight.w700, letterSpacing: -0.5, ), ), const SizedBox(height: 36), if (echec) ..._echec(repo) else ..._chargement(repo), ], ); }, ), ), ), ), ), ); } /// Loader + étape en cours juste en dessous. List _chargement(ProduitRepository repo) => [ const SizedBox( width: 34, height: 34, child: CircularProgressIndicator(strokeWidth: 3), ), const SizedBox(height: 18), Text( repo.etape.isEmpty ? 'Démarrage…' : repo.etape, textAlign: TextAlign.center, style: const TextStyle( fontSize: 14.5, fontWeight: FontWeight.w500, color: AppTheme.grisTexte, ), ), const SizedBox(height: 6), Text( repo.serveurUrl, textAlign: TextAlign.center, style: const TextStyle(fontSize: 12, color: AppTheme.grisTexte), ), ]; /// Serveur injoignable et aucun produit en cache : on explique et on propose. List _echec(ProduitRepository repo) => [ const Text( 'Serveur injoignable', style: TextStyle(fontSize: 17, fontWeight: FontWeight.w700), ), const SizedBox(height: 8), Text( repo.serveurUrl, textAlign: TextAlign.center, style: const TextStyle(fontSize: 12.5, color: AppTheme.grisTexte), ), const SizedBox(height: 10), const Text( 'Vérifie que le serveur est allumé et que la tablette est bien ' 'connectée au réseau (Tailscale actif).', textAlign: TextAlign.center, style: TextStyle(fontSize: 13, color: AppTheme.grisTexte), ), const SizedBox(height: 28), FilledButton.icon( onPressed: _reessayer, icon: const Icon(Icons.refresh), label: const Text('Réessayer'), ), const SizedBox(height: 10), TextButton( onPressed: () => setState(() => _fini = true), child: const Text('Continuer hors ligne'), ), ]; }