diff --git a/eme-frontend/lib/models/emprunt_item.dart b/eme-frontend/lib/models/emprunt_item.dart new file mode 100644 index 0000000..27f112e --- /dev/null +++ b/eme-frontend/lib/models/emprunt_item.dart @@ -0,0 +1,15 @@ +import "materiel_item.dart"; + +/// Un emprunt en cours de l'étudiant, affiché dans le parcours de restitution +/// (données statiques pour l'instant). +class EmpruntItem { + const EmpruntItem({ + required this.materiel, + required this.dateEmprunt, + required this.retourPrevu, + }); + + final MaterielItem materiel; + final String dateEmprunt; + final String retourPrevu; +} diff --git a/eme-frontend/lib/screens/home_screen.dart b/eme-frontend/lib/screens/home_screen.dart index d3ab7dd..77ab1ee 100644 --- a/eme-frontend/lib/screens/home_screen.dart +++ b/eme-frontend/lib/screens/home_screen.dart @@ -6,17 +6,12 @@ import "../widgets/profile_card.dart"; import "../widgets/action_card.dart"; import "../widgets/brand_corners.dart"; import "catalogue_screen.dart"; +import "restitution_select_screen.dart"; /// Écran d'accueil étudiant : profil + choix Emprunter / Restituer. class HomeScreen extends StatelessWidget { const HomeScreen({super.key}); - void _bientot(BuildContext context, String action) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text("$action — écran à venir")), - ); - } - @override Widget build(BuildContext context) { return Scaffold( @@ -93,7 +88,9 @@ class HomeScreen extends StatelessWidget { description: "Restituer un matériel que vous avez emprunté", color: EnsupColors.teal, - onTap: () => _bientot(context, "Restituer"), + onTap: () => Navigator.of(context).push( + MaterialPageRoute(builder: (_) => const RestitutionSelectScreen()), + ), ), ), ], diff --git a/eme-frontend/lib/screens/restitution_select_screen.dart b/eme-frontend/lib/screens/restitution_select_screen.dart new file mode 100644 index 0000000..cf6d335 --- /dev/null +++ b/eme-frontend/lib/screens/restitution_select_screen.dart @@ -0,0 +1,187 @@ +import "package:flutter/material.dart"; +import "package:google_fonts/google_fonts.dart"; +import "../theme/ensup_colors.dart"; +import "../models/materiel_item.dart"; +import "../models/emprunt_item.dart"; +import "../widgets/ensup_top_bar.dart"; +import "../widgets/brand_corners.dart"; + +const _pcDell = MaterielItem( + nom: "PC Dell Latitude 5420", + categorie: "Ordinateur", + marque: "Dell", + modele: "Latitude 5420", + reference: "ENS-PC-001", + campus: "Paris", + etatGeneral: "Bon état", + disponible: false, + accessoires: ["Chargeur 65W", "Souris sans fil", "Housse de protection", "Câble HDMI"], + icon: Icons.laptop_mac, +); + +const _emprunts = [ + EmpruntItem(materiel: _pcDell, dateEmprunt: "28/05/2026 à 09:15", retourPrevu: "29/05"), +]; + +/// Sélection de l'emprunt en cours à restituer (RG15 : ses propres emprunts). +class RestitutionSelectScreen extends StatelessWidget { + const RestitutionSelectScreen({super.key}); + + void _restituer(BuildContext context, EmpruntItem emprunt) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text("Checklist de retour de ${emprunt.materiel.nom} — écran à venir")), + ); + } + + @override + Widget build(BuildContext context) { + 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: "Restitution", + campusTag: "Paris · Ensitech", + userName: "Lucas Martin", + userInitials: "LM", + onBack: () => Navigator.of(context).pop(), + ), + Expanded( + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 28), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + "Sélectionner le matériel à restituer", + style: GoogleFonts.darkerGrotesque( + fontSize: 24, + fontWeight: FontWeight.w900, + color: EnsupColors.text, + ), + ), + const SizedBox(height: 16), + for (final emprunt in _emprunts) + Padding( + padding: const EdgeInsets.only(bottom: 10), + child: _EmpruntCard( + emprunt: emprunt, + onRestituer: () => _restituer(context, emprunt), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ), + ), + const Positioned.fill(child: BrandCorners()), + ], + ), + ); + } +} + +class _EmpruntCard extends StatelessWidget { + const _EmpruntCard({required this.emprunt, required this.onRestituer}); + + final EmpruntItem emprunt; + final VoidCallback onRestituer; + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 16), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12), + border: Border.all(color: EnsupColors.line, width: 1.5), + ), + child: Row( + children: [ + Container( + width: 44, + height: 44, + decoration: BoxDecoration( + color: EnsupColors.teal.withValues(alpha: 0.08), + borderRadius: BorderRadius.circular(10), + ), + child: Icon(emprunt.materiel.icon, color: EnsupColors.teal, size: 20), + ), + const SizedBox(width: 14), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + emprunt.materiel.nom, + style: GoogleFonts.darkerGrotesque( + fontWeight: FontWeight.w700, + fontSize: 16, + color: EnsupColors.text, + ), + ), + const SizedBox(height: 2), + Text( + "Emprunté le ${emprunt.dateEmprunt} · Retour prévu ${emprunt.retourPrevu}", + style: GoogleFonts.titilliumWeb(fontSize: 12, color: EnsupColors.muted), + ), + ], + ), + ), + const SizedBox(width: 10), + Container( + padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4), + decoration: BoxDecoration( + color: const Color(0xFFFEF9C3), + borderRadius: BorderRadius.circular(999), + ), + child: Text( + "En cours", + style: GoogleFonts.darkerGrotesque( + fontSize: 13, + fontWeight: FontWeight.w700, + color: const Color(0xFFA16207), + ), + ), + ), + const SizedBox(width: 12), + FilledButton( + onPressed: onRestituer, + style: FilledButton.styleFrom( + backgroundColor: EnsupColors.cyan, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10), + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), + ), + child: Text( + "Restituer", + style: GoogleFonts.darkerGrotesque(fontWeight: FontWeight.w700, fontSize: 14), + ), + ), + ], + ), + ); + } +} diff --git a/review.md b/review.md index b2bc759..f14f178 100644 --- a/review.md +++ b/review.md @@ -207,4 +207,4 @@ En terminal interactif (VS Code), `migrate dev` fonctionne normalement (taper `y --- -*Dernière mise à jour : 2026-07-06 — Frontend : parcours emprunt complet (jusqu'à la confirmation).* +*Dernière mise à jour : 2026-07-06 — Frontend : parcours emprunt complet + début restitution (sélection).*