- Ajout système complet de gestion des secteurs avec contours géographiques - Import des contours départementaux depuis GeoJSON - API REST pour la gestion des secteurs (/api/sectors) - Service de géolocalisation pour déterminer les secteurs - Migration base de données avec tables x_departements_contours et sectors_adresses - Interface Flutter pour visualisation et gestion des secteurs - Ajout thème sombre dans l'application - Corrections diverses et optimisations 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
242 lines
8.3 KiB
Dart
Executable File
242 lines
8.3 KiB
Dart
Executable File
import 'package:flutter/material.dart';
|
|
import 'package:geosector_app/presentation/widgets/custom_text_field.dart';
|
|
import 'package:geosector_app/presentation/widgets/form_section.dart';
|
|
|
|
/// Exemple d'utilisation modernisée du formulaire de passage
|
|
/// utilisant CustomTextField et FormSection adaptés
|
|
class PassageFormModernizedExample extends StatefulWidget {
|
|
final bool readOnly;
|
|
|
|
const PassageFormModernizedExample({
|
|
super.key,
|
|
this.readOnly = false,
|
|
});
|
|
|
|
@override
|
|
State<PassageFormModernizedExample> createState() => _PassageFormModernizedExampleState();
|
|
}
|
|
|
|
class _PassageFormModernizedExampleState extends State<PassageFormModernizedExample> {
|
|
// Controllers pour l'exemple
|
|
final _numeroController = TextEditingController();
|
|
final _rueBisController = TextEditingController();
|
|
final _rueController = TextEditingController();
|
|
final _villeController = TextEditingController();
|
|
final _dateController = TextEditingController();
|
|
final _timeController = TextEditingController();
|
|
final _nameController = TextEditingController();
|
|
final _emailController = TextEditingController();
|
|
final _phoneController = TextEditingController();
|
|
final _montantController = TextEditingController();
|
|
final _remarqueController = TextEditingController();
|
|
|
|
@override
|
|
void dispose() {
|
|
_numeroController.dispose();
|
|
_rueBisController.dispose();
|
|
_rueController.dispose();
|
|
_villeController.dispose();
|
|
_dateController.dispose();
|
|
_timeController.dispose();
|
|
_nameController.dispose();
|
|
_emailController.dispose();
|
|
_phoneController.dispose();
|
|
_montantController.dispose();
|
|
_remarqueController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
void _selectDate() {
|
|
// Logique de sélection de date
|
|
}
|
|
|
|
void _selectTime() {
|
|
// Logique de sélection d'heure
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
appBar: AppBar(title: const Text('Formulaire Modernisé')),
|
|
body: SingleChildScrollView(
|
|
padding: const EdgeInsets.all(16),
|
|
child: Column(
|
|
children: [
|
|
// Section Date et Heure avec FormSection
|
|
FormSection(
|
|
title: 'Date et Heure de passage',
|
|
icon: Icons.schedule,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: CustomTextField(
|
|
controller: _dateController,
|
|
label: "Date",
|
|
isRequired: true,
|
|
readOnly: true,
|
|
showLabel: false,
|
|
hintText: "DD/MM/YYYY",
|
|
suffixIcon: const Icon(Icons.calendar_today),
|
|
onTap: widget.readOnly ? null : _selectDate,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: CustomTextField(
|
|
controller: _timeController,
|
|
label: "Heure",
|
|
isRequired: true,
|
|
readOnly: true,
|
|
showLabel: false,
|
|
hintText: "HH:MM",
|
|
suffixIcon: const Icon(Icons.access_time),
|
|
onTap: widget.readOnly ? null : _selectTime,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
// Section Adresse
|
|
FormSection(
|
|
title: 'Adresse',
|
|
icon: Icons.location_on,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 1,
|
|
child: CustomTextField(
|
|
controller: _numeroController,
|
|
label: "Numéro",
|
|
isRequired: true,
|
|
showLabel: false,
|
|
textAlign: TextAlign.right,
|
|
keyboardType: TextInputType.number,
|
|
readOnly: widget.readOnly,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
flex: 1,
|
|
child: CustomTextField(
|
|
controller: _rueBisController,
|
|
label: "Bis/Ter",
|
|
showLabel: false,
|
|
readOnly: widget.readOnly,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
CustomTextField(
|
|
controller: _rueController,
|
|
label: "Rue",
|
|
isRequired: true,
|
|
showLabel: false,
|
|
readOnly: widget.readOnly,
|
|
),
|
|
const SizedBox(height: 16),
|
|
CustomTextField(
|
|
controller: _villeController,
|
|
label: "Ville",
|
|
isRequired: true,
|
|
showLabel: false,
|
|
readOnly: widget.readOnly,
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
// Section Occupant
|
|
FormSection(
|
|
title: 'Occupant',
|
|
icon: Icons.person,
|
|
children: [
|
|
CustomTextField(
|
|
controller: _nameController,
|
|
label: "Nom de l'occupant",
|
|
isRequired: true,
|
|
showLabel: false,
|
|
readOnly: widget.readOnly,
|
|
),
|
|
const SizedBox(height: 16),
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: CustomTextField(
|
|
controller: _emailController,
|
|
label: "Email",
|
|
showLabel: false,
|
|
keyboardType: TextInputType.emailAddress,
|
|
readOnly: widget.readOnly,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: CustomTextField(
|
|
controller: _phoneController,
|
|
label: "Téléphone",
|
|
showLabel: false,
|
|
keyboardType: TextInputType.phone,
|
|
readOnly: widget.readOnly,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 24),
|
|
|
|
// Section Règlement (sans bordure)
|
|
FormSection(
|
|
title: '',
|
|
showBorder: true,
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: CustomTextField(
|
|
controller: _montantController,
|
|
label: "Montant (€)",
|
|
isRequired: true,
|
|
showLabel: false,
|
|
hintText: "0.00",
|
|
textAlign: TextAlign.right,
|
|
keyboardType: const TextInputType.numberWithOptions(decimal: true),
|
|
readOnly: widget.readOnly,
|
|
),
|
|
),
|
|
const SizedBox(width: 12),
|
|
Expanded(
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
decoration: BoxDecoration(
|
|
border: Border.all(color: Theme.of(context).colorScheme.outline),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: const Text("Dropdown de type de règlement"),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 16),
|
|
CustomTextField(
|
|
controller: _remarqueController,
|
|
label: "Remarque",
|
|
showLabel: false,
|
|
hintText: "Commentaire sur le passage...",
|
|
maxLines: 2,
|
|
readOnly: widget.readOnly,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |