inscription_page.dart 5,91 ko
Newer Older
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<InscriptionPage> createState() => _InscriptionPageState();
}

class _InscriptionPageState extends State<InscriptionPage> {
  final _formKey = GlobalKey<FormState>();
  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<int>.from(raw));
      return bytes.map((b) => b.toRadixString(16).padLeft(2, '0').toUpperCase()).join(':');
    } catch (_) {
      return raw.toString();
    }
  }

  Future<void> _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<void> _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'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}