feat(frontend): connect borrow flow to api
This commit is contained in:
@@ -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),
|
||||
),
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
import "package:flutter/material.dart";
|
||||
import "package:google_fonts/google_fonts.dart";
|
||||
import "../theme/ensup_colors.dart";
|
||||
import "../models/emprunt_response.dart";
|
||||
import "../models/materiel_item.dart";
|
||||
import "../widgets/ensup_top_bar.dart";
|
||||
import "../widgets/brand_corners.dart";
|
||||
|
||||
/// Écran de succès clôturant l'emprunt : confirmation + récapitulatif.
|
||||
class ConfirmationScreen extends StatelessWidget {
|
||||
const ConfirmationScreen({super.key, required this.item, this.note});
|
||||
const ConfirmationScreen({super.key, required this.emprunt, this.note});
|
||||
|
||||
final MaterielItem item;
|
||||
final EmpruntResponse emprunt;
|
||||
final String? note;
|
||||
|
||||
MaterielItem get item => emprunt.materiel;
|
||||
|
||||
static String _deuxChiffres(int valeur) => valeur.toString().padLeft(2, "0");
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final now = DateTime.now();
|
||||
final date = "${_deuxChiffres(now.day)}/${_deuxChiffres(now.month)}/${now.year}";
|
||||
final heure = "${_deuxChiffres(now.hour)}:${_deuxChiffres(now.minute)}";
|
||||
final dateEmprunt = emprunt.dateEmprunt;
|
||||
final date =
|
||||
"${_deuxChiffres(dateEmprunt.day)}/${_deuxChiffres(dateEmprunt.month)}/${dateEmprunt.year}";
|
||||
final heure = "${_deuxChiffres(dateEmprunt.hour)}:${_deuxChiffres(dateEmprunt.minute)}";
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: EnsupColors.soft,
|
||||
@@ -181,6 +185,7 @@ class ConfirmationScreen extends StatelessWidget {
|
||||
const SizedBox(height: 10),
|
||||
_rrow("Matériel", item.nom),
|
||||
_rrow("Référence", item.reference),
|
||||
_rrow("N° emprunt", "#${emprunt.id}"),
|
||||
_rrow("Emprunteur", "Lucas Martin"),
|
||||
_rrow("Date d'emprunt", date),
|
||||
_rrow("Heure", heure),
|
||||
|
||||
Reference in New Issue
Block a user