feat(frontend): connect borrow flow to api

This commit is contained in:
SaidSoighiri94
2026-07-07 13:22:53 +02:00
parent 27171562de
commit 7aba1a930d
7 changed files with 180 additions and 21 deletions
@@ -2,6 +2,7 @@ import "package:flutter/material.dart";
import "package:google_fonts/google_fonts.dart";
import "../theme/ensup_colors.dart";
import "../models/materiel_item.dart";
import "../services/emprunt_service.dart";
import "../widgets/ensup_top_bar.dart";
import "../widgets/brand_corners.dart";
import "../widgets/etat_checklist.dart";
@@ -19,27 +20,79 @@ class ChecklistDepartScreen extends StatefulWidget {
}
class _ChecklistDepartScreenState extends State<ChecklistDepartScreen> {
late final List<String> _elements = widget.item.accessoires.isEmpty
? <String>[widget.item.nom]
: widget.item.accessoires;
late final List<EtatChecklist> _etats = List<EtatChecklist>.filled(
widget.item.accessoires.length,
_elements.length,
EtatChecklist.present,
);
final TextEditingController _commentaireController = TextEditingController();
bool _envoiEnCours = false;
@override
void dispose() {
_commentaireController.dispose();
super.dispose();
}
Future<void> _valider() async {
setState(() => _envoiEnCours = true);
void _valider() {
final anomalies = <String>[];
for (var i = 0; i < _etats.length; i++) {
if (_etats[i] == EtatChecklist.absent) {
anomalies.add("${widget.item.accessoires[i]} absent au départ");
anomalies.add("${_elements[i]} absent au départ");
} else if (_etats[i] == EtatChecklist.deteriore) {
anomalies.add("${widget.item.accessoires[i]} détérioré au départ");
anomalies.add("${_elements[i]} détérioré au départ");
}
}
final note = anomalies.isEmpty ? null : anomalies.join(", ");
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ConfirmationScreen(item: widget.item, note: note),
),
);
try {
final emprunt = await EmpruntService.creerEmprunt(
materielId: widget.item.id,
commentaireDepart: _commentaireController.text,
elements: _elements.asMap().entries.map((entry) {
return {
"nomElement": entry.value,
"etat": _etatApi(_etats[entry.key]),
"quantiteConstatee": _etats[entry.key] == EtatChecklist.absent ? 0 : 1,
};
}).toList(),
);
if (!mounted) {
return;
}
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ConfirmationScreen(emprunt: emprunt, note: note),
),
);
} catch (error) {
if (!mounted) {
return;
}
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(error.toString())),
);
} finally {
if (mounted) {
setState(() => _envoiEnCours = false);
}
}
}
String _etatApi(EtatChecklist etat) {
switch (etat) {
case EtatChecklist.present:
return "PRESENT";
case EtatChecklist.absent:
return "ABSENT";
case EtatChecklist.deteriore:
return "DETERIORE";
}
}
@override
@@ -141,7 +194,7 @@ class _ChecklistDepartScreenState extends State<ChecklistDepartScreen> {
),
const SizedBox(height: 16),
ChecklistTableau(
accessoires: widget.item.accessoires,
accessoires: _elements,
etats: _etats,
onChanged: (index, etat) => setState(() => _etats[index] = etat),
),
@@ -161,15 +214,23 @@ class _ChecklistDepartScreenState extends State<ChecklistDepartScreen> {
"endommagé pour éviter tout litige au retour.",
),
const SizedBox(height: 14),
const ChecklistCommentaire(),
ChecklistCommentaire(controller: _commentaireController),
const SizedBox(height: 14),
SizedBox(
width: double.infinity,
child: FilledButton.icon(
onPressed: _valider,
icon: const Icon(Icons.check, size: 18),
onPressed: _envoiEnCours ? null : _valider,
icon: _envoiEnCours
? const SizedBox(
width: 18,
height: 18,
child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white),
)
: const Icon(Icons.check, size: 18),
label: Text(
"Valider la checklist et confirmer l'emprunt",
_envoiEnCours
? "Enregistrement..."
: "Valider la checklist et confirmer l'emprunt",
textAlign: TextAlign.center,
style: GoogleFonts.darkerGrotesque(fontWeight: FontWeight.w700, fontSize: 15),
),