import "package:flutter/material.dart"; import "package:google_fonts/google_fonts.dart"; import "../theme/ensup_colors.dart"; import "../models/materiel_item.dart"; import "status_pill.dart"; /// Ligne du catalogue matériel (fidèle au `.mat-card` de la maquette). class MaterielCard extends StatelessWidget { const MaterielCard({super.key, required this.item, this.onSelect}); final MaterielItem item; final VoidCallback? onSelect; @override Widget build(BuildContext context) { final disponible = item.disponible; final accent = disponible ? EnsupColors.cyan : EnsupColors.muted; return Opacity( opacity: disponible ? 1 : 0.55, child: 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), boxShadow: [ BoxShadow( color: EnsupColors.text.withValues(alpha: 0.035), blurRadius: 10, offset: const Offset(0, 3), ), ], ), child: LayoutBuilder( builder: (context, constraints) { final compact = constraints.maxWidth < 620; final information = Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Container( width: 46, height: 46, decoration: BoxDecoration( color: accent.withValues(alpha: 0.09), borderRadius: BorderRadius.circular(10), ), child: Icon(item.icon, color: accent, size: 21), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( item.nom, maxLines: 2, overflow: TextOverflow.ellipsis, style: GoogleFonts.darkerGrotesque( fontWeight: FontWeight.w800, fontSize: 17, height: 1.05, color: EnsupColors.text, ), ), const SizedBox(height: 4), Text( "${item.categorie} · Réf. ${item.reference}", maxLines: 2, overflow: TextOverflow.ellipsis, style: GoogleFonts.titilliumWeb( fontSize: 12, color: EnsupColors.muted, ), ), const SizedBox(height: 3), Row( children: [ const Icon( Icons.location_on_outlined, size: 13, color: EnsupColors.muted, ), const SizedBox(width: 4), Expanded( child: Text( item.campus, maxLines: 1, overflow: TextOverflow.ellipsis, style: GoogleFonts.titilliumWeb( fontSize: 11, color: EnsupColors.muted, ), ), ), ], ), ], ), ), ], ); final actions = Wrap( spacing: 10, runSpacing: 8, crossAxisAlignment: WrapCrossAlignment.center, alignment: WrapAlignment.end, children: [ StatusPill(disponible: disponible), if (disponible) FilledButton.icon( onPressed: onSelect, style: FilledButton.styleFrom( backgroundColor: EnsupColors.cyan, padding: const EdgeInsets.symmetric( horizontal: 15, vertical: 11, ), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(9), ), ), icon: const Icon(Icons.arrow_forward_rounded, size: 16), label: Text( "Sélectionner", style: GoogleFonts.darkerGrotesque( fontWeight: FontWeight.w700, fontSize: 14, ), ), ) else Text( "Indisponible", style: GoogleFonts.darkerGrotesque( fontWeight: FontWeight.w700, fontSize: 14, color: EnsupColors.muted, ), ), ], ); if (compact) { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ information, const SizedBox(height: 14), Align(alignment: Alignment.centerRight, child: actions), ], ); } return Row( children: [ Expanded(child: information), const SizedBox(width: 16), actions, ], ); }, ), ), ); } }