import 'package:flutter/material.dart'; import 'package:nfc_manager/nfc_manager.dart'; import 'dart:typed_data'; import 'google_sheets_api.dart'; import 'inscription_page.dart'; // <-- 1. IMPORTER LA NOUVELLE PAGE void main() { WidgetsFlutterBinding.ensureInitialized(); runApp(const MaterialApp( debugShowCheckedModeBanner: false, home: SimpleNfcReader(), )); } class SimpleNfcReader extends StatefulWidget { const SimpleNfcReader({super.key}); @override State createState() => _SimpleNfcReaderState(); } class _SimpleNfcReaderState extends State { bool _isReading = false; String _status = 'Appuyez sur le bouton pour vérifier un étudiant'; String? _lastScannedUid; // <-- 2. GARDER EN MÉMOIRE L'UID SCANNÉ final GoogleSheetsApi _sheetsApi = GoogleSheetsApi(); Future _startNfc() async { bool available = await NfcManager.instance.isAvailable(); if (!available) { setState(() => _status = '❌ NFC non disponible sur cet appareil'); return; } setState(() { _isReading = true; _status = '🔄 Approchez une carte étudiant...'; _lastScannedUid = null; // Réinitialiser à chaque scan }); NfcManager.instance.startSession( pollingOptions: { NfcPollingOption.iso14443, NfcPollingOption.iso15693, NfcPollingOption.iso18092, }, onDiscovered: (NfcTag tag) async { String? uid; try { dynamic data; try { data = (tag as dynamic).data; } catch (_) {} final idBytes = _safeLookup(data, 'id'); if (idBytes != null) { uid = _bytesToHexString(idBytes); } if (uid == null) { setState(() => _status = '❌ Impossible de lire le N° de série.'); await NfcManager.instance.stopSession(); setState(() => _isReading = false); return; } setState(() => _status = '🔄 N° de série: $uid\nVérification en cours...'); await NfcManager.instance.stopSession(); String? nomEtudiant = await _sheetsApi.findStudentNameByNfcUid(uid); setState(() { if (nomEtudiant != null) { _status = '✅ Bienvenue, $nomEtudiant !'; _lastScannedUid = null; // Trouvé, donc on n'inscrit pas } else { _status = '❌ Étudiant inexistant.\nN°: $uid'; _lastScannedUid = uid; // <-- 3. ON SAUVEGARDE L'UID POUR L'INSCRIPTION } }); } catch (e) { setState(() { _status = 'Erreur: ${e.toString()}'; }); await NfcManager.instance.stopSession(); } setState(() => _isReading = false); }, ); } // --- 4. FONCTION POUR OUVRIR LA PAGE D'INSCRIPTION --- void _goToInscriptionPage() { if (_lastScannedUid == null) return; // Naviguer vers la page d'inscription et lui passer l'UID Navigator.push( context, MaterialPageRoute( builder: (context) => InscriptionPage(prefilledMac: _lastScannedUid), ), ).then((inscriptionReussie) { // Ce code s'exécute quand on revient de la page d'inscription if (inscriptionReussie == true) { setState(() { _status = '✅ Nouvel étudiant enregistré !'; _lastScannedUid = null; // On nettoie }); } }); } // --- Fonctions utilitaires (inchangées) --- String _bytesToHexString(dynamic maybeBytes) { try { Uint8List bytes; if (maybeBytes is Uint8List) bytes = maybeBytes; else if (maybeBytes is List) bytes = Uint8List.fromList(maybeBytes); else return maybeBytes.toString(); // SANS DEUX-POINTS return bytes.map((b) => b.toRadixString(16).padLeft(2, '0').toUpperCase()).join(''); } catch (_) { return maybeBytes.toString(); } } dynamic _safeLookup(dynamic obj, String key) { if (obj == null) return null; try { if (obj is Map) { if (obj.containsKey(key)) return obj[key]; final lower = key.toLowerCase(); if (obj.containsKey(lower)) return obj[lower]; } } catch (_) {} try { return (obj as dynamic)[key]; } catch (_) {} try { if (key == 'id') return (obj as dynamic).id; } catch (_) {} return null; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('📡 Vérification Étudiant')), body: Padding( padding: const EdgeInsets.all(20), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Icon( _isReading ? Icons.nfc : Icons.school, size: 100, color: Colors.blueAccent, ), const SizedBox(height: 30), Text( _status, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold), textAlign: TextAlign.center, ), // --- 5. AFFICHAGE DU BOUTON D'INSCRIPTION --- if (_lastScannedUid != null && !_isReading) Padding( padding: const EdgeInsets.only(top: 24.0), child: ElevatedButton.icon( onPressed: _goToInscriptionPage, icon: const Icon(Icons.person_add), label: const Text('Inscrire ce nouvel étudiant'), style: ElevatedButton.styleFrom( backgroundColor: Colors.green, // Couleur différente padding: const EdgeInsets.symmetric(vertical: 12), ), ), ), const Spacer(), Center( child: ElevatedButton.icon( onPressed: _isReading ? null : _startNfc, icon: _isReading ? const SizedBox( width: 20, height: 20, child: CircularProgressIndicator(color: Colors.white, strokeWidth: 2) ) : const Icon(Icons.nfc), label: Text(_isReading ? 'Lecture en cours...' : 'Vérifier la carte'), style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 15), ), ), ), ], ), ), ); } }