feat(front): câbler PATCH refus utilisateur depuis wizards validation (#110)

- UserService.refuseUser → /users/:id/refuser
- AM + famille : envoi motifs, onSuccess + refresh liste
- Famille : refus séquentiel pour chaque parent en_attente
- ValidationRefusForm : état isSubmitting (UX)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-13 17:38:29 +02:00
co-authored by Cursor
parent 43dabd1885
commit 7ba8d51668
4 changed files with 115 additions and 24 deletions
@@ -8,12 +8,15 @@ class ValidationRefusForm extends StatefulWidget {
/// Retour à l’étape précédente du wizard (écran avec Valider / Refuser).
final VoidCallback onPrevious;
final ValueChanged<String?> onSubmit;
/// Pendant l'appel API : désactive les actions (ticket #110).
final bool isSubmitting;
const ValidationRefusForm({
super.key,
required this.onCancel,
required this.onPrevious,
required this.onSubmit,
this.isSubmitting = false,
});
@override
@@ -67,6 +70,7 @@ class _ValidationRefusFormState extends State<ValidationRefusForm> {
),
child: TextFormField(
controller: _controller,
readOnly: widget.isSubmitting,
maxLines: null,
minLines: 1,
validator: _validateMotifs,
@@ -91,7 +95,7 @@ class _ValidationRefusFormState extends State<ValidationRefusForm> {
Row(
children: [
TextButton(
onPressed: widget.onCancel,
onPressed: widget.isSubmitting ? null : widget.onCancel,
child: const Text('Annuler'),
),
const Spacer(),
@@ -99,19 +103,29 @@ class _ValidationRefusFormState extends State<ValidationRefusForm> {
mainAxisSize: MainAxisSize.min,
children: [
TextButton(
onPressed: widget.onPrevious,
onPressed: widget.isSubmitting ? null : widget.onPrevious,
child: const Text('Précédent'),
),
const SizedBox(width: 8),
ElevatedButton(
style: ValidationModalTheme.primaryElevatedStyle,
onPressed: () {
if (_formKey.currentState!.validate()) {
widget.onSubmit(_controller.text.trim());
}
},
child: const Text('Envoyer'),
),
if (widget.isSubmitting)
const Padding(
padding: EdgeInsets.symmetric(horizontal: 12),
child: SizedBox(
width: 22,
height: 22,
child: CircularProgressIndicator(strokeWidth: 2),
),
)
else
ElevatedButton(
style: ValidationModalTheme.primaryElevatedStyle,
onPressed: () {
if (_formKey.currentState!.validate()) {
widget.onSubmit(_controller.text.trim());
}
},
child: const Text('Envoyer'),
),
],
),
],