# GEOSECTOR Une application puissante et intuitive de gestion de vos distributions de calendriers par secteurs géographiques pour les amicales de pompiers. ## 📱 Présentation GEOSECTOR est une application Flutter qui permet aux amicales de pompiers de gérer efficacement la distribution de calendriers par secteurs géographiques. ### Fonctionnalités principales - **Gestion des secteurs géographiques** avec cartes interactives (Flutter Map) - **Suivi des passages** avec géolocalisation - **Interface différenciée** : utilisateur et administrateur - **Authentification sécurisée** avec gestion des rôles@ - **Chat intégré** avec système de notifications - **Stockage local** avec synchronisation en ligne - **Support multi-plateforme** : Web, iOS, Android ## 🏗️ Architecture ### Stack technique - **Framework** : Flutter 3.32 - **Routing** : Go Router - **Base de données locale** : Hive - **Gestion d'état** : Provider + Repository Pattern - **Cartes** : Flutter Map avec Mapbox - **API** : Dio pour les requêtes HTTP - **Chat** : MQTT5 Client ### Architecture de données : Hive + Provider + Repository L'application utilise une architecture en couches pour la gestion des données : ``` UI Layer (Widgets) ↓ Provider Layer (State Management) ↓ Repository Layer (Business Logic) ↓ Data Layer (Hive + API) ``` #### Couches de l'architecture 1. **UI Layer** : Widgets Flutter qui affichent les données 2. **Provider Layer** : Gestion d'état avec ChangeNotifier 3. **Repository Layer** : Logique métier et orchestration des sources de données 4. **Data Layer** : Stockage local (Hive) et API distante ### Structure des dossiers ``` lib/ ├── core/ │ ├── config/ │ ├── constants/ │ ├── errors/ │ ├── network/ │ └── utils/ ├── data/ │ ├── datasources/ │ ├── models/ │ └── repositories/ ├── domain/ │ ├── entities/ │ ├── repositories/ │ └── usecases/ ├── presentation/ │ ├── pages/ │ ├── providers/ │ ├── widgets/ │ └── theme/ └── main.dart ``` ## 🚀 Installation et configuration ### Prérequis - Flutter 3.x - Dart SDK - Android Studio / VS Code - Émulateur ou appareil physique ### Installation 1. **Cloner le repository** ```bash git clone https://github.com/votre-repo/geosector.git cd geosector ``` 2. **Installer les dépendances** ```bash flutter pub get ``` 3. **Configuration des clés API** Créer un fichier `.env` à la racine : ```env MAPBOX_ACCESS_TOKEN=your_mapbox_token API_BASE_URL=https://your-api.com MQTT_BROKER_URL=your-mqtt-broker ``` 4. **Lancer l'application** ```bash flutter run ``` ## 📦 Dépendances principales ```yaml dependencies: flutter: sdk: flutter # État et navigation provider: ^6.1.1 go_router: ^12.1.3 # Stockage local hive: ^2.2.3 hive_flutter: ^1.1.0 # Réseau dio: ^5.4.0 # Cartes flutter_map: ^6.1.0 geolocator: ^10.1.0 # Chat mqtt5_client: ^4.2.0 # UI flutter_screenutil: ^5.9.0 cached_network_image: ^3.3.0 dev_dependencies: hive_generator: ^2.0.1 build_runner: ^2.4.7 ``` ## 🗄️ Modèles de données ### Secteur ```dart @HiveType(typeId: 0) class Secteur extends HiveObject { @HiveField(0) String id; @HiveField(1) String nom; @HiveField(2) List polygone; @HiveField(3) String couleur; @HiveField(4) int nombreCalendriers; @HiveField(5) DateTime dateCreation; } ``` ### Passage ```dart @HiveType(typeId: 1) class Passage extends HiveObject { @HiveField(0) String id; @HiveField(1) String secteurId; @HiveField(2) String utilisateurId; @HiveField(3) DateTime datePassage; @HiveField(4) LatLng position; @HiveField(5) int calendriersDistribues; @HiveField(6) String commentaire; @HiveField(7) List photos; } ``` ### Utilisateur ```dart @HiveType(typeId: 2) class Utilisateur extends HiveObject { @HiveField(0) String id; @HiveField(1) String nom; @HiveField(2) String email; @HiveField(3) String role; // 'admin' ou 'user' @HiveField(4) List secteursAssignes; @HiveField(5) DateTime dernierLogin; } ``` ## 🔧 Gestion d'état avec Provider ### SecteurProvider ```dart class SecteurProvider extends ChangeNotifier { final SecteurRepository _repository; List _secteurs = []; bool _isLoading = false; List get secteurs => _secteurs; bool get isLoading => _isLoading; Future loadSecteurs() async { _isLoading = true; notifyListeners(); try { _secteurs = await _repository.getAllSecteurs(); } catch (e) { // Gestion d'erreur } finally { _isLoading = false; notifyListeners(); } } } ``` ## 🗺️ Cartes et géolocalisation ### Configuration Flutter Map ```dart FlutterMap( options: MapOptions( center: LatLng(46.2276, 2.2137), // Centre de la France zoom: 6.0, ), children: [ TileLayer( urlTemplate: 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', additionalOptions: { 'accessToken': mapboxToken, 'id': 'mapbox/streets-v11', }, ), PolygonLayer( polygons: secteurs.map((secteur) => Polygon( points: secteur.polygone, color: Color(int.parse(secteur.couleur)), borderColor: Colors.black, borderStrokeWidth: 2.0, )).toList(), ), ], ) ``` ## 💬 Chat intégré ### Configuration MQTT ```dart class ChatService { late MqttClient client; Future connect() async { client = MqttClient('mqtt://broker-url', 'client-id'); await client.connect(); client.subscribe('geosector/chat', MqttQos.atLeastOnce); client.updates!.listen((messages) { // Traitement des messages }); } } ``` ## 🔐 Authentification ### Gestion des rôles ```dart class AuthProvider extends ChangeNotifier { Utilisateur? _currentUser; bool get isAdmin => _currentUser?.role == 'admin'; bool get isAuthenticated => _currentUser != null; Future login(String email, String password) async { // Logique d'authentification } void logout() { _currentUser = null; notifyListeners(); } } ``` ## 📱 Interface utilisateur ### Thème de l'application ```dart class AppTheme { static ThemeData get lightTheme => ThemeData( primarySwatch: Colors.red, appBarTheme: AppBarTheme( backgroundColor: Colors.red[700], elevation: 0, ), elevatedButtonTheme: ElevatedButtonThemeData( style: ElevatedButton.styleFrom( backgroundColor: Colors.red[700], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), ), ); } ``` ## 🔄 Synchronisation des données ### Repository Pattern ```dart class SecteurRepository { final SecteurLocalDataSource _localDataSource; final SecteurRemoteDataSource _remoteDataSource; Future> getAllSecteurs() async { try { // Essayer de récupérer depuis l'API final remoteSecteurs = await _remoteDataSource.getAllSecteurs(); await _localDataSource.cacheSecteurs(remoteSecteurs); return remoteSecteurs; } catch (e) { // Fallback sur le cache local return await _localDataSource.getAllSecteurs(); } } } ``` ## 🧪 Tests ### Tests unitaires ```bash flutter test ``` ### Tests d'intégration ```bash flutter test integration_test/ ``` ## 📚 Documentation - [Guide d'utilisation](docs/guide-utilisation.md) - [API Reference](docs/api-reference.md) - [Architecture détaillée](docs/architecture.md) - [Contribution](docs/contributing.md) ## 🤝 Contribution 1. Fork le projet 2. Créer une branche feature (`git checkout -b feature/AmazingFeature`) 3. Commit vos changements (`git commit -m 'Add some AmazingFeature'`) 4. Push vers la branche (`git push origin feature/AmazingFeature`) 5. Ouvrir une Pull Request ## 📄 Licence Distribué sous la licence MIT. Voir `LICENSE` pour plus d'informations. ## 👥 Équipe - **Développeur Principal** - [@votre-username](https://github.com/votre-username) - **Designer UI/UX** - [@designer-username](https://github.com/designer-username) ## 📞 Support Pour toute question ou problème : - 📧 Email : support@geosector.com - 🐛 Issues : [GitHub Issues](https://github.com/votre-repo/geosector/issues) - 📖 Documentation : [Wiki](https://github.com/votre-repo/geosector/wiki) --- **GEOSECTOR** - Simplifiant la gestion des distributions de calendriers pour les amicales de pompiers 🚒