Feature Onboarding - Guide complet
Vue d'ensemble
Le feature Onboarding collecte les informations essentielles de l'utilisateur à la première connexion, notamment :
- Le type de métier / activité artisanale
- Le nom de son business (optionnel)
Ces informations permettent de personnaliser l'expérience utilisateur dans toute l'application.
Fonctionnalités
Flow d'onboarding en 3 étapes
- Welcome Screen : Présentation de l'app et ses fonctionnalités principales
- Business Type Selection : Sélection du type de métier parmi 16 catégories
- Business Name : Nom du business (optionnel)
Personnalisation selon le métier
Le BusinessType enum permet d'adapter :
- Terminologie : "Rendez-vous" pour coiffeur, "Réservation" pour pâtissier, "Séance" pour photographe
- Icônes : Emoji approprié pour chaque métier
- Templates : Messages et suggestions adaptés au métier
Architecture
Structure des dossiers
lib/features/onboarding/
├── domain/
│ └── entities/
│ └── business_type.dart # Enum BusinessType avec 16 métiers
├── presentation/
│ └── pages/
│ └── onboarding_flow_page.dart # Flow complet d'onboarding
├── ONBOARDING_DATABASE.md # Documentation SQL
└── README.md # Ce fichier
Entités principales
BusinessType (Enum)
enum BusinessType {
patisserie, boulangerie, traiteur, chocolaterie,
ongles, coiffure, esthetique, massage, barbier,
couture, fleuriste, photographe, maquilleuse,
tatoueur, bijouterie, autre
}
Propriétés importantes :
value: Valeur stockée en base de donnéeslabel: Libellé affiché à l'utilisateuremoji: Emoji représentant le métierdescription: Description du métierorderTermSingular: Terme approprié au singulier ("Rendez-vous", "Réservation", etc.)orderTermPlural: Terme approprié au plurielcalendarIcon: Icône pour le calendrier
Exemple d'utilisation :
final businessType = BusinessType.patisserie;
print(businessType.orderTermSingular); // "Réservation"
final coiffeur = BusinessType.coiffure;
print(coiffeur.orderTermSingular); // "Rendez-vous"
Modification du UserProfile
Trois nouveaux champs ont été ajoutés à l'entité UserProfile:
final String? businessType; // Type de métier
final String? businessName; // Nom du business
final bool? hasCompletedOnboarding; // Flag d'onboarding complété
Utilisation
1. Configuration de la base de données
Exécuter le SQL de migration dans Supabase (voir ONBOARDING_DATABASE.md) :
ALTER TABLE user_profiles
ADD COLUMN IF NOT EXISTS business_type TEXT,
ADD COLUMN IF NOT EXISTS business_name TEXT,
ADD COLUMN IF NOT EXISTS has_completed_onboarding BOOLEAN DEFAULT false;
2. Navigation vers l'onboarding
L'onboarding doit être affiché après l'inscription ou au premier lancement si l'utilisateur n'a pas complété l'onboarding.
// Exemple : Vérifier si l'onboarding est nécessaire
final profile = await settingsRepository.getUserProfile();
if (profile == null || profile.hasCompletedOnboarding != true) {
// Rediriger vers l'onboarding
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const OnboardingFlowPage(),
),
);
} else {
// Aller vers la page principale
Navigator.of(context).pushReplacementNamed('/main');
}
3. Intégration dans le flow d'authentification
Dans votre page d'auth / splash screen :
Future<void> _checkOnboardingStatus() async {
final user = SupabaseConfig.client.auth.currentUser;
if (user == null) {
// Utilisateur non connecté → Login
Navigator.of(context).pushReplacementNamed('/login');
return;
}
final repository = SettingsRepositoryImpl(SupabaseConfig.client);
final profile = await repository.getUserProfile();
if (profile == null || profile.hasCompletedOnboarding != true) {
// Onboarding non complété
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => const OnboardingFlowPage(),
),
);
} else {
// Onboarding complété → Page principale
Navigator.of(context).pushReplacementNamed('/main');
}
}
4. Utiliser le BusinessType dans l'app
Récupérer le type de métier :
final profile = await repository.getUserProfile();
final businessType = profile?.businessType != null
? BusinessType.fromValue(profile!.businessType!)
: null;
if (businessType != null) {
// Adapter l'interface
print('Type de rendez-vous : ${businessType.orderTermSingular}');
}
Adapter la terminologie :
// Au lieu de hard-coder "Commande"
Text('Mes commandes');
// Utiliser le terme approprié
final businessType = BusinessType.fromValue(profile.businessType!);
Text('Mes ${businessType.orderTermPlural}');
// Affichera : "Mes Rendez-vous" pour un coiffeur
// Affichera : "Mes Réservations" pour un pâtissier
5. Modifier les informations depuis les paramètres
Ajouter une option dans les paramètres pour modifier le type de métier :
_buildSettingsItem(
icon: Icons.work,
title: 'Type d\'activité',
subtitle: businessType?.label ?? 'Non défini',
onTap: () {
// Ouvrir un dialog ou une page pour changer le métier
_showBusinessTypeDialog();
},
),
Liste complète des métiers
| Métier | Emoji | Terme (singulier) | Terme (pluriel) |
|---|---|---|---|
| Pâtisserie | 🎂 | Réservation | Réservations |
| Boulangerie | 🥖 | Réservation | Réservations |
| Traiteur | 🍽️ | Réservation | Réservations |
| Chocolaterie | 🍫 | Réservation | Réservations |
| Onglerie | 💅 | Rendez-vous | Rendez-vous |
| Coiffure | 💇 | Rendez-vous | Rendez-vous |
| Esthétique | ✨ | Rendez-vous | Rendez-vous |
| Massage | 💆 | Rendez-vous | Rendez-vous |
| Barbier | 💈 | Rendez-vous | Rendez-vous |
| Couture | 🧵 | Réservation | Réservations |
| Fleuriste | 🌸 | Réservation | Réservations |
| Photographe | 📸 | Séance | Séances |
| Maquillage | 💄 | Rendez-vous | Rendez-vous |
| Tatouage | 🎨 | Rendez-vous | Rendez-vous |
| Bijouterie | 💎 | Réservation | Réservations |
| Autre | 🔧 | Réservation | Réservations |
Améliorations futures
Phase 1 (Base)
- ✅ Flow d'onboarding 3 étapes
- ✅ Sélection du type de métier
- ✅ Nom du business (optionnel)
- ✅ Stockage dans user_profile
Phase 2 (Personnalisation)
- ⬜ Adaptation automatique de la terminologie dans toute l'app
- ⬜ Templates de messages selon le métier
- ⬜ Suggestions de produits/services par défaut
- ⬜ Modifier le métier depuis les paramètres
Phase 3 (Avancé)
- ⬜ Onboarding différent selon le métier
- ⬜ Collecte d'informations spécifiques au métier
- ⬜ Recommandations personnalisées
- ⬜ Analytics par type de métier
Personnalisation de l'onboarding
Ajouter un nouveau métier
- Ajouter l'enum dans
business_type.dart:
enum BusinessType {
// ... existants
menuisier('menuisier', 'Menuiserie', '🪚', 'Créations en bois sur mesure'),
}
- Mettre à jour la contrainte SQL :
ALTER TABLE user_profiles
DROP CONSTRAINT check_business_type;
ALTER TABLE user_profiles
ADD CONSTRAINT check_business_type CHECK (
business_type IS NULL OR
business_type IN (
'patisserie', 'boulangerie', ..., 'menuisier'
)
);
Changer les étapes de l'onboarding
Modifier le PageView dans onboarding_flow_page.dart :
PageView(
controller: _pageController,
children: [
_buildWelcomePage(),
_buildBusinessTypePage(),
_buildBusinessNamePage(),
_buildNewCustomPage(), // Nouvelle étape
],
)
Tests
Tests manuels
-
Premier lancement :
- Créer un nouveau compte
- Vérifier que l'onboarding s'affiche
- Compléter les 3 étapes
- Vérifier l'arrivée sur la page principale
-
Sélection du métier :
- Sélectionner différents métiers
- Vérifier que la sélection est visuelle
- Vérifier qu'on ne peut pas continuer sans sélectionner
-
Business name :
- Laisser vide (optionnel)
- Remplir avec un nom
- Vérifier la sauvegarde dans les deux cas
-
Vérification BDD :
- Vérifier dans Supabase que les données sont bien enregistrées
- Vérifier que
has_completed_onboardingest àtrue
Tests unitaires à implémenter
- Tests pour
BusinessTypeenum - Tests pour la navigation du PageView
- Tests pour la validation du formulaire
- Tests pour la sauvegarde du profil
Troubleshooting
L'onboarding ne s'affiche pas
- Vérifier que les colonnes existent dans
user_profiles - Vérifier que
has_completed_onboardingest àfalse - Vérifier la logique de navigation après login
Le profil ne se sauvegarde pas
- Vérifier la connexion Supabase
- Vérifier les RLS policies sur
user_profiles - Vérifier que l'utilisateur est bien connecté
- Vérifier les logs d'erreur
Le BusinessType n'est pas reconnu
- Vérifier que la valeur en BDD correspond à
BusinessType.value - Vérifier la contrainte CHECK en SQL
- Utiliser
BusinessType.fromValue()pour parser
Migration des utilisateurs existants
Si vous avez déjà des utilisateurs:
-- Option 1 : Forcer tous les utilisateurs à passer par l'onboarding
UPDATE user_profiles
SET has_completed_onboarding = false;
-- Option 2 : Marquer les anciens utilisateurs comme ayant complété l'onboarding
UPDATE user_profiles
SET has_completed_onboarding = true
WHERE created_at < NOW() - INTERVAL '1 day';
Support
Pour toute question :
- Voir la documentation SQL :
ONBOARDING_DATABASE.md - Voir le code source :
lib/features/onboarding/ - Contacter l'équipe de développement