feat: Gestion des secteurs et migration v3.0.4+304

- 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>
This commit is contained in:
pierre
2025-08-07 11:01:45 +02:00
parent 3bbc599ab4
commit 1018b86537
620 changed files with 120502 additions and 91396 deletions

View File

@@ -89,7 +89,8 @@ class PassageSummaryCard extends StatelessWidget {
child: Icon(
backgroundIcon,
size: backgroundIconSize,
color: (backgroundIconColor ?? AppTheme.primaryColor).withOpacity(backgroundIconOpacity),
color: (backgroundIconColor ?? AppTheme.primaryColor)
.withOpacity(backgroundIconOpacity),
),
),
),
@@ -118,7 +119,7 @@ class PassageSummaryCard extends StatelessWidget {
? _buildPassagesListWithValueListenable()
: _buildPassagesListWithStaticData(),
),
// Séparateur vertical
if (isDesktop) const VerticalDivider(width: 24),
@@ -157,7 +158,8 @@ class PassageSummaryCard extends StatelessWidget {
/// Construction du titre avec ValueListenableBuilder
Widget _buildTitleWithValueListenable() {
return ValueListenableBuilder(
valueListenable: Hive.box<PassageModel>(AppKeys.passagesBoxName).listenable(),
valueListenable:
Hive.box<PassageModel>(AppKeys.passagesBoxName).listenable(),
builder: (context, Box<PassageModel> passagesBox, child) {
final totalUserPassages = _calculateUserPassagesCount(passagesBox);
@@ -181,7 +183,8 @@ class PassageSummaryCard extends StatelessWidget {
),
),
Text(
customTotalDisplay?.call(totalUserPassages) ?? totalUserPassages.toString(),
customTotalDisplay?.call(totalUserPassages) ??
totalUserPassages.toString(),
style: TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
@@ -196,8 +199,9 @@ class PassageSummaryCard extends StatelessWidget {
/// Construction du titre avec données statiques
Widget _buildTitleWithStaticData() {
final totalPassages = passagesByType?.values.fold(0, (sum, count) => sum + count) ?? 0;
final totalPassages =
passagesByType?.values.fold(0, (sum, count) => sum + count) ?? 0;
return Row(
children: [
if (titleIcon != null) ...[
@@ -232,7 +236,8 @@ class PassageSummaryCard extends StatelessWidget {
/// Construction de la liste des passages avec ValueListenableBuilder
Widget _buildPassagesListWithValueListenable() {
return ValueListenableBuilder(
valueListenable: Hive.box<PassageModel>(AppKeys.passagesBoxName).listenable(),
valueListenable:
Hive.box<PassageModel>(AppKeys.passagesBoxName).listenable(),
builder: (context, Box<PassageModel> passagesBox, child) {
final passagesCounts = _calculatePassagesCounts(passagesBox);
@@ -293,7 +298,7 @@ class PassageSummaryCard extends StatelessWidget {
],
),
);
}).toList(),
}),
],
);
}
@@ -309,7 +314,7 @@ class PassageSummaryCard extends StatelessWidget {
// Pour les utilisateurs : seulement leurs passages
final currentUser = userRepository.getCurrentUser();
final targetUserId = userId ?? currentUser?.id;
if (targetUserId == null) return 0;
return passagesBox.values
@@ -338,7 +343,7 @@ class PassageSummaryCard extends StatelessWidget {
// Pour les utilisateurs : compter seulement leurs passages
final currentUser = userRepository.getCurrentUser();
final targetUserId = userId ?? currentUser?.id;
if (targetUserId != null) {
for (final passage in passagesBox.values) {
if (passage.fkUser == targetUserId) {
@@ -350,4 +355,4 @@ class PassageSummaryCard extends StatelessWidget {
return counts;
}
}
}