import 'package:flutter/material.dart'; import 'package:nfc_manager/nfc_manager.dart'; import 'dart:typed_data'; import 'google_sheets_api.dart'; class InscriptionPage extends StatefulWidget { final String? prefilledMac; const InscriptionPage({super.key, this.prefilledMac}); @override State createState() => _InscriptionPageState(); } class _InscriptionPageState extends State { final _formKey = GlobalKey(); final TextEditingController _numController = TextEditingController(); final TextEditingController _firstController = TextEditingController(); final TextEditingController _lastController = TextEditingController(); final TextEditingController _macController = TextEditingController(); final TextEditingController _qrController = TextEditingController(); bool _hasNfc = false; bool _isScanning = false; @override void initState() { super.initState(); if (widget.prefilledMac != null) { _macController.text = widget.prefilledMac!; _hasNfc = true; } } @override void dispose() { _numController.dispose(); _firstController.dispose(); _lastController.dispose(); _macController.dispose(); _qrController.dispose(); super.dispose(); } String _bytesToUid(dynamic raw) { try { final bytes = raw is Uint8List ? raw : Uint8List.fromList(List.from(raw)); return bytes.map((b) => b.toRadixString(16).padLeft(2, '0').toUpperCase()).join(':'); } catch (_) { return raw.toString(); } } Future _scanNfcAndFill() async { setState(() => _isScanning = true); bool available = await NfcManager.instance.isAvailable(); if (!available) { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('NFC non disponible'))); setState(() => _isScanning = false); return; } NfcManager.instance.startSession( pollingOptions: {NfcPollingOption.iso14443, NfcPollingOption.iso15693}, onDiscovered: (NfcTag tag) async { try { dynamic data; try { data = (tag as dynamic).data; } catch (_) { data = null; } String uid = ''; try { final id = (data is Map && data.containsKey('id')) ? data['id'] : (tag as dynamic).id; uid = _bytesToUid(id); } catch (_) { try { uid = _bytesToUid((tag as dynamic).id); } catch (_) { uid = ''; } } if (uid.isNotEmpty) { _macController.text = uid; _hasNfc = true; } } catch (e) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Erreur lecture NFC: $e'))); } await NfcManager.instance.stopSession(); setState(() => _isScanning = false); }, ); } Future _submit() async { if (!_formKey.currentState!.validate()) return; final num = _numController.text.trim(); final first = _firstController.text.trim(); final last = _lastController.text.trim(); final mac = _macController.text.trim(); final qr = _qrController.text.trim(); final nfc = _hasNfc ? 'oui' : 'non'; final date = DateTime.now().toIso8601String(); final row = [num, first, last, mac, nfc, qr, date]; final api = GoogleSheetsApi(); final ok = await api.appendData(row); if (ok) { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Étudiant enregistré'))); Navigator.of(context).pop(true); } else { ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text('Échec enregistrement'))); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Inscription étudiant')), body: Padding( padding: const EdgeInsets.all(16.0), child: Form( key: _formKey, child: ListView( children: [ TextFormField( controller: _numController, decoration: const InputDecoration(labelText: "N° Etudiant"), validator: (v) => (v == null || v.trim().isEmpty) ? 'Veuillez saisir le numéro' : null, keyboardType: TextInputType.text, ), TextFormField( controller: _firstController, decoration: const InputDecoration(labelText: 'Prénom'), validator: (v) => (v == null || v.trim().isEmpty) ? 'Veuillez saisir le prénom' : null, ), TextFormField( controller: _lastController, decoration: const InputDecoration(labelText: 'Nom'), validator: (v) => (v == null || v.trim().isEmpty) ? 'Veuillez saisir le nom' : null, ), const SizedBox(height: 12), TextFormField( controller: _macController, decoration: const InputDecoration(labelText: 'MAC (UID NFC)'), ), Row( children: [ Checkbox(value: _hasNfc, onChanged: (v) => setState(() => _hasNfc = v ?? false)), const Text('NFC détecté'), const Spacer(), ElevatedButton.icon( onPressed: _isScanning ? null : _scanNfcAndFill, icon: const Icon(Icons.nfc), label: Text(_isScanning ? 'Scan en cours...' : 'Scanner NFC'), ) ], ), TextFormField( controller: _qrController, decoration: const InputDecoration(labelText: 'QR (optionnel)'), ), const SizedBox(height: 16), ElevatedButton( onPressed: _submit, child: const Text('Enregistrer dans Google Sheets'), ), ], ), ), ), ); } }