import 'package:flutter/material.dart'; import '../models/client.dart'; import '../services/client_repository.dart'; import '../theme.dart'; import '../widgets/pastille_points.dart'; import 'client_detail_screen.dart'; import 'client_edit_screen.dart'; /// Onglet 1 : liste de tous les clients, avec recherche et ajout. class ClientsScreen extends StatefulWidget { final VoidCallback onAllerScanner; const ClientsScreen({super.key, required this.onAllerScanner}); @override State createState() => _ClientsScreenState(); } class _ClientsScreenState extends State { final _repo = ClientRepository.instance; final _rechercheCtrl = TextEditingController(); String _requete = ''; @override void dispose() { _rechercheCtrl.dispose(); super.dispose(); } Future _ajouter() async { final client = await Navigator.of(context).push( MaterialPageRoute(builder: (_) => const ClientEditScreen()), ); if (client != null && mounted) { // On ouvre directement la fiche du nouveau client. Navigator.of(context).push( MaterialPageRoute(builder: (_) => ClientDetailScreen(clientId: client.id)), ); } } void _ouvrir(Client c) { Navigator.of(context).push( MaterialPageRoute(builder: (_) => ClientDetailScreen(clientId: c.id)), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Clients')), floatingActionButton: FloatingActionButton.extended( onPressed: _ajouter, icon: const Icon(Icons.person_add_alt_1), label: const Text('Nouveau client'), ), body: Column( children: [ Padding( padding: const EdgeInsets.fromLTRB(16, 4, 16, 12), child: TextField( controller: _rechercheCtrl, onChanged: (v) => setState(() => _requete = v), textInputAction: TextInputAction.search, decoration: InputDecoration( hintText: 'Rechercher (nom, téléphone, code)', prefixIcon: const Icon(Icons.search), suffixIcon: _requete.isEmpty ? null : IconButton( icon: const Icon(Icons.close), onPressed: () { _rechercheCtrl.clear(); setState(() => _requete = ''); }, ), ), ), ), Expanded( child: AnimatedBuilder( animation: _repo, builder: (context, _) { final liste = _repo.rechercher(_requete); if (_repo.clients.isEmpty) return _vide(); if (liste.isEmpty) { return const Center( child: Text('Aucun client ne correspond.', style: TextStyle(color: AppTheme.grisTexte)), ); } return ListView.separated( padding: const EdgeInsets.fromLTRB(16, 0, 16, 96), itemCount: liste.length, separatorBuilder: (_, _) => const SizedBox(height: 10), itemBuilder: (context, i) => _carte(liste[i]), ); }, ), ), ], ), ); } Widget _carte(Client c) { return Card( child: InkWell( borderRadius: BorderRadius.circular(16), onTap: () => _ouvrir(c), child: Padding( padding: const EdgeInsets.all(14), child: Row( children: [ CircleAvatar( radius: 24, backgroundColor: AppTheme.accent.withValues(alpha: 0.14), child: Text( c.initiales, style: const TextStyle( color: AppTheme.accent, fontWeight: FontWeight.w700), ), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( c.nomComplet, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w700), maxLines: 1, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 2), Text( c.telephone?.isNotEmpty == true ? c.telephone! : c.code, style: const TextStyle( fontSize: 13, color: AppTheme.grisTexte), ), ], ), ), const SizedBox(width: 8), PastillePoints(c.points), ], ), ), ), ); } Widget _vide() { return Center( child: Padding( padding: const EdgeInsets.all(32), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Icon(Icons.people_outline, size: 64, color: AppTheme.grisTexte), const SizedBox(height: 16), const Text( 'Aucun client pour l\'instant', style: TextStyle(fontSize: 18, fontWeight: FontWeight.w700), ), const SizedBox(height: 8), const Text( 'Créez une fiche client : un QR code de fidélité sera généré automatiquement.', textAlign: TextAlign.center, style: TextStyle(color: AppTheme.grisTexte), ), const SizedBox(height: 24), FilledButton.icon( onPressed: _ajouter, icon: const Icon(Icons.person_add_alt_1), label: const Text('Créer le premier client'), ), const SizedBox(height: 12), TextButton.icon( onPressed: widget.onAllerScanner, icon: const Icon(Icons.qr_code_scanner), label: const Text('Ou scanner un QR client'), ), ], ), ), ); } }