Aller au contenu principal

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

  1. Welcome Screen : Présentation de l'app et ses fonctionnalités principales
  2. Business Type Selection : Sélection du type de métier parmi 16 catégories
  3. 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ées
  • label: Libellé affiché à l'utilisateur
  • emoji: Emoji représentant le métier
  • description: Description du métier
  • orderTermSingular: Terme approprié au singulier ("Rendez-vous", "Réservation", etc.)
  • orderTermPlural: Terme approprié au pluriel
  • calendarIcon: 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étierEmojiTerme (singulier)Terme (pluriel)
Pâtisserie🎂RéservationRéservations
Boulangerie🥖RéservationRéservations
Traiteur🍽️RéservationRéservations
Chocolaterie🍫RéservationRéservations
Onglerie💅Rendez-vousRendez-vous
Coiffure💇Rendez-vousRendez-vous
EsthétiqueRendez-vousRendez-vous
Massage💆Rendez-vousRendez-vous
Barbier💈Rendez-vousRendez-vous
Couture🧵RéservationRéservations
Fleuriste🌸RéservationRéservations
Photographe📸SéanceSéances
Maquillage💄Rendez-vousRendez-vous
Tatouage🎨Rendez-vousRendez-vous
Bijouterie💎RéservationRéservations
Autre🔧RéservationRé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

  1. Ajouter l'enum dans business_type.dart :
enum BusinessType {
// ... existants
menuisier('menuisier', 'Menuiserie', '🪚', 'Créations en bois sur mesure'),
}
  1. 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

  1. 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
  2. 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
  3. Business name :

    • Laisser vide (optionnel)
    • Remplir avec un nom
    • Vérifier la sauvegarde dans les deux cas
  4. Vérification BDD :

    • Vérifier dans Supabase que les données sont bien enregistrées
    • Vérifier que has_completed_onboarding est à true

Tests unitaires à implémenter

  • Tests pour BusinessType enum
  • 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

  1. Vérifier que les colonnes existent dans user_profiles
  2. Vérifier que has_completed_onboarding est à false
  3. Vérifier la logique de navigation après login

Le profil ne se sauvegarde pas

  1. Vérifier la connexion Supabase
  2. Vérifier les RLS policies sur user_profiles
  3. Vérifier que l'utilisateur est bien connecté
  4. Vérifier les logs d'erreur

Le BusinessType n'est pas reconnu

  1. Vérifier que la valeur en BDD correspond à BusinessType.value
  2. Vérifier la contrainte CHECK en SQL
  3. 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