import 'package:flutter/material.dart'; import 'package:p_tits_pas/models/dossier_unifie.dart'; import 'package:p_tits_pas/services/user_service.dart'; import 'package:p_tits_pas/widgets/admin/validation_am_wizard.dart'; import 'package:p_tits_pas/widgets/admin/validation_family_wizard.dart'; /// Modale (dialog) : charge le dossier par numéro puis affiche le wizard AM ou Famille. Ticket #107, #119. class ValidationDossierModal extends StatefulWidget { final String numeroDossier; final VoidCallback onClose; final VoidCallback? onSuccess; const ValidationDossierModal({ super.key, required this.numeroDossier, required this.onClose, this.onSuccess, }); @override State createState() => _ValidationDossierModalState(); } class _ValidationDossierModalState extends State { bool _loading = true; String? _error; DossierUnifie? _dossier; int? _stepIndex; int? _stepTotal; void _onStepChanged(int step, int total) { // step = 0-based dans les wizards, affichage 1-based dans l'en-tête. if (!mounted) return; setState(() { _stepIndex = step; _stepTotal = total; }); } @override void initState() { super.initState(); _load(); } Future _load() async { setState(() { _loading = true; _error = null; _dossier = null; _stepIndex = null; _stepTotal = null; }); try { final d = await UserService.getDossier(widget.numeroDossier); if (!mounted) return; setState(() { _dossier = d; _loading = false; }); } catch (e) { if (!mounted) return; setState(() { _error = e is Exception ? e.toString().replaceFirst('Exception: ', '') : 'Erreur inconnue'; _loading = false; }); } } void _onSuccess() { widget.onSuccess?.call(); // La modale est fermée par l’appelant dans onSuccess (Navigator.pop). } /// Largeur modale = 1,5 × 620. static const double _modalWidth = 930; // 620 * 1.5 // Hauteur uniforme (ajustée +5px pour éviter l'overflow des étapes parents sans scroll). static const double _bodyHeight = 435; @override Widget build(BuildContext context) { final maxH = MediaQuery.of(context).size.height * 0.85; final showStep = _stepIndex != null && _stepTotal != null && (_stepTotal ?? 0) > 0; return Dialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), child: ConstrainedBox( constraints: BoxConstraints(maxWidth: _modalWidth, maxHeight: maxH), child: Column( mainAxisSize: MainAxisSize.min, children: [ Row( children: [ Padding( padding: const EdgeInsets.fromLTRB(18, 18, 0, 12), child: Text( 'Dossier ${widget.numeroDossier}', style: const TextStyle( fontSize: 18, fontWeight: FontWeight.w700), ), ), const Spacer(), if (showStep) ...[ Text( 'Étape ${(_stepIndex ?? 0) + 1}/${_stepTotal ?? 1}', style: Theme.of(context).textTheme.titleSmall?.copyWith( color: Colors.black54, fontStyle: FontStyle.italic, ), ), const SizedBox(width: 8), ], IconButton( icon: const Icon(Icons.close), onPressed: widget.onClose, tooltip: 'Fermer', ), ], ), const Divider(height: 1), SizedBox( height: _bodyHeight, child: _buildBody(), ), ], ), ), ); } Widget _buildBody() { if (_loading) { return const Padding( padding: EdgeInsets.all(48), child: Center(child: CircularProgressIndicator()), ); } if (_error != null && _error!.isNotEmpty) { return Padding( padding: const EdgeInsets.all(24), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text(_error!, style: const TextStyle(color: Colors.red), textAlign: TextAlign.center), const SizedBox(height: 16), ElevatedButton(onPressed: _load, child: const Text('Réessayer')), const SizedBox(height: 8), TextButton(onPressed: widget.onClose, child: const Text('Fermer')), ], ), ); } final d = _dossier!; if (d.isAm) { return ValidationAmWizard( dossier: d.asAm, onClose: widget.onClose, onSuccess: _onSuccess, onStepChanged: _onStepChanged, ); } return ValidationFamilyWizard( dossier: d.asFamily, onClose: widget.onClose, onSuccess: _onSuccess, onStepChanged: _onStepChanged, ); } }