import "package:flutter/material.dart"; import "package:google_fonts/google_fonts.dart"; import "../demo_identity.dart"; import "../theme/ensup_colors.dart"; import "../models/emprunt_item.dart"; import "../models/anomalie_retour.dart"; import "../widgets/ensup_top_bar.dart"; import "../widgets/brand_corners.dart"; class ResultatRetourScreen extends StatelessWidget { const ResultatRetourScreen({ super.key, required this.emprunt, required this.anomalies, }); final EmpruntItem emprunt; final List anomalies; bool get _conforme => emprunt.statut == "CLOTURE"; bool get _enAttente => emprunt.statut == "EN_ATTENTE_VALIDATION_RETOUR"; static String _deux(int valeur) => valeur.toString().padLeft(2, "0"); @override Widget build(BuildContext context) { final fond = _conforme ? const [Color(0xFFF0FDF4), Color(0xFFF8FAFC)] : _enAttente ? const [Color(0xFFFFF7ED), Color(0xFFF8FAFC)] : const [Color(0xFFFFF5F5), Color(0xFFF8FAFC)]; return Scaffold( backgroundColor: EnsupColors.soft, body: Stack( children: [ Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 1280, maxHeight: 820), child: Container( margin: const EdgeInsets.all(24), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: EnsupColors.text.withValues(alpha: 0.14), blurRadius: 60, offset: const Offset(0, 18), ), ], ), clipBehavior: Clip.antiAlias, child: Column( children: [ EnsupTopBar( brandText: "EME · Résultat du contrôle", campusTag: DemoIdentity.campusTag, ), Expanded( child: DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: fond, ), ), child: Center( child: SingleChildScrollView( padding: const EdgeInsets.symmetric( horizontal: 28, vertical: 32, ), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 560), child: Column( children: [ if (_conforme) _succes() else if (_enAttente) _attente() else _anomalie(), const SizedBox(height: 16), SizedBox( width: double.infinity, child: FilledButton.icon( onPressed: () => Navigator.of(context).popUntil( (route) => route.settings.name == "home", ), icon: const Icon( Icons.home_outlined, size: 18, ), label: Text( "Retour à l'accueil", style: GoogleFonts.darkerGrotesque( fontWeight: FontWeight.w700, fontSize: 16, ), ), style: FilledButton.styleFrom( backgroundColor: EnsupColors.cyan, padding: const EdgeInsets.symmetric( vertical: 16, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular( 10, ), ), ), ), ), ], ), ), ), ), ), ), ], ), ), ), ), const Positioned.fill(child: BrandCorners()), ], ), ); } Widget _succes() { return Container( width: double.infinity, padding: const EdgeInsets.all(36), decoration: BoxDecoration( gradient: const LinearGradient( colors: [Color(0xFFF0FDF4), Color(0xFFECFDF5)], ), borderRadius: BorderRadius.circular(16), border: Border.all(color: const Color(0xFFBBF7D0), width: 2), ), child: Column( children: [ Container( width: 72, height: 72, decoration: const BoxDecoration( shape: BoxShape.circle, gradient: LinearGradient( colors: [Color(0xFF16A34A), Color(0xFF22C55E)], ), ), child: const Icon(Icons.check, color: Colors.white, size: 36), ), const SizedBox(height: 18), Text( "Retour conforme", style: GoogleFonts.darkerGrotesque( fontSize: 28, fontWeight: FontWeight.w900, color: const Color(0xFF15803D), ), ), const SizedBox(height: 8), Text( "L'emprunt a été clôturé et le matériel est de nouveau disponible.", textAlign: TextAlign.center, style: GoogleFonts.titilliumWeb( fontSize: 14, color: const Color(0xFF166534), ), ), ], ), ); } Widget _anomalie() { final now = DateTime.now(); final date = "${_deux(now.day)}/${_deux(now.month)}/${now.year} · ${_deux(now.hour)}:${_deux(now.minute)}"; return Column( children: [ Container( width: double.infinity, padding: const EdgeInsets.all(18), decoration: BoxDecoration( color: EnsupColors.red.withValues(alpha: 0.06), borderRadius: BorderRadius.circular(12), border: Border.all( color: EnsupColors.red.withValues(alpha: 0.2), width: 1.5, ), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Icon( Icons.warning_amber_rounded, color: EnsupColors.red, size: 24, ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "Retour non conforme — Anomalie détectée", style: GoogleFonts.darkerGrotesque( fontSize: 17, fontWeight: FontWeight.w800, color: EnsupColors.red, ), ), const SizedBox(height: 4), Text( "Une différence a été constatée avec la checklist de départ. Une anomalie " "a été créée automatiquement et le responsable matériel a été notifié.", style: GoogleFonts.titilliumWeb( fontSize: 13, color: EnsupColors.text2, height: 1.5, ), ), ], ), ), ], ), ), const SizedBox(height: 16), Container( width: double.infinity, padding: const EdgeInsets.all(18), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), border: Border.all(color: EnsupColors.line, width: 1.5), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "DÉTAIL DE L'ANOMALIE", style: GoogleFonts.darkerGrotesque( fontSize: 12, fontWeight: FontWeight.w700, color: EnsupColors.muted, letterSpacing: 0.6, ), ), const SizedBox(height: 10), for (final anomalie in anomalies) _drow( anomalie.element, anomalie.etatRetour, valeurCouleur: EnsupColors.red, ), _drow( "Matériel", "${emprunt.materiel.nom} · ${emprunt.materiel.reference}", ), _drow("Emprunteur", DemoIdentity.userName), _drow("Date détection", date), ], ), ), const SizedBox(height: 14), Text( "Le responsable matériel traitera cette anomalie. Vous pouvez retourner à l'accueil.", textAlign: TextAlign.center, style: GoogleFonts.titilliumWeb( fontSize: 13, color: EnsupColors.muted, height: 1.6, ), ), ], ); } Widget _attente() { return Column( children: [ Container( width: double.infinity, padding: const EdgeInsets.all(22), decoration: BoxDecoration( color: const Color(0xFFFFF7ED), borderRadius: BorderRadius.circular(12), border: Border.all(color: const Color(0xFFFED7AA), width: 1.5), ), child: Column( children: [ const Icon( Icons.pending_actions_outlined, color: Color(0xFFD97706), size: 42, ), const SizedBox(height: 12), Text( "Changement en attente", style: GoogleFonts.darkerGrotesque( fontSize: 26, fontWeight: FontWeight.w900, color: const Color(0xFF9A3412), ), ), const SizedBox(height: 8), Text( "Le responsable a été alerté. Le changement reste provisoire " "et aucune anomalie n'est créée avant sa confirmation.", textAlign: TextAlign.center, style: GoogleFonts.titilliumWeb( fontSize: 14, color: EnsupColors.text2, height: 1.5, ), ), ], ), ), const SizedBox(height: 16), Container( width: double.infinity, padding: const EdgeInsets.all(18), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), border: Border.all(color: EnsupColors.line), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "MODIFICATIONS DÉCLARÉES", style: GoogleFonts.darkerGrotesque( fontSize: 12, fontWeight: FontWeight.w700, color: EnsupColors.muted, ), ), const SizedBox(height: 8), for (final anomalie in anomalies) _drow( anomalie.element, anomalie.etatRetour, valeurCouleur: const Color(0xFFD97706), ), ], ), ), ], ); } Widget _drow(String cle, String valeur, {Color? valeurCouleur}) { return Padding( padding: const EdgeInsets.symmetric(vertical: 7), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( cle, style: GoogleFonts.titilliumWeb( fontSize: 13, color: EnsupColors.muted, ), ), const SizedBox(width: 16), Expanded( child: Text( valeur, textAlign: TextAlign.right, style: GoogleFonts.titilliumWeb( fontSize: 13, fontWeight: FontWeight.w600, color: valeurCouleur ?? EnsupColors.text, ), ), ), ], ), ); } }