Refactor TravelMate Admin: Remove quickstart and SQL reference documents, update app settings to use JSON configuration, enhance database service error handling, and implement MVVM pattern with observable properties for messages and support requests. Update UI to display connection errors and improve navigation.

This commit is contained in:
Van Leemput Dayron
2026-01-12 19:23:57 +01:00
parent f9690045ea
commit 1c89209cfa
20 changed files with 207 additions and 1702 deletions

3
.gitignore vendored
View File

@@ -52,3 +52,6 @@ bld/
# Configuration sensible - NE PAS COMMIT ! # Configuration sensible - NE PAS COMMIT !
# Décommentez si vous voulez ignorer votre configuration locale # Décommentez si vous voulez ignorer votre configuration locale
# **/Configuration/AppSettings.cs # **/Configuration/AppSettings.cs
appsettings.json
.env

View File

@@ -1,182 +0,0 @@
# 📅 Changelog - TravelMate Admin
Toutes les modifications notables de ce projet seront documentées dans ce fichier.
Le format est basé sur [Keep a Changelog](https://keepachangelog.com/fr/1.0.0/),
et ce projet adhère à [Semantic Versioning](https://semver.org/lang/fr/).
## [1.0.0] - 2026-01-12
### ✨ Ajouté
#### Architecture & Structure
- Architecture MVVM complète avec CommunityToolkit.Mvvm
- Pattern strict avec séparation Models/Views/ViewModels/Services
- Injection de dépendances configurée dans MauiProgram.cs
- Navigation Shell avec TabBar
#### Models
- `Message.cs` : Modèle pour les messages de demande avec propriétés calculées
- `SupportRequest.cs` : Modèle pour les demandes support avec propriétés calculées
#### Services
- `IDatabaseService.cs` : Interface du service de base de données
- `DatabaseService.cs` : Implémentation complète avec MySqlConnector
- Connexion à MariaDB/MySQL
- Méthodes CRUD asynchrones
- Gestion des erreurs et logs
- Test de connexion
#### ViewModels
- `DashboardViewModel.cs` : Gestion du tableau de bord avec statistiques
- `MessagesViewModel.cs` : Gestion de la liste des messages avec filtres
- `SupportViewModel.cs` : Gestion des demandes support avec filtres
- Utilisation de `[ObservableProperty]` et `[RelayCommand]`
- Commandes asynchrones pour toutes les opérations
#### Views
- `DashboardPage.xaml/.cs` : Page principale avec cartes de statistiques
- `MessagesPage.xaml/.cs` : Liste des messages avec CollectionView
- `SupportPage.xaml/.cs` : Liste des demandes support
- Design moderne avec dark theme (#1a1a1a)
- Layout responsive
- Indicateurs de chargement
#### UI/UX
- Dark theme par défaut avec palette de couleurs cohérente
- Cartes avec ombres et coins arrondis
- Animations smooth pour les interactions
- Empty states pour listes vides
- Pull-to-refresh sur les listes
- Filtres dynamiques (Tout / À faire / Fait)
#### Converters
- `BoolToStatusTextConverter` : Conversion bool → texte bouton
- `BoolToColorConverter` : Conversion bool → couleur bouton
#### Configuration
- `AppSettings.cs` : Configuration centralisée de la connexion DB
- Paramètres modifiables (Server, Port, Database, User, Password)
#### Base de Données
- Script SQL `database_setup.sql` complet :
- Création de la base `travelmateadmin`
- Table `messages` avec 8 colonnes et index
- Table `support_requests` avec 8 colonnes et index
- 4 messages de test
- 4 demandes support de test
- Encodage UTF-8 (utf8mb4)
#### Fonctionnalités
- Dashboard avec statistiques en temps réel
- Filtrage des demandes (tout/à faire/fait)
- Changement de statut d'une demande (toggle done)
- Tri par date (plus récent en haut)
- Rafraîchissement manuel des données
- Navigation entre les sections
- Indicateur de connexion DB
#### Packages NuGet
- `CommunityToolkit.Mvvm` v8.3.2
- `MySqlConnector` v2.4.0
#### Documentation
- `README.md` : Documentation complète du projet (sections détaillées)
- `QUICKSTART.md` : Guide de démarrage rapide (5 minutes)
- `CONFIGURATION.md` : Guide de configuration DB avec exemples
- `ARCHITECTURE.md` : Documentation architecture MVVM détaillée
- `COMMANDS.md` : Référence des commandes de développement
- `SQL_REFERENCE.md` : Référence complète des requêtes SQL
- `PROJECT_SUMMARY.md` : Résumé du projet et checklist
- `.gitignore` : Configuration Git adaptée .NET MAUI
#### DevOps
- Configuration csproj pour multi-plateforme (Mac/Win/Android/iOS)
- Build scripts pour toutes les plateformes
- Compilation vérifiée et réussie
### 🎯 Plateformes Supportées
- ✅ macOS (MacCatalyst) - net10.0-maccatalyst
- ✅ Windows - net10.0-windows10.0.19041.0
- ⚠️ Android - net10.0-android (non testé)
- ⚠️ iOS - net10.0-ios (non testé)
### 📊 Statistiques
- **Fichiers créés** : 35+
- **Lignes de code** : ~2000+ (C# + XAML)
- **Modèles** : 2
- **Services** : 1 (+ interface)
- **ViewModels** : 3
- **Views** : 3 (+ code-behind)
- **Documentation** : 8 fichiers MD
---
## [Unreleased] - Fonctionnalités Futures
### 🚀 Planifié pour v1.1.0
- [ ] Mode light/dark configurable
- [ ] Recherche/filtrage avancé
- [ ] Export de données (CSV, PDF)
- [ ] Pagination pour grandes listes
- [ ] Statistiques graphiques (charts)
### 🔮 Planifié pour v1.2.0
- [ ] Authentification utilisateur
- [ ] Gestion des permissions
- [ ] Historique des modifications
- [ ] Notifications push
- [ ] Multi-langue (i18n)
### 🧪 Planifié pour v1.3.0
- [ ] Tests unitaires (ViewModels)
- [ ] Tests d'intégration (Services)
- [ ] CI/CD avec GitHub Actions
- [ ] Couverture de code
### 🎨 Améliorations UI/UX
- [ ] Animations de transitions
- [ ] Thèmes personnalisables
- [ ] Accessibilité (screen readers)
- [ ] Raccourcis clavier
### 🔧 Améliorations Techniques
- [ ] Connection pooling optimisé
- [ ] Cache des données
- [ ] Offline mode
- [ ] Synchronisation automatique
- [ ] Logs structurés (Serilog)
### 🔐 Sécurité
- [ ] Chiffrement de la chaîne de connexion
- [ ] Variables d'environnement
- [ ] Azure Key Vault integration
- [ ] Audit trail
- [ ] Rate limiting
---
## Types de Changements
- `Added` ✨ : Nouvelles fonctionnalités
- `Changed` 🔄 : Modifications de fonctionnalités existantes
- `Deprecated` ⚠️ : Fonctionnalités bientôt supprimées
- `Removed` 🗑️ : Fonctionnalités supprimées
- `Fixed` 🐛 : Corrections de bugs
- `Security` 🔐 : Corrections de sécurité
---
## Format des Versions
```
[MAJOR.MINOR.PATCH] - YYYY-MM-DD
MAJOR : Changements incompatibles de l'API
MINOR : Nouvelles fonctionnalités rétrocompatibles
PATCH : Corrections de bugs rétrocompatibles
```
---
**Note** : Ce fichier sera mis à jour à chaque release avec les changements apportés.

View File

@@ -1,311 +0,0 @@
# Commandes Utiles - TravelMate Admin
## 🔧 Développement
### Restaurer les packages
```bash
dotnet restore
```
### Build le projet
```bash
# MacCatalyst
dotnet build -f net10.0-maccatalyst
# Windows
dotnet build -f net10.0-windows10.0.19041.0
# Android
dotnet build -f net10.0-android
# iOS
dotnet build -f net10.0-ios
```
### Lancer l'application
```bash
# MacCatalyst
dotnet build -t:Run -f net10.0-maccatalyst
# Windows
dotnet build -t:Run -f net10.0-windows10.0.19041.0
```
### Nettoyer le projet
```bash
dotnet clean
rm -rf TravelMateAdmin/bin TravelMateAdmin/obj
```
### Rebuild complet
```bash
dotnet clean
dotnet restore
dotnet build
```
## 🗄️ Base de Données
### Créer la base de données
```bash
mysql -u root -p < database_setup.sql
```
### Se connecter à MySQL
```bash
mysql -u root -p travelmateadmin
```
### Afficher les tables
```sql
USE travelmateadmin;
SHOW TABLES;
```
### Voir les données
```sql
-- Tous les messages
SELECT * FROM messages ORDER BY created_at DESC;
-- Messages en attente
SELECT * FROM messages WHERE done = FALSE;
-- Statistiques
SELECT
COUNT(*) as total,
SUM(done = FALSE) as pending,
SUM(done = TRUE) as completed
FROM messages;
```
### Ajouter un message de test
```sql
INSERT INTO messages (nom, prenom, email, message, done, created_at)
VALUES ('Test', 'User', 'test@example.com', 'Ceci est un test', FALSE, NOW());
```
### Marquer tous les messages comme non traités
```sql
UPDATE messages SET done = FALSE;
UPDATE support_requests SET done = FALSE;
```
### Réinitialiser les données
```bash
mysql -u root -p travelmateadmin < database_setup.sql
```
### Backup de la base
```bash
mysqldump -u root -p travelmateadmin > backup_$(date +%Y%m%d_%H%M%S).sql
```
### Restore depuis un backup
```bash
mysql -u root -p travelmateadmin < backup_20260112_143000.sql
```
## 📦 NuGet Packages
### Voir les packages installés
```bash
dotnet list TravelMateAdmin/TravelMateAdmin.csproj package
```
### Mettre à jour un package
```bash
dotnet add TravelMateAdmin/TravelMateAdmin.csproj package CommunityToolkit.Mvvm
dotnet add TravelMateAdmin/TravelMateAdmin.csproj package MySqlConnector
```
### Mettre à jour tous les packages
```bash
dotnet list TravelMateAdmin/TravelMateAdmin.csproj package --outdated
```
## 🐛 Debugging
### Voir les logs
Dans le terminal où vous avez lancé l'app, les logs apparaissent via :
```csharp
System.Diagnostics.Debug.WriteLine("Mon log");
```
### Tests de connexion MySQL
```bash
# Tester si MySQL est accessible
nc -zv localhost 3306
# Voir les processus MySQL
ps aux | grep mysql
# Démarrer MySQL (Mac avec Homebrew)
brew services start mysql
# Démarrer MySQL (Linux)
sudo service mysql start
# Démarrer MySQL (MAMP)
# Utiliser l'interface MAMP
```
## 📱 Plateforme Spécifique
### MacCatalyst - Voir les logs système
```bash
log stream --predicate 'processImagePath contains "TravelMateAdmin"' --level debug
```
### Android - Voir les logs
```bash
adb logcat | grep TravelMateAdmin
```
### iOS Simulator - Voir les logs
```bash
xcrun simctl spawn booted log stream --level debug | grep TravelMateAdmin
```
## 🔍 Code Analysis
### Format le code
```bash
dotnet format TravelMateAdmin/TravelMateAdmin.csproj
```
### Analyser le code
```bash
dotnet build /p:TreatWarningsAsErrors=true
```
## 📊 Statistiques du Projet
### Compter les lignes de code
```bash
find TravelMateAdmin -name "*.cs" -not -path "*/obj/*" -not -path "*/bin/*" | xargs wc -l
```
### Voir l'arborescence
```bash
tree -I 'bin|obj' TravelMateAdmin/
```
### Taille du projet
```bash
du -sh TravelMateAdmin/
```
## 🚀 Publication
### Publish MacCatalyst
```bash
dotnet publish -f net10.0-maccatalyst -c Release -p:CreatePackage=true
```
### Publish Windows
```bash
dotnet publish -f net10.0-windows10.0.19041.0 -c Release
```
### Créer un package pour Mac App Store
```bash
dotnet publish -f net10.0-maccatalyst -c Release \
-p:RuntimeIdentifier=maccatalyst-arm64 \
-p:CreatePackage=true \
-p:CodesignKey="Apple Distribution: Your Name" \
-p:CodesignProvision="Your Provisioning Profile"
```
## 🧪 Tests (futur)
### Ajouter un projet de tests
```bash
dotnet new xunit -n TravelMateAdmin.Tests
dotnet sln add TravelMateAdmin.Tests/TravelMateAdmin.Tests.csproj
dotnet add TravelMateAdmin.Tests reference TravelMateAdmin/TravelMateAdmin.csproj
```
### Lancer les tests
```bash
dotnet test
```
## 📝 Git
### Initialiser le repo
```bash
git init
git add .
git commit -m "Initial commit: TravelMate Admin MAUI app"
```
### Ignorer les fichiers de build
Le `.gitignore` est déjà configuré pour :
- bin/, obj/
- .vs/, .vscode/
- Configuration sensible
### Créer une branche
```bash
git checkout -b feature/nouvelle-fonctionnalite
```
## 🔐 Sécurité
### Chiffrer la configuration (exemple)
```bash
# Générer une clé
openssl rand -base64 32
# Chiffrer un fichier
openssl enc -aes-256-cbc -salt -in AppSettings.cs -out AppSettings.cs.enc
# Déchiffrer
openssl enc -d -aes-256-cbc -in AppSettings.cs.enc -out AppSettings.cs
```
## 🛠️ Maintenance
### Vérifier les dépendances obsolètes
```bash
dotnet list package --outdated
```
### Mettre à jour .NET
```bash
# Vérifier la version actuelle
dotnet --version
# Télécharger la dernière version
# https://dotnet.microsoft.com/download
```
### Nettoyer NuGet cache
```bash
dotnet nuget locals all --clear
```
---
## 💡 Tips & Tricks
### Hot Reload
Lors du développement, les changements XAML sont appliqués en temps réel avec Hot Reload.
### Raccourcis Visual Studio
- `F5` : Run avec debug
- `Ctrl+F5` (Cmd+F5 Mac) : Run sans debug
- `Shift+F5` : Stop debugging
### Performance
```bash
# Build en Release pour tester les performances réelles
dotnet build -c Release -f net10.0-maccatalyst
```
### Multi-targeting
Pour cibler plusieurs plateformes en une fois :
```bash
dotnet build
# Build toutes les plateformes définies dans TargetFrameworks
```

View File

@@ -1,102 +0,0 @@
# Configuration de l'Application TravelMate Admin
## Configuration de Base de Données
Pour configurer la connexion à votre base de données, modifiez le fichier :
`TravelMateAdmin/Configuration/AppSettings.cs`
### Exemple pour une connexion locale :
```csharp
public const string Server = "localhost";
public const string Port = "3306";
public const string Database = "travelmateadmin";
public const string User = "root";
public const string Password = "monmotdepasse";
```
### Exemple pour une connexion distante :
```csharp
public const string Server = "192.168.1.100"; // IP du serveur
public const string Port = "3306";
public const string Database = "travelmateadmin";
public const string User = "admin";
public const string Password = "motdepassesecurise";
```
### Exemple avec un serveur cloud (ex: AWS RDS, Azure Database) :
```csharp
public const string Server = "myserver.mysql.database.azure.com";
public const string Port = "3306";
public const string Database = "travelmateadmin";
public const string User = "myadmin@myserver";
public const string Password = "P@ssw0rd!";
```
## Sécurité
⚠️ **Important** : Ne commitez JAMAIS vos mots de passe dans Git !
Pour une meilleure sécurité en production :
1. Utilisez des variables d'environnement
2. Utilisez un système de gestion des secrets (Azure Key Vault, AWS Secrets Manager)
3. Chiffrez la chaîne de connexion
### Exemple avec variables d'environnement :
```csharp
public static string GetConnectionString()
{
var server = Environment.GetEnvironmentVariable("DB_SERVER") ?? Server;
var port = Environment.GetEnvironmentVariable("DB_PORT") ?? Port;
var database = Environment.GetEnvironmentVariable("DB_NAME") ?? Database;
var user = Environment.GetEnvironmentVariable("DB_USER") ?? User;
var password = Environment.GetEnvironmentVariable("DB_PASSWORD") ?? Password;
return $"Server={server};Port={port};Database={database};User={user};Password={password};";
}
```
## Paramètres Supplémentaires MySQL
Vous pouvez ajouter des paramètres supplémentaires à la chaîne de connexion :
```csharp
public static string GetConnectionString()
{
return $"Server={Server};Port={Port};Database={Database};User={User};Password={Password};" +
"SslMode=Required;" + // Pour SSL/TLS
"AllowPublicKeyRetrieval=True;" + // Pour l'authentification
"ConnectionTimeout=30;" + // Timeout en secondes
"DefaultCommandTimeout=30;"; // Timeout des commandes
}
```
## Test de Connexion
Pour tester votre connexion, lancez l'application et vérifiez :
1. Le dashboard doit afficher "✓ Connecté" en haut à droite
2. Les statistiques doivent se charger
3. Si "✗ Déconnecté", vérifiez vos paramètres et les logs de débogage
## Dépannage Connexion
### Erreur "Access denied"
- Vérifiez le nom d'utilisateur et le mot de passe
- Vérifiez que l'utilisateur a les droits sur la base de données :
```sql
GRANT ALL PRIVILEGES ON travelmateadmin.* TO 'user'@'localhost';
FLUSH PRIVILEGES;
```
### Erreur "Cannot connect to server"
- Vérifiez que MySQL est démarré
- Vérifiez le serveur et le port
- Vérifiez les règles de firewall
### Erreur "Unknown database"
- Vérifiez que la base de données existe
- Exécutez le script `database_setup.sql`

232
INDEX.md
View File

@@ -1,232 +0,0 @@
# 📚 Index de Documentation - TravelMate Admin
Guide complet pour naviguer dans la documentation du projet.
---
## 🚀 Pour Commencer
**Nouveau sur le projet ? Commencez ici :**
1. 📖 [README.md](README.md) - **Lisez-moi d'abord** - Vue d'ensemble du projet
2. ⚡ [QUICKSTART.md](QUICKSTART.md) - Installation en 5 minutes
3. 🎉 Lancez l'application !
---
## 📂 Documentation par Catégorie
### 🏗️ Architecture & Développement
| Fichier | Description | Quand le consulter |
|---------|-------------|-------------------|
| [ARCHITECTURE.md](ARCHITECTURE.md) | Architecture MVVM détaillée, flux de données, patterns | Comprendre la structure du code |
| [PROJECT_SUMMARY.md](PROJECT_SUMMARY.md) | Résumé complet, fichiers créés, checklist | Vue d'ensemble technique |
| [CHANGELOG.md](CHANGELOG.md) | Historique des versions et modifications | Voir les changements apportés |
### ⚙️ Configuration & Installation
| Fichier | Description | Quand le consulter |
|---------|-------------|-------------------|
| [QUICKSTART.md](QUICKSTART.md) | Guide rapide d'installation (5 min) | Première installation |
| [CONFIGURATION.md](CONFIGURATION.md) | Configuration de la base de données | Problèmes de connexion DB |
| [README.md](README.md) | Guide complet avec tous les détails | Documentation générale |
### 💻 Développement & Maintenance
| Fichier | Description | Quand le consulter |
|---------|-------------|-------------------|
| [COMMANDS.md](COMMANDS.md) | Commandes utiles (build, DB, debug) | Tâches de développement |
| [SQL_REFERENCE.md](SQL_REFERENCE.md) | Requêtes SQL complètes | Gérer la base de données |
### 📊 Base de Données
| Fichier | Description | Quand le consulter |
|---------|-------------|-------------------|
| [database_setup.sql](database_setup.sql) | Script SQL de création + données test | Initialiser la DB |
| [SQL_REFERENCE.md](SQL_REFERENCE.md) | Guide complet des requêtes SQL | Opérations sur les données |
---
## 🎯 Guides par Scénario
### Scénario 1 : Je veux installer l'app rapidement
1. [QUICKSTART.md](QUICKSTART.md) - Suivez les 5 étapes
2. [database_setup.sql](database_setup.sql) - Exécutez ce script
3. Modifiez `TravelMateAdmin/Configuration/AppSettings.cs`
4. Lancez l'app !
### Scénario 2 : J'ai des problèmes de connexion DB
1. [CONFIGURATION.md](CONFIGURATION.md) - Guide de dépannage
2. Vérifiez `AppSettings.cs`
3. [COMMANDS.md](COMMANDS.md) - Commandes de test MySQL
### Scénario 3 : Je veux comprendre le code
1. [ARCHITECTURE.md](ARCHITECTURE.md) - Pattern MVVM expliqué
2. [PROJECT_SUMMARY.md](PROJECT_SUMMARY.md) - Structure des fichiers
3. Lisez les commentaires dans le code source
### Scénario 4 : Je veux ajouter une fonctionnalité
1. [ARCHITECTURE.md](ARCHITECTURE.md) - Section "Extensibilité"
2. [COMMANDS.md](COMMANDS.md) - Commandes de build/test
3. Suivez le pattern existant (Models → Services → ViewModels → Views)
### Scénario 5 : Je veux gérer les données
1. [SQL_REFERENCE.md](SQL_REFERENCE.md) - Toutes les requêtes SQL
2. [COMMANDS.md](COMMANDS.md) - Section "Base de Données"
### Scénario 6 : Je veux personnaliser l'UI
1. [README.md](README.md) - Section "Personnalisation"
2. Modifiez les couleurs dans les fichiers XAML
3. Consultez les Views existantes comme exemples
---
## 📖 Structure de la Documentation
```
Documentation/
├── README.md ⭐ Point d'entrée principal
├── QUICKSTART.md 🚀 Installation rapide
├── ARCHITECTURE.md 🏗️ Architecture technique
├── CONFIGURATION.md ⚙️ Configuration DB
├── COMMANDS.md 💻 Commandes de dev
├── SQL_REFERENCE.md 📊 Référence SQL
├── PROJECT_SUMMARY.md 📝 Résumé complet
├── CHANGELOG.md 📅 Historique des versions
└── INDEX.md 📚 Ce fichier
Code Source/
├── TravelMateAdmin/
│ ├── Models/ 📦 Modèles de données
│ ├── Services/ 🔧 Couche d'accès aux données
│ ├── ViewModels/ 🎭 Logique de présentation
│ ├── Views/ 🎨 Interface utilisateur
│ ├── Converters/ 🔄 Converters XAML
│ └── Configuration/ ⚙️ Configuration app
Base de Données/
└── database_setup.sql 🗄️ Script SQL
```
---
## 🔍 Index par Mots-Clés
### A
- **Architecture MVVM** → [ARCHITECTURE.md](ARCHITECTURE.md)
- **Ajouter une fonctionnalité** → [ARCHITECTURE.md](ARCHITECTURE.md#extensibilité)
### B
- **Base de données** → [CONFIGURATION.md](CONFIGURATION.md), [SQL_REFERENCE.md](SQL_REFERENCE.md)
- **Build** → [COMMANDS.md](COMMANDS.md#développement)
- **Backup** → [COMMANDS.md](COMMANDS.md#base-de-données)
### C
- **Commandes** → [COMMANDS.md](COMMANDS.md)
- **Configuration** → [CONFIGURATION.md](CONFIGURATION.md)
- **Connexion DB** → [CONFIGURATION.md](CONFIGURATION.md)
- **CommunityToolkit.Mvvm** → [ARCHITECTURE.md](ARCHITECTURE.md)
### D
- **Dashboard** → [PROJECT_SUMMARY.md](PROJECT_SUMMARY.md)
- **DatabaseService** → [ARCHITECTURE.md](ARCHITECTURE.md)
- **Dépannage** → [CONFIGURATION.md](CONFIGURATION.md), [QUICKSTART.md](QUICKSTART.md)
### F
- **Filtres** → [ARCHITECTURE.md](ARCHITECTURE.md)
### I
- **Installation** → [QUICKSTART.md](QUICKSTART.md)
- **Injection de dépendances** → [ARCHITECTURE.md](ARCHITECTURE.md)
### M
- **MariaDB** → [CONFIGURATION.md](CONFIGURATION.md)
- **Messages** → [README.md](README.md)
- **MySQL** → [CONFIGURATION.md](CONFIGURATION.md), [SQL_REFERENCE.md](SQL_REFERENCE.md)
- **MVVM** → [ARCHITECTURE.md](ARCHITECTURE.md)
### N
- **Navigation** → [ARCHITECTURE.md](ARCHITECTURE.md)
- **NuGet** → [COMMANDS.md](COMMANDS.md)
### P
- **Performance** → [ARCHITECTURE.md](ARCHITECTURE.md), [SQL_REFERENCE.md](SQL_REFERENCE.md)
- **Problèmes** → [QUICKSTART.md](QUICKSTART.md), [CONFIGURATION.md](CONFIGURATION.md)
### Q
- **Quick Start** → [QUICKSTART.md](QUICKSTART.md)
### R
- **Requêtes SQL** → [SQL_REFERENCE.md](SQL_REFERENCE.md)
### S
- **Sécurité** → [CONFIGURATION.md](CONFIGURATION.md), [ARCHITECTURE.md](ARCHITECTURE.md)
- **Services** → [ARCHITECTURE.md](ARCHITECTURE.md)
- **SQL** → [SQL_REFERENCE.md](SQL_REFERENCE.md)
- **Support** → [PROJECT_SUMMARY.md](PROJECT_SUMMARY.md)
### T
- **Tests** → [COMMANDS.md](COMMANDS.md), [ARCHITECTURE.md](ARCHITECTURE.md)
### V
- **ViewModels** → [ARCHITECTURE.md](ARCHITECTURE.md)
- **Views** → [ARCHITECTURE.md](ARCHITECTURE.md)
### X
- **XAML** → [ARCHITECTURE.md](ARCHITECTURE.md), [README.md](README.md)
---
## 📊 Statistiques de la Documentation
| Type | Nombre | Lignes Totales |
|------|--------|----------------|
| Fichiers Markdown | 8 | ~1500+ lignes |
| Sections | 100+ | - |
| Exemples de code | 50+ | - |
| Commandes | 100+ | - |
| Requêtes SQL | 60+ | - |
---
## 🆘 Aide Rapide
**Je ne trouve pas ce que je cherche !**
1. Utilisez Ctrl+F (Cmd+F sur Mac) dans ce fichier pour chercher un mot-clé
2. Consultez la section "Guides par Scénario" ci-dessus
3. Ouvrez [README.md](README.md) pour une vue d'ensemble
4. Tous les fichiers sont en Markdown, faciles à lire avec n'importe quel éditeur
**Suggestions de documentation manquante ?**
N'hésitez pas à créer une issue ou à contribuer !
---
## 🎓 Ordre de Lecture Recommandé
### Pour les Débutants
1. [README.md](README.md) - Vue d'ensemble
2. [QUICKSTART.md](QUICKSTART.md) - Installation
3. [PROJECT_SUMMARY.md](PROJECT_SUMMARY.md) - Résumé
4. Lancez l'app et explorez !
### Pour les Développeurs
1. [ARCHITECTURE.md](ARCHITECTURE.md) - Comprendre la structure
2. [COMMANDS.md](COMMANDS.md) - Commandes de dev
3. [SQL_REFERENCE.md](SQL_REFERENCE.md) - Opérations DB
4. Code source dans TravelMateAdmin/
### Pour les Administrateurs DB
1. [CONFIGURATION.md](CONFIGURATION.md) - Configuration
2. [database_setup.sql](database_setup.sql) - Script d'installation
3. [SQL_REFERENCE.md](SQL_REFERENCE.md) - Référence complète
4. [COMMANDS.md](COMMANDS.md#base-de-données) - Maintenance
---
**Dernière mise à jour** : 12 janvier 2026
**Version de la documentation** : 1.0.0

View File

@@ -1,233 +0,0 @@
# ✅ PROJET COMPLÉTÉ - TravelMate Admin
## 📋 Résumé
Application desktop .NET MAUI (Mac/Windows) avec architecture MVVM pour gérer les demandes clients depuis une base de données MariaDB/MySQL.
---
## 🎯 Ce qui a été créé
### 1. Structure MVVM Complète
#### **Models** (2 fichiers)
-`Message.cs` - Modèle pour les messages de demande
-`SupportRequest.cs` - Modèle pour les demandes support
#### **Services** (2 fichiers)
-`IDatabaseService.cs` - Interface du service de base de données
-`DatabaseService.cs` - Implémentation avec MySqlConnector
- Connexion à MariaDB/MySQL
- CRUD operations pour messages et support_requests
- Gestion asynchrone complète
#### **ViewModels** (3 fichiers)
-`DashboardViewModel.cs` - Gestion du tableau de bord
-`MessagesViewModel.cs` - Gestion de la liste des messages
-`SupportViewModel.cs` - Gestion des demandes support
- Tous utilisent CommunityToolkit.Mvvm (ObservableProperty, RelayCommand)
#### **Views** (3 paires XAML + Code-behind)
-`DashboardPage.xaml/.cs` - Tableau de bord avec statistiques
-`MessagesPage.xaml/.cs` - Liste des messages avec filtres
-`SupportPage.xaml/.cs` - Liste des demandes support
#### **Converters** (1 fichier)
-`BoolConverters.cs` - Conversion bool → texte et couleur pour les boutons
#### **Configuration** (1 fichier)
-`AppSettings.cs` - Configuration de la connexion DB
### 2. Configuration & Infrastructure
-`MauiProgram.cs` - Injection de dépendances configurée
-`AppShell.xaml` - Navigation Shell avec 3 onglets
-`TravelMateAdmin.csproj` - Packages NuGet ajoutés :
- CommunityToolkit.Mvvm (8.3.2)
- MySqlConnector (2.4.0)
### 3. Base de Données
-`database_setup.sql` - Script SQL complet :
- Création de la base `travelmateadmin`
- Table `messages` (8 colonnes)
- Table `support_requests` (8 colonnes)
- Données de test (4 messages + 4 demandes support)
### 4. Documentation
-`README.md` - Documentation complète du projet
-`QUICKSTART.md` - Guide de démarrage rapide (5 minutes)
-`CONFIGURATION.md` - Guide de configuration DB
-`ARCHITECTURE.md` - Documentation architecture MVVM
-`COMMANDS.md` - Commandes utiles pour le développement
-`.gitignore` - Fichiers à ignorer dans Git
---
## 🎨 Fonctionnalités Implémentées
### ✅ Dashboard
- Affichage des statistiques en temps réel
- 4 cartes : Messages (en attente/traités) + Support (en attente/traités)
- Indicateur de statut de connexion
- Bouton de rafraîchissement
- Navigation vers les pages de détail
### ✅ Page Messages
- Liste complète des messages avec scroll
- Tri par date (plus récent en haut)
- Filtre : Tout / À faire / Fait
- Affichage : Nom, Prénom, Email, Message, Date, Statut
- Bouton pour changer le statut (fait ↔ en attente)
- Rafraîchissement manuel
### ✅ Page Support
- Liste des demandes support
- Même système de filtres que Messages
- Affichage : Nom, Prénom, Account Email, Contact Email, Message, Date, Statut
- Bouton pour changer le statut
- Rafraîchissement manuel
### ✅ Design
- **Dark theme** moderne et professionnel
- Couleurs configurables (Primary, Accent, Success, Warning)
- Cartes avec shadow et coins arrondis
- Layout responsive
- Indicateurs de chargement (ActivityIndicator)
---
## 🛠️ Technologies Utilisées
| Technologie | Version | Usage |
|-------------|---------|-------|
| .NET | 10.0 | Framework principal |
| .NET MAUI | Dernière | UI multi-plateforme |
| CommunityToolkit.Mvvm | 8.3.2 | Pattern MVVM |
| MySqlConnector | 2.4.0 | Connexion MariaDB/MySQL |
| XAML | - | Interface utilisateur |
---
## 📊 Structure du Projet
```
TravelMateAdmin/
├── TravelMateAdmin/ # Projet principal
│ ├── Configuration/
│ │ └── AppSettings.cs # Config DB
│ ├── Converters/
│ │ └── BoolConverters.cs # Converters XAML
│ ├── Models/
│ │ ├── Message.cs
│ │ └── SupportRequest.cs
│ ├── Services/
│ │ ├── IDatabaseService.cs
│ │ └── DatabaseService.cs
│ ├── ViewModels/
│ │ ├── DashboardViewModel.cs
│ │ ├── MessagesViewModel.cs
│ │ └── SupportViewModel.cs
│ ├── Views/
│ │ ├── DashboardPage.xaml/.cs
│ │ ├── MessagesPage.xaml/.cs
│ │ └── SupportPage.xaml/.cs
│ ├── App.xaml/.cs
│ ├── AppShell.xaml/.cs
│ ├── MauiProgram.cs
│ └── TravelMateAdmin.csproj
├── database_setup.sql # Script SQL
├── README.md # Documentation principale
├── QUICKSTART.md # Guide rapide
├── CONFIGURATION.md # Guide configuration
├── ARCHITECTURE.md # Documentation architecture
├── COMMANDS.md # Commandes utiles
└── .gitignore # Git ignore
Total: 35+ fichiers créés/modifiés
```
---
## 🚀 État du Projet
### ✅ Complété (100%)
- [x] Architecture MVVM complète
- [x] Modèles de données (Message, SupportRequest)
- [x] Service de base de données avec toutes les méthodes
- [x] ViewModels avec CommunityToolkit.Mvvm
- [x] Vues XAML avec design moderne
- [x] Converters pour l'affichage
- [x] Injection de dépendances
- [x] Navigation Shell
- [x] Script SQL avec données de test
- [x] Documentation complète
- [x] Compilation réussie ✅
### ⏭️ Étapes Suivantes (Optionnel)
- [ ] Ajouter authentification utilisateur
- [ ] Implémenter pagination pour grandes listes
- [ ] Ajouter recherche/filtrage avancé
- [ ] Exporter les données (CSV, PDF)
- [ ] Notifications push
- [ ] Tests unitaires
- [ ] Mode light/dark configurable
- [ ] Statistiques avancées (graphiques)
---
## 📝 Pour Commencer
### Option 1 : Rapide (5 minutes)
```bash
# 1. Configurer la base de données
mysql -u root -p < database_setup.sql
# 2. Modifier AppSettings.cs avec vos identifiants MySQL
# 3. Lancer l'app
dotnet build -t:Run -f net10.0-maccatalyst # Mac
# OU
dotnet build -t:Run -f net10.0-windows10.0.19041.0 # Windows
```
### Option 2 : Détaillée
Consultez `QUICKSTART.md` pour un guide pas-à-pas complet.
---
## 🎓 Points Clés de l'Architecture
1. **Séparation des responsabilités** : MVVM strict
2. **Réactivité** : INotifyPropertyChanged automatique
3. **Asynchrone** : Toutes les opérations DB sont async
4. **Injection de dépendances** : Services injectés automatiquement
5. **Testabilité** : Interface IDatabaseService mockable
6. **Extensibilité** : Facile d'ajouter de nouvelles entités
---
## 📞 Support
- **README.md** : Documentation générale
- **QUICKSTART.md** : Installation rapide
- **CONFIGURATION.md** : Problèmes de connexion DB
- **ARCHITECTURE.md** : Comprendre le code
- **COMMANDS.md** : Commandes de développement
---
## 🎉 Félicitations !
Vous avez maintenant une application d'administration complète et professionnelle avec :
- ✅ Code propre et bien structuré
- ✅ Pattern MVVM moderne
- ✅ Interface utilisateur intuitive
- ✅ Base de données intégrée
- ✅ Documentation exhaustive
- ✅ Prête à être étendue
**Prochaine étape** : Lancez l'application et explorez les fonctionnalités ! 🚀

View File

@@ -1,123 +0,0 @@
# 🚀 Guide de Démarrage Rapide - TravelMate Admin
## Installation en 5 Minutes
### Étape 1 : Prérequis ✅
Installez si nécessaire :
- [.NET 8+ SDK](https://dotnet.microsoft.com/download)
- [MySQL/MariaDB](https://dev.mysql.com/downloads/) ou [MAMP](https://www.mamp.info/) (Mac) / [XAMPP](https://www.apachefriends.org/) (Windows)
### Étape 2 : Base de Données 🗄️
**Option A - Avec MySQL en ligne de commande :**
```bash
mysql -u root -p < database_setup.sql
```
**Option B - Avec phpMyAdmin ou MySQL Workbench :**
1. Créez une base de données nommée `travelmateadmin`
2. Importez le fichier `database_setup.sql`
**Option C - Manuellement :**
```sql
CREATE DATABASE travelmateadmin;
USE travelmateadmin;
-- Puis copiez/collez le contenu de database_setup.sql
```
### Étape 3 : Configuration ⚙️
Ouvrez `TravelMateAdmin/Configuration/AppSettings.cs` et modifiez :
```csharp
public const string Server = "localhost"; // ✏️ Votre serveur
public const string Port = "3306"; // ✏️ Votre port
public const string Database = "travelmateadmin";
public const string User = "root"; // ✏️ Votre utilisateur
public const string Password = "VOTRE_MDP"; // ✏️ IMPORTANT: Changez ici !
```
### Étape 4 : Restaurer les Packages 📦
```bash
cd TravelMateAdmin
dotnet restore
```
### Étape 5 : Lancer l'Application 🎉
**Sur Mac :**
```bash
dotnet build -t:Run -f net10.0-maccatalyst
```
**Sur Windows :**
```bash
dotnet build -t:Run -f net10.0-windows10.0.19041.0
```
**Avec Visual Studio :**
1. Ouvrez `TravelMateAdmin.sln`
2. Sélectionnez la plateforme (Mac Catalyst ou Windows)
3. Appuyez sur F5 ou cliquez sur ▶️ Run
---
## ✅ Vérification
Au lancement, vous devriez voir :
- ✅ Dashboard avec les statistiques
- ✅ "✓ Connecté" en haut à droite
- ✅ 4 messages et 4 demandes support (données de test)
## ❌ Problèmes ?
### "✗ Déconnecté" s'affiche
1. Vérifiez que MySQL est démarré
2. Vérifiez vos paramètres dans `AppSettings.cs`
3. Testez la connexion MySQL : `mysql -u root -p`
### Erreur "Cannot find project"
```bash
cd /Users/dayronvanleemput/Documents/Coding/TravelMateAdmin
dotnet restore
```
### Erreur de build
```bash
dotnet clean
dotnet restore
dotnet build
```
---
## 📚 Prochaines Étapes
1. **Tester l'application** : Naviguez entre Dashboard, Messages et Support
2. **Changer un statut** : Cliquez sur un bouton "Marquer comme fait"
3. **Filtrer** : Utilisez le menu déroulant pour filtrer les demandes
4. **Personnaliser** : Changez les couleurs dans les fichiers XAML
5. **Ajouter des données** : Ajoutez vos propres demandes dans la base
## 🎨 Captures d'Écran des Fonctionnalités
### Dashboard
- Vue d'ensemble des statistiques
- Cartes cliquables pour accéder aux détails
- Statut de connexion en temps réel
### Messages
- Liste complète des messages
- Filtre : Tout / À faire / Fait
- Action : Marquer comme fait/en attente
### Support
- Liste des demandes d'assistance
- Affichage des emails (compte et contact)
- Même système de filtres et actions
---
**Besoin d'aide ?** Consultez le [README.md](README.md) complet ou le guide de [CONFIGURATION.md](CONFIGURATION.md)

View File

@@ -1,433 +0,0 @@
# 📊 SQL Queries Reference - TravelMate Admin
Requêtes SQL utiles pour gérer et interroger la base de données.
## 🔍 Requêtes de Consultation
### Messages
```sql
-- Tous les messages
SELECT * FROM messages ORDER BY created_at DESC;
-- Messages en attente uniquement
SELECT * FROM messages WHERE done = FALSE ORDER BY created_at DESC;
-- Messages traités uniquement
SELECT * FROM messages WHERE done = TRUE ORDER BY created_at DESC;
-- Compter les messages par statut
SELECT
COUNT(*) AS total,
SUM(CASE WHEN done = FALSE THEN 1 ELSE 0 END) AS en_attente,
SUM(CASE WHEN done = TRUE THEN 1 ELSE 0 END) AS traites
FROM messages;
-- Messages récents (dernières 24h)
SELECT * FROM messages
WHERE created_at > NOW() - INTERVAL 24 HOUR
ORDER BY created_at DESC;
-- Messages d'un utilisateur spécifique
SELECT * FROM messages
WHERE email = 'jean.dupont@example.com'
ORDER BY created_at DESC;
-- Recherche dans les messages
SELECT * FROM messages
WHERE message LIKE '%RGPD%'
OR nom LIKE '%Dupont%'
ORDER BY created_at DESC;
```
### Support Requests
```sql
-- Toutes les demandes support
SELECT * FROM support_requests ORDER BY created_at DESC;
-- Demandes en attente
SELECT * FROM support_requests WHERE done = FALSE ORDER BY created_at DESC;
-- Demandes traitées
SELECT * FROM support_requests WHERE done = TRUE ORDER BY created_at DESC;
-- Compter par statut
SELECT
COUNT(*) AS total,
SUM(CASE WHEN done = FALSE THEN 1 ELSE 0 END) AS en_attente,
SUM(CASE WHEN done = TRUE THEN 1 ELSE 0 END) AS traites
FROM support_requests;
-- Demandes d'un compte spécifique
SELECT * FROM support_requests
WHERE account_email = 'lucas.petit@example.com'
ORDER BY created_at DESC;
-- Recherche par email de contact
SELECT * FROM support_requests
WHERE contact_email = 'lucas.contact@example.com'
ORDER BY created_at DESC;
```
### Statistiques Globales
```sql
-- Vue d'ensemble complète
SELECT
'Messages' AS type,
COUNT(*) AS total,
SUM(CASE WHEN done = FALSE THEN 1 ELSE 0 END) AS en_attente,
SUM(CASE WHEN done = TRUE THEN 1 ELSE 0 END) AS traites
FROM messages
UNION ALL
SELECT
'Support',
COUNT(*),
SUM(CASE WHEN done = FALSE THEN 1 ELSE 0 END),
SUM(CASE WHEN done = TRUE THEN 1 ELSE 0 END)
FROM support_requests;
-- Activité par jour (7 derniers jours)
SELECT
DATE(created_at) AS date,
COUNT(*) AS messages
FROM messages
WHERE created_at > NOW() - INTERVAL 7 DAY
GROUP BY DATE(created_at)
ORDER BY date DESC;
-- Volume par heure de la journée
SELECT
HOUR(created_at) AS heure,
COUNT(*) AS nombre_messages
FROM messages
GROUP BY HOUR(created_at)
ORDER BY heure;
```
## ✏️ Requêtes de Modification
### Changer le Statut
```sql
-- Marquer un message comme traité
UPDATE messages SET done = TRUE WHERE id = 1;
-- Marquer une demande support comme traitée
UPDATE support_requests SET done = TRUE WHERE id = 1;
-- Marquer comme non traité
UPDATE messages SET done = FALSE WHERE id = 1;
-- Marquer tous les messages en attente
UPDATE messages SET done = FALSE;
-- Marquer tous comme traités
UPDATE messages SET done = TRUE;
-- Marquer les vieux messages comme traités (plus de 30 jours)
UPDATE messages
SET done = TRUE
WHERE created_at < NOW() - INTERVAL 30 DAY AND done = FALSE;
```
### Ajouter des Données
```sql
-- Nouveau message
INSERT INTO messages (nom, prenom, email, message, done, created_at)
VALUES (
'Nouveau',
'Test',
'test@example.com',
'Ceci est un nouveau message de test',
FALSE,
NOW()
);
-- Nouvelle demande support
INSERT INTO support_requests (nom, prenom, account_email, contact_email, message, done, created_at)
VALUES (
'Support',
'Test',
'account@example.com',
'contact@example.com',
'Problème de connexion',
FALSE,
NOW()
);
-- Ajouter plusieurs messages en une fois
INSERT INTO messages (nom, prenom, email, message, done, created_at) VALUES
('User1', 'Test', 'user1@test.com', 'Message 1', FALSE, NOW()),
('User2', 'Test', 'user2@test.com', 'Message 2', FALSE, NOW()),
('User3', 'Test', 'user3@test.com', 'Message 3', FALSE, NOW());
```
### Supprimer des Données
```sql
-- Supprimer un message spécifique
DELETE FROM messages WHERE id = 1;
-- Supprimer tous les messages traités
DELETE FROM messages WHERE done = TRUE;
-- Supprimer les vieux messages (plus de 90 jours)
DELETE FROM messages WHERE created_at < NOW() - INTERVAL 90 DAY;
-- Attention : Supprimer TOUTES les données
-- DELETE FROM messages;
-- DELETE FROM support_requests;
```
## 🔧 Maintenance
### Optimisation
```sql
-- Analyser les tables
ANALYZE TABLE messages;
ANALYZE TABLE support_requests;
-- Optimiser les tables
OPTIMIZE TABLE messages;
OPTIMIZE TABLE support_requests;
-- Vérifier l'état de la table
CHECK TABLE messages;
CHECK TABLE support_requests;
-- Réparer une table (si nécessaire)
REPAIR TABLE messages;
```
### Index
```sql
-- Voir les index existants
SHOW INDEX FROM messages;
SHOW INDEX FROM support_requests;
-- Créer un index sur l'email (si performance lente)
CREATE INDEX idx_messages_email ON messages(email);
CREATE INDEX idx_support_account_email ON support_requests(account_email);
-- Supprimer un index
DROP INDEX idx_messages_email ON messages;
```
### Backup
```sql
-- Exporter les données en SQL (en ligne de commande)
-- mysqldump -u root -p travelmateadmin > backup.sql
-- Exporter uniquement les messages
-- mysqldump -u root -p travelmateadmin messages > messages_backup.sql
-- Exporter sans données (structure seulement)
-- mysqldump -u root -p --no-data travelmateadmin > structure.sql
```
## 📊 Rapports et Analytics
### Analyse des Messages
```sql
-- Messages les plus fréquents par email
SELECT
email,
COUNT(*) AS nombre_messages,
MAX(created_at) AS dernier_message
FROM messages
GROUP BY email
ORDER BY nombre_messages DESC
LIMIT 10;
-- Temps moyen de traitement
SELECT
AVG(TIMESTAMPDIFF(HOUR, created_at, NOW())) AS heures_moyennes
FROM messages
WHERE done = TRUE;
-- Messages par mois
SELECT
DATE_FORMAT(created_at, '%Y-%m') AS mois,
COUNT(*) AS nombre
FROM messages
GROUP BY DATE_FORMAT(created_at, '%Y-%m')
ORDER BY mois DESC;
-- Taux de complétion
SELECT
ROUND(SUM(done) / COUNT(*) * 100, 2) AS taux_completion_pourcent
FROM messages;
```
### Analyse du Support
```sql
-- Problèmes les plus fréquents (par mots-clés)
SELECT
CASE
WHEN message LIKE '%connexion%' THEN 'Connexion'
WHEN message LIKE '%mot de passe%' THEN 'Mot de passe'
WHEN message LIKE '%synchronisation%' THEN 'Synchronisation'
WHEN message LIKE '%facturation%' THEN 'Facturation'
ELSE 'Autre'
END AS categorie,
COUNT(*) AS nombre
FROM support_requests
GROUP BY categorie
ORDER BY nombre DESC;
-- Utilisateurs avec plusieurs demandes
SELECT
account_email,
COUNT(*) AS nombre_demandes,
SUM(done) AS traitees,
COUNT(*) - SUM(done) AS en_attente
FROM support_requests
GROUP BY account_email
HAVING nombre_demandes > 1
ORDER BY nombre_demandes DESC;
```
## 🧪 Tests et Développement
### Générer des Données de Test
```sql
-- Générer 50 messages aléatoires
INSERT INTO messages (nom, prenom, email, message, done, created_at)
SELECT
CONCAT('Nom', n.n),
CONCAT('Prenom', n.n),
CONCAT('test', n.n, '@example.com'),
CONCAT('Message de test numéro ', n.n),
n.n % 3 = 0, -- Un tiers sera "done"
NOW() - INTERVAL FLOOR(RAND() * 30) DAY
FROM (
SELECT @row := @row + 1 AS n
FROM (SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) t1,
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) t2,
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) t3,
(SELECT 0 UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3) t4,
(SELECT @row := 0) r
LIMIT 50
) n;
```
### Réinitialiser pour les Tests
```sql
-- Vider toutes les tables
TRUNCATE TABLE messages;
TRUNCATE TABLE support_requests;
-- Réinitialiser les auto-increment
ALTER TABLE messages AUTO_INCREMENT = 1;
ALTER TABLE support_requests AUTO_INCREMENT = 1;
-- Recréer les données de test
SOURCE database_setup.sql;
```
## 🔐 Sécurité et Utilisateurs
### Gestion des Utilisateurs
```sql
-- Créer un utilisateur pour l'application
CREATE USER 'travelmateapp'@'localhost' IDENTIFIED BY 'votre_mot_de_passe';
-- Donner les permissions nécessaires
GRANT SELECT, INSERT, UPDATE ON travelmateadmin.* TO 'travelmateapp'@'localhost';
-- Ne PAS donner DELETE en production pour la sécurité
-- GRANT DELETE ON travelmateadmin.* TO 'travelmateapp'@'localhost';
-- Appliquer les changements
FLUSH PRIVILEGES;
-- Voir les permissions d'un utilisateur
SHOW GRANTS FOR 'travelmateapp'@'localhost';
-- Révoquer une permission
REVOKE DELETE ON travelmateadmin.* FROM 'travelmateapp'@'localhost';
-- Supprimer un utilisateur
DROP USER 'travelmateapp'@'localhost';
```
## 📝 Informations sur la Base
```sql
-- Voir toutes les bases de données
SHOW DATABASES;
-- Utiliser la base TravelMate
USE travelmateadmin;
-- Voir toutes les tables
SHOW TABLES;
-- Voir la structure d'une table
DESCRIBE messages;
DESCRIBE support_requests;
-- Voir le CREATE TABLE original
SHOW CREATE TABLE messages;
-- Taille de la base de données
SELECT
table_schema AS 'Database',
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Size (MB)'
FROM information_schema.tables
WHERE table_schema = 'travelmateadmin';
-- Nombre de lignes par table
SELECT
TABLE_NAME,
TABLE_ROWS
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'travelmateadmin';
```
## 🚨 Dépannage
```sql
-- Vérifier les connexions actives
SHOW PROCESSLIST;
-- Tuer une connexion bloquée (remplacer X par l'ID)
-- KILL X;
-- Voir les variables MySQL
SHOW VARIABLES LIKE 'max_connections';
SHOW VARIABLES LIKE 'wait_timeout';
-- Voir le statut du serveur
SHOW STATUS;
-- Voir les erreurs récentes
SHOW WARNINGS;
SHOW ERRORS;
```
---
## 💡 Tips
- Toujours tester vos requêtes DELETE/UPDATE avec SELECT d'abord
- Faites des backups avant toute modification importante
- Utilisez LIMIT dans vos requêtes de test
- Les index améliorent les performances SELECT mais ralentissent INSERT/UPDATE
- Utilisez EXPLAIN pour analyser les performances des requêtes
```sql
-- Exemple d'analyse de performance
EXPLAIN SELECT * FROM messages WHERE done = FALSE ORDER BY created_at DESC;
```

View File

@@ -18,27 +18,22 @@
</ResourceDictionary> </ResourceDictionary>
</Shell.Resources> </Shell.Resources>
<!-- Dashboard --> <FlyoutItem Title="Dashboard" Icon="home">
<TabBar>
<ShellContent <ShellContent
Title="Dashboard"
Icon="home"
ContentTemplate="{DataTemplate views:DashboardPage}" ContentTemplate="{DataTemplate views:DashboardPage}"
Route="DashboardPage" /> Route="DashboardPage" />
</FlyoutItem>
<!-- Messages --> <FlyoutItem Title="Messages" Icon="mail">
<ShellContent <ShellContent
Title="Messages"
Icon="mail"
ContentTemplate="{DataTemplate views:MessagesPage}" ContentTemplate="{DataTemplate views:MessagesPage}"
Route="MessagesPage" /> Route="MessagesPage" />
</FlyoutItem>
<!-- Support --> <FlyoutItem Title="Support" Icon="help">
<ShellContent <ShellContent
Title="Support"
Icon="help"
ContentTemplate="{DataTemplate views:SupportPage}" ContentTemplate="{DataTemplate views:SupportPage}"
Route="SupportPage" /> Route="SupportPage" />
</TabBar> </FlyoutItem>
</Shell> </Shell>

View File

@@ -1,17 +1,65 @@
using System.Text.Json;
namespace TravelMateAdmin.Configuration; namespace TravelMateAdmin.Configuration;
public class DatabaseConfig
{
public string Host { get; set; } = "localhost";
public string Port { get; set; } = "3306";
public string Name { get; set; } = "travelmateadmin";
public string User { get; set; } = "root";
public string Password { get; set; } = "";
}
public class AppConfig
{
public DatabaseConfig Database { get; set; } = new();
}
public static class AppSettings public static class AppSettings
{ {
// Configuration de la base de données private static AppConfig? _config;
// Modifiez ces valeurs selon votre environnement
public const string Server = "localhost"; static AppSettings()
public const string Port = "3306"; {
public const string Database = "travelmateadmin"; LoadConfiguration();
public const string User = "root"; }
public const string Password = "yourpassword";
private static void LoadConfiguration()
{
try
{
System.Diagnostics.Debug.WriteLine($"=== CHARGEMENT CONFIG ===");
using var stream = FileSystem.OpenAppPackageFileAsync("appsettings.json").Result;
using var reader = new StreamReader(stream);
var json = reader.ReadToEnd();
_config = JsonSerializer.Deserialize<AppConfig>(json);
System.Diagnostics.Debug.WriteLine("✓ Configuration chargée depuis appsettings.json");
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine($"❌ Erreur chargement config: {ex.Message}");
_config = new AppConfig();
}
}
public static string Server => _config?.Database.Host ?? "localhost";
public static string Port => _config?.Database.Port ?? "3306";
public static string Database => _config?.Database.Name ?? "travelmateadmin";
public static string User => _config?.Database.User ?? "root";
public static string Password => _config?.Database.Password ?? "";
public static string GetConnectionString() public static string GetConnectionString()
{ {
return $"Server={Server};Port={Port};Database={Database};User={User};Password={Password};"; var connString = $"Server={Server};Port={Port};Database={Database};User={User};Password={Password};";
System.Diagnostics.Debug.WriteLine("=== CONNECTION STRING ===");
System.Diagnostics.Debug.WriteLine($"Server: {Server}");
System.Diagnostics.Debug.WriteLine($"Port: {Port}");
System.Diagnostics.Debug.WriteLine($"Database: {Database}");
System.Diagnostics.Debug.WriteLine($"User: {User}");
System.Diagnostics.Debug.WriteLine($"Password: {(string.IsNullOrEmpty(Password) ? "VIDE" : "***défini***")}");
return connString;
} }
} }

View File

@@ -35,3 +35,16 @@ public class BoolToColorConverter : IValueConverter
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
public class StringNotEmptyConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return value is string str && !string.IsNullOrWhiteSpace(str);
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View File

@@ -1,16 +1,26 @@
using CommunityToolkit.Mvvm.ComponentModel;
namespace TravelMateAdmin.Models; namespace TravelMateAdmin.Models;
public class Message public partial class Message : ObservableObject
{ {
public int Id { get; set; } public int Id { get; set; }
public string Nom { get; set; } = string.Empty; public string Nom { get; set; } = string.Empty;
public string Prenom { get; set; } = string.Empty; public string Prenom { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty; public string Email { get; set; } = string.Empty;
public string MessageText { get; set; } = string.Empty; public string MessageText { get; set; } = string.Empty;
public bool Done { get; set; }
[ObservableProperty]
private bool done;
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
public string FullName => $"{Prenom} {Nom}"; public string FullName => $"{Prenom} {Nom}";
public string StatusText => Done ? "Traité" : "En attente"; public string StatusText => Done ? "Traité" : "En attente";
public string CreatedAtFormatted => CreatedAt.ToString("dd/MM/yyyy HH:mm"); public string CreatedAtFormatted => CreatedAt.ToString("dd/MM/yyyy HH:mm");
partial void OnDoneChanged(bool value)
{
OnPropertyChanged(nameof(StatusText));
}
} }

View File

@@ -1,6 +1,8 @@
using CommunityToolkit.Mvvm.ComponentModel;
namespace TravelMateAdmin.Models; namespace TravelMateAdmin.Models;
public class SupportRequest public partial class SupportRequest : ObservableObject
{ {
public int Id { get; set; } public int Id { get; set; }
public string Nom { get; set; } = string.Empty; public string Nom { get; set; } = string.Empty;
@@ -8,10 +10,18 @@ public class SupportRequest
public string AccountEmail { get; set; } = string.Empty; public string AccountEmail { get; set; } = string.Empty;
public string ContactEmail { get; set; } = string.Empty; public string ContactEmail { get; set; } = string.Empty;
public string MessageText { get; set; } = string.Empty; public string MessageText { get; set; } = string.Empty;
public bool Done { get; set; }
[ObservableProperty]
private bool done;
public DateTime CreatedAt { get; set; } public DateTime CreatedAt { get; set; }
public string FullName => $"{Prenom} {Nom}"; public string FullName => $"{Prenom} {Nom}";
public string StatusText => Done ? "Traité" : "En attente"; public string StatusText => Done ? "Traité" : "En attente";
public string CreatedAtFormatted => CreatedAt.ToString("dd/MM/yyyy HH:mm"); public string CreatedAtFormatted => CreatedAt.ToString("dd/MM/yyyy HH:mm");
partial void OnDoneChanged(bool value)
{
OnPropertyChanged(nameof(StatusText));
}
} }

View File

@@ -7,6 +7,7 @@ namespace TravelMateAdmin.Services;
public class DatabaseService : IDatabaseService public class DatabaseService : IDatabaseService
{ {
private readonly string _connectionString; private readonly string _connectionString;
public string LastError { get; private set; } = string.Empty;
public DatabaseService() public DatabaseService()
{ {
@@ -25,12 +26,26 @@ public class DatabaseService : IDatabaseService
{ {
try try
{ {
System.Diagnostics.Debug.WriteLine("=== TEST CONNEXION DB ===");
System.Diagnostics.Debug.WriteLine($"Connection String complet: {_connectionString}");
using var connection = new MySqlConnection(_connectionString); using var connection = new MySqlConnection(_connectionString);
await connection.OpenAsync(); await connection.OpenAsync();
System.Diagnostics.Debug.WriteLine("✓ Connexion réussie !");
LastError = string.Empty;
return true; return true;
} }
catch catch (Exception ex)
{ {
LastError = $"{ex.Message}\n\nConnection: {_connectionString}";
System.Diagnostics.Debug.WriteLine($"❌ Erreur de connexion: {ex.Message}");
System.Diagnostics.Debug.WriteLine($"Connection String: {_connectionString}");
System.Diagnostics.Debug.WriteLine($"Type: {ex.GetType().Name}");
if (ex.InnerException != null)
{
System.Diagnostics.Debug.WriteLine($"Inner Exception: {ex.InnerException.Message}");
}
return false; return false;
} }
} }
@@ -48,7 +63,7 @@ public class DatabaseService : IDatabaseService
using var connection = new MySqlConnection(_connectionString); using var connection = new MySqlConnection(_connectionString);
await connection.OpenAsync(); await connection.OpenAsync();
var query = "SELECT id, nom, prenom, email, message, done, created_at FROM messages ORDER BY created_at DESC"; var query = "SELECT id, nom, prenom, email, message, done, date_envoi FROM messages ORDER BY date_envoi DESC";
using var command = new MySqlCommand(query, connection); using var command = new MySqlCommand(query, connection);
using var reader = await command.ExecuteReaderAsync(); using var reader = await command.ExecuteReaderAsync();
@@ -62,7 +77,7 @@ public class DatabaseService : IDatabaseService
Email = reader.GetString("email"), Email = reader.GetString("email"),
MessageText = reader.GetString("message"), MessageText = reader.GetString("message"),
Done = reader.GetBoolean("done"), Done = reader.GetBoolean("done"),
CreatedAt = reader.GetDateTime("created_at") CreatedAt = reader.GetDateTime("date_envoi")
}); });
} }
} }
@@ -83,10 +98,15 @@ public class DatabaseService : IDatabaseService
try try
{ {
System.Diagnostics.Debug.WriteLine($"=== GetMessagesFilteredAsync ===");
System.Diagnostics.Debug.WriteLine($"isDone: {isDone}");
using var connection = new MySqlConnection(_connectionString); using var connection = new MySqlConnection(_connectionString);
await connection.OpenAsync(); await connection.OpenAsync();
var query = "SELECT id, nom, prenom, email, message, done, created_at FROM messages WHERE done = @done ORDER BY created_at DESC"; var query = "SELECT id, nom, prenom, email, message, done, date_envoi FROM messages WHERE done = @done ORDER BY date_envoi DESC";
System.Diagnostics.Debug.WriteLine($"Query: {query}");
using var command = new MySqlCommand(query, connection); using var command = new MySqlCommand(query, connection);
command.Parameters.AddWithValue("@done", isDone.Value); command.Parameters.AddWithValue("@done", isDone.Value);
using var reader = await command.ExecuteReaderAsync(); using var reader = await command.ExecuteReaderAsync();
@@ -101,9 +121,11 @@ public class DatabaseService : IDatabaseService
Email = reader.GetString("email"), Email = reader.GetString("email"),
MessageText = reader.GetString("message"), MessageText = reader.GetString("message"),
Done = reader.GetBoolean("done"), Done = reader.GetBoolean("done"),
CreatedAt = reader.GetDateTime("created_at") CreatedAt = reader.GetDateTime("date_envoi")
}); });
} }
System.Diagnostics.Debug.WriteLine($"Messages trouvés: {messages.Count}");
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -54,6 +54,7 @@
<!-- Raw Assets (also remove the "Resources\Raw" prefix) --> <!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" /> <MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
<MauiAsset Include="appsettings.json" LogicalName="appsettings.json" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -61,6 +62,7 @@
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.0" /> <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.0" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" /> <PackageReference Include="CommunityToolkit.Mvvm" Version="8.3.2" />
<PackageReference Include="MySqlConnector" Version="2.4.0" /> <PackageReference Include="MySqlConnector" Version="2.4.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="10.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -26,6 +26,9 @@ public partial class DashboardViewModel : ObservableObject
[ObservableProperty] [ObservableProperty]
private string connectionStatus = "Non connecté"; private string connectionStatus = "Non connecté";
[ObservableProperty]
private string connectionError = string.Empty;
public DashboardViewModel(IDatabaseService databaseService) public DashboardViewModel(IDatabaseService databaseService)
{ {
_databaseService = databaseService; _databaseService = databaseService;
@@ -35,26 +38,39 @@ public partial class DashboardViewModel : ObservableObject
public async Task LoadDashboardAsync() public async Task LoadDashboardAsync()
{ {
IsLoading = true; IsLoading = true;
ConnectionError = string.Empty;
try try
{ {
// Test connection // Test connection
var isConnected = await _databaseService.TestConnectionAsync(); var isConnected = await _databaseService.TestConnectionAsync();
ConnectionStatus = isConnected ? "✓ Connecté" : "✗ Déconnecté";
if (isConnected) if (isConnected)
{ {
ConnectionStatus = "✓ Connecté";
// Load stats // Load stats
MessagesPending = await _databaseService.GetMessagesPendingCountAsync(); MessagesPending = await _databaseService.GetMessagesPendingCountAsync();
MessagesDone = await _databaseService.GetMessagesDoneCountAsync(); MessagesDone = await _databaseService.GetMessagesDoneCountAsync();
SupportRequestsPending = await _databaseService.GetSupportRequestsPendingCountAsync(); SupportRequestsPending = await _databaseService.GetSupportRequestsPendingCountAsync();
SupportRequestsDone = await _databaseService.GetSupportRequestsDoneCountAsync(); SupportRequestsDone = await _databaseService.GetSupportRequestsDoneCountAsync();
} }
else
{
ConnectionStatus = "✗ Déconnecté";
// Afficher l'erreur si disponible
var dbService = _databaseService as DatabaseService;
if (dbService != null && !string.IsNullOrEmpty(dbService.LastError))
{
ConnectionError = dbService.LastError;
System.Diagnostics.Debug.WriteLine($"Erreur DB: {dbService.LastError}");
}
}
} }
catch (Exception ex) catch (Exception ex)
{ {
System.Diagnostics.Debug.WriteLine($"Error loading dashboard: {ex.Message}"); System.Diagnostics.Debug.WriteLine($"Error loading dashboard: {ex.Message}");
ConnectionStatus = "✗ Erreur de connexion"; ConnectionStatus = "✗ Erreur de connexion";
ConnectionError = ex.Message;
} }
finally finally
{ {

View File

@@ -33,6 +33,9 @@ public partial class MessagesViewModel : ObservableObject
try try
{ {
System.Diagnostics.Debug.WriteLine($"=== CHARGEMENT MESSAGES ===");
System.Diagnostics.Debug.WriteLine($"Filtre sélectionné: {SelectedFilter}");
bool? isDone = SelectedFilter switch bool? isDone = SelectedFilter switch
{ {
"À faire" => false, "À faire" => false,
@@ -40,16 +43,22 @@ public partial class MessagesViewModel : ObservableObject
_ => null _ => null
}; };
System.Diagnostics.Debug.WriteLine($"isDone filter: {isDone}");
var messagesList = await _databaseService.GetMessagesFilteredAsync(isDone); var messagesList = await _databaseService.GetMessagesFilteredAsync(isDone);
System.Diagnostics.Debug.WriteLine($"Messages récupérés: {messagesList.Count}");
Messages.Clear(); Messages.Clear();
foreach (var message in messagesList) foreach (var message in messagesList)
{ {
System.Diagnostics.Debug.WriteLine($"Message: {message.FullName} - {message.Email}");
Messages.Add(message); Messages.Add(message);
} }
System.Diagnostics.Debug.WriteLine($"Total messages affichés: {Messages.Count}");
} }
catch (Exception ex) catch (Exception ex)
{ {
System.Diagnostics.Debug.WriteLine($"Error loading messages: {ex.Message}"); System.Diagnostics.Debug.WriteLine($"Error loading messages: {ex.Message}");
System.Diagnostics.Debug.WriteLine($"Stack trace: {ex.StackTrace}");
} }
finally finally
{ {
@@ -57,6 +66,12 @@ public partial class MessagesViewModel : ObservableObject
} }
} }
[RelayCommand]
private async Task GoBackAsync()
{
await Shell.Current.GoToAsync("..");
}
[RelayCommand] [RelayCommand]
private async Task ToggleMessageStatusAsync(Message message) private async Task ToggleMessageStatusAsync(Message message)
{ {
@@ -66,7 +81,6 @@ public partial class MessagesViewModel : ObservableObject
if (success) if (success)
{ {
message.Done = !message.Done; message.Done = !message.Done;
OnPropertyChanged(nameof(Messages));
} }
} }

View File

@@ -33,6 +33,9 @@ public partial class SupportViewModel : ObservableObject
try try
{ {
System.Diagnostics.Debug.WriteLine($"=== CHARGEMENT SUPPORT ===");
System.Diagnostics.Debug.WriteLine($"Filtre sélectionné: {SelectedFilter}");
bool? isDone = SelectedFilter switch bool? isDone = SelectedFilter switch
{ {
"À faire" => false, "À faire" => false,
@@ -40,16 +43,22 @@ public partial class SupportViewModel : ObservableObject
_ => null _ => null
}; };
System.Diagnostics.Debug.WriteLine($"isDone filter: {isDone}");
var requestsList = await _databaseService.GetSupportRequestsFilteredAsync(isDone); var requestsList = await _databaseService.GetSupportRequestsFilteredAsync(isDone);
System.Diagnostics.Debug.WriteLine($"Support requests récupérés: {requestsList.Count}");
SupportRequests.Clear(); SupportRequests.Clear();
foreach (var request in requestsList) foreach (var request in requestsList)
{ {
System.Diagnostics.Debug.WriteLine($"Support: {request.FullName} - {request.AccountEmail}");
SupportRequests.Add(request); SupportRequests.Add(request);
} }
System.Diagnostics.Debug.WriteLine($"Total support affichés: {SupportRequests.Count}");
} }
catch (Exception ex) catch (Exception ex)
{ {
System.Diagnostics.Debug.WriteLine($"Error loading support requests: {ex.Message}"); System.Diagnostics.Debug.WriteLine($"Error loading support requests: {ex.Message}");
System.Diagnostics.Debug.WriteLine($"Stack trace: {ex.StackTrace}");
} }
finally finally
{ {
@@ -57,6 +66,12 @@ public partial class SupportViewModel : ObservableObject
} }
} }
[RelayCommand]
private async Task GoBackAsync()
{
await Shell.Current.GoToAsync("..");
}
[RelayCommand] [RelayCommand]
private async Task ToggleSupportRequestStatusAsync(SupportRequest request) private async Task ToggleSupportRequestStatusAsync(SupportRequest request)
{ {
@@ -66,7 +81,6 @@ public partial class SupportViewModel : ObservableObject
if (success) if (success)
{ {
request.Done = !request.Done; request.Done = !request.Done;
OnPropertyChanged(nameof(SupportRequests));
} }
} }

View File

@@ -2,6 +2,7 @@
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:TravelMateAdmin.ViewModels" xmlns:vm="clr-namespace:TravelMateAdmin.ViewModels"
xmlns:converters="clr-namespace:TravelMateAdmin.Converters"
x:Class="TravelMateAdmin.Views.DashboardPage" x:Class="TravelMateAdmin.Views.DashboardPage"
x:DataType="vm:DashboardViewModel" x:DataType="vm:DashboardViewModel"
Title="Tableau de Bord" Title="Tableau de Bord"
@@ -16,6 +17,8 @@
<Color x:Key="TextSecondary">#B0B0B0</Color> <Color x:Key="TextSecondary">#B0B0B0</Color>
<Color x:Key="Success">#4CAF50</Color> <Color x:Key="Success">#4CAF50</Color>
<Color x:Key="Warning">#FFA726</Color> <Color x:Key="Warning">#FFA726</Color>
<converters:StringNotEmptyConverter x:Key="StringNotEmptyConverter"/>
</ResourceDictionary> </ResourceDictionary>
</ContentPage.Resources> </ContentPage.Resources>
@@ -45,6 +48,29 @@
</Grid> </Grid>
</Frame> </Frame>
<!-- Erreur de Connexion -->
<Frame BackgroundColor="#8B0000"
CornerRadius="10"
Padding="15"
HasShadow="True"
IsVisible="{Binding ConnectionError, Converter={StaticResource StringNotEmptyConverter}}">
<VerticalStackLayout Spacing="5">
<Label Text="❌ Erreur de Connexion"
FontSize="16"
FontAttributes="Bold"
TextColor="White"/>
<Label Text="{Binding ConnectionError}"
FontSize="12"
TextColor="White"
LineBreakMode="WordWrap"/>
<Label Text="💡 Vérifiez vos identifiants MySQL et les permissions d'accès"
FontSize="11"
TextColor="#FFB6C1"
LineBreakMode="WordWrap"
Margin="0,5,0,0"/>
</VerticalStackLayout>
</Frame>
<!-- Loading Indicator --> <!-- Loading Indicator -->
<ActivityIndicator IsRunning="{Binding IsLoading}" <ActivityIndicator IsRunning="{Binding IsLoading}"
IsVisible="{Binding IsLoading}" IsVisible="{Binding IsLoading}"

View File

@@ -1,52 +0,0 @@
-- Script SQL pour créer la base de données TravelMate Admin
-- À exécuter dans MySQL/MariaDB
-- Créer la base de données
CREATE DATABASE IF NOT EXISTS travelmateadmin CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE travelmateadmin;
-- Table des messages
CREATE TABLE IF NOT EXISTS messages (
id INT AUTO_INCREMENT PRIMARY KEY,
nom VARCHAR(100) NOT NULL,
prenom VARCHAR(100) NOT NULL,
email VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
done BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_done (done),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Table des demandes support
CREATE TABLE IF NOT EXISTS support_requests (
id INT AUTO_INCREMENT PRIMARY KEY,
nom VARCHAR(100) NOT NULL,
prenom VARCHAR(100) NOT NULL,
account_email VARCHAR(255) NOT NULL,
contact_email VARCHAR(255) NOT NULL,
message TEXT NOT NULL,
done BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
INDEX idx_done (done),
INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- Données de test pour messages
INSERT INTO messages (nom, prenom, email, message, done, created_at) VALUES
('Dupont', 'Jean', 'jean.dupont@example.com', 'Je souhaite effacer toutes mes données personnelles conformément au RGPD.', FALSE, NOW() - INTERVAL 2 DAY),
('Martin', 'Sophie', 'sophie.martin@example.com', 'Pouvez-vous supprimer mon compte et toutes les informations associées ?', FALSE, NOW() - INTERVAL 1 DAY),
('Bernard', 'Pierre', 'pierre.bernard@example.com', 'Demande de suppression de données RGPD', TRUE, NOW() - INTERVAL 5 DAY),
('Dubois', 'Marie', 'marie.dubois@example.com', 'Bonjour, je voudrais avoir des informations sur vos services.', FALSE, NOW() - INTERVAL 3 HOUR);
-- Données de test pour support_requests
INSERT INTO support_requests (nom, prenom, account_email, contact_email, message, done, created_at) VALUES
('Petit', 'Lucas', 'lucas.petit@example.com', 'lucas.contact@example.com', 'Je n''arrive pas à me connecter à mon compte depuis hier.', FALSE, NOW() - INTERVAL 1 DAY),
('Roux', 'Emma', 'emma.roux@example.com', 'emma.pro@example.com', 'Mon mot de passe ne fonctionne plus, pouvez-vous m''aider ?', FALSE, NOW() - INTERVAL 6 HOUR),
('Moreau', 'Thomas', 'thomas.moreau@example.com', 'thomas.m@example.com', 'Problème de synchronisation des données', TRUE, NOW() - INTERVAL 4 DAY),
('Simon', 'Julie', 'julie.simon@example.com', 'julie.s@example.com', 'Question sur la facturation de mon abonnement', FALSE, NOW() - INTERVAL 2 HOUR);
-- Afficher un résumé
SELECT 'Messages créés:' AS info, COUNT(*) AS count FROM messages
UNION ALL
SELECT 'Support créés:', COUNT(*) FROM support_requests;