Files
app_fideliter/lib/screens/client_edit_screen.dart
T
Mathew 1d3ee69c6d Initial commit — app fidélité magasin (tablette)
App Flutter de programme de fidélité : login staff, clients (nom/prénom),
scan QR, factures (€→points), récompenses, réglages. Backend Supabase
(schéma SQL + RLS anti-triche dans supabase/). Icône incluse.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-17 21:37:06 +02:00

139 lines
4.3 KiB
Dart

import 'package:flutter/material.dart';
import '../models/client.dart';
import '../services/client_repository.dart';
/// Création (client == null) ou édition d'une fiche client.
/// Retourne le [Client] créé/modifié via Navigator.pop, ou null si annulé.
class ClientEditScreen extends StatefulWidget {
final Client? client;
const ClientEditScreen({super.key, this.client});
@override
State<ClientEditScreen> createState() => _ClientEditScreenState();
}
class _ClientEditScreenState extends State<ClientEditScreen> {
final _formKey = GlobalKey<FormState>();
late final TextEditingController _nomCtrl;
late final TextEditingController _prenomCtrl;
late final TextEditingController _telCtrl;
bool _enregistre = false;
bool get _edition => widget.client != null;
@override
void initState() {
super.initState();
_nomCtrl = TextEditingController(text: widget.client?.nom ?? '');
_prenomCtrl = TextEditingController(text: widget.client?.prenom ?? '');
_telCtrl = TextEditingController(text: widget.client?.telephone ?? '');
}
@override
void dispose() {
_nomCtrl.dispose();
_prenomCtrl.dispose();
_telCtrl.dispose();
super.dispose();
}
Future<void> _enregistrer() async {
if (!_formKey.currentState!.validate()) return;
setState(() => _enregistre = true);
final repo = ClientRepository.instance;
try {
final Client resultat;
if (_edition) {
resultat = widget.client!.copyWith(
nom: _nomCtrl.text.trim(),
prenom: _prenomCtrl.text.trim(),
telephone: _telCtrl.text.trim(),
);
await repo.modifier(resultat);
} else {
resultat = await repo.creer(
nom: _nomCtrl.text.trim(),
prenom: _prenomCtrl.text.trim(),
telephone: _telCtrl.text.trim(),
);
}
if (mounted) Navigator.of(context).pop(resultat);
} catch (e) {
if (mounted) {
setState(() => _enregistre = false);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Erreur : $e')),
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(_edition ? 'Modifier le client' : 'Nouveau client'),
),
body: Form(
key: _formKey,
child: ListView(
padding: const EdgeInsets.all(16),
children: [
TextFormField(
controller: _nomCtrl,
textCapitalization: TextCapitalization.words,
autofocus: !_edition,
decoration: const InputDecoration(
labelText: 'Nom *',
prefixIcon: Icon(Icons.person_outline),
),
validator: (v) =>
(v == null || v.trim().isEmpty) ? 'Nom obligatoire' : null,
),
const SizedBox(height: 16),
TextFormField(
controller: _prenomCtrl,
textCapitalization: TextCapitalization.words,
decoration: const InputDecoration(
labelText: 'Prénom',
prefixIcon: Icon(Icons.badge_outlined),
),
),
const SizedBox(height: 16),
TextFormField(
controller: _telCtrl,
keyboardType: TextInputType.phone,
decoration: const InputDecoration(
labelText: 'Téléphone (facultatif)',
prefixIcon: Icon(Icons.phone_outlined),
),
),
const SizedBox(height: 24),
FilledButton(
onPressed: _enregistre ? null : _enregistrer,
child: _enregistre
? const SizedBox(
height: 22,
width: 22,
child: CircularProgressIndicator(
strokeWidth: 2, color: Colors.white),
)
: Text(_edition ? 'Enregistrer' : 'Créer le client'),
),
if (!_edition) ...[
const SizedBox(height: 16),
const Text(
'Un code de fidélité unique et son QR code seront générés automatiquement.',
textAlign: TextAlign.center,
style: TextStyle(fontSize: 13, color: Color(0xFF6B6B72)),
),
],
],
),
),
);
}
}