import 'package:flutter/material.dart'; import '../../../../shared/design_system/tokens/app_colors.dart'; import '../../../../shared/design_system/tokens/unionflow_colors.dart'; /// Header commun à toutes les étapes d'onboarding class OnboardingStepHeader extends StatelessWidget { final int step; final int total; final String title; final String subtitle; const OnboardingStepHeader({ super.key, required this.step, required this.total, required this.title, required this.subtitle, }); @override Widget build(BuildContext context) { return Container( decoration: const BoxDecoration(gradient: UnionFlowColors.primaryGradient), child: SafeArea( bottom: false, child: Padding( padding: const EdgeInsets.fromLTRB(20, 12, 20, 24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Barre de progression segmentée Row( children: List.generate(total, (i) { final done = i < step; return Expanded( child: Container( height: 4, margin: EdgeInsets.only(right: i < total - 1 ? 6 : 0), decoration: BoxDecoration( color: done ? Colors.white : Colors.white.withOpacity(0.3), borderRadius: BorderRadius.circular(2), ), ), ); }), ), const SizedBox(height: 6), Text( 'Étape $step sur $total', style: TextStyle( color: Colors.white.withOpacity(0.75), fontSize: 12, fontWeight: FontWeight.w500, ), ), const SizedBox(height: 12), Text( title, style: const TextStyle( color: Colors.white, fontSize: 22, fontWeight: FontWeight.w800, ), ), const SizedBox(height: 4), Text( subtitle, style: TextStyle( color: Colors.white.withOpacity(0.8), fontSize: 13, height: 1.4, ), ), ], ), ), ), ); } } /// Titre de section avec icône — dark/light adaptatif class OnboardingSectionTitle extends StatelessWidget { final IconData icon; final String title; final String? badge; // Ex: "Étape 1 complète ✓" const OnboardingSectionTitle({ super.key, required this.icon, required this.title, this.badge, }); @override Widget build(BuildContext context) { final isDark = Theme.of(context).brightness == Brightness.dark; final textColor = isDark ? AppColors.textPrimaryDark : AppColors.textPrimary; return Row( children: [ Icon(icon, color: UnionFlowColors.unionGreen, size: 20), const SizedBox(width: 8), Expanded( child: Text( title, style: TextStyle( color: textColor, fontWeight: FontWeight.w700, fontSize: 16, ), ), ), if (badge != null) Container( padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( color: UnionFlowColors.unionGreen.withOpacity(0.12), borderRadius: BorderRadius.circular(12), ), child: Text( badge!, style: const TextStyle( fontSize: 10, fontWeight: FontWeight.w700, color: UnionFlowColors.unionGreen, ), ), ), ], ); } } /// Barre de bouton principale en bas de page — dark/light adaptatif class OnboardingBottomBar extends StatelessWidget { final bool enabled; final String label; final VoidCallback onPressed; final String? hint; // Texte optionnel au-dessus du bouton const OnboardingBottomBar({ super.key, required this.enabled, required this.label, required this.onPressed, this.hint, }); @override Widget build(BuildContext context) { final isDark = Theme.of(context).brightness == Brightness.dark; final bgColor = isDark ? AppColors.surfaceDark : AppColors.surface; final borderColor = isDark ? AppColors.borderDark : AppColors.border; final hintColor = isDark ? AppColors.textSecondaryDark : AppColors.textSecondary; return Container( padding: EdgeInsets.fromLTRB( 20, 12, 20, MediaQuery.of(context).padding.bottom + 12), decoration: BoxDecoration( color: bgColor, border: Border(top: BorderSide(color: borderColor, width: 0.5)), boxShadow: [ BoxShadow(color: AppColors.shadow, blurRadius: 12, offset: const Offset(0, -4)), ], ), child: Column( mainAxisSize: MainAxisSize.min, children: [ if (hint != null) ...[ Text( hint!, style: TextStyle(fontSize: 11, color: hintColor), textAlign: TextAlign.center, ), const SizedBox(height: 8), ], SizedBox( width: double.infinity, child: ElevatedButton( onPressed: enabled ? onPressed : null, style: ElevatedButton.styleFrom( backgroundColor: UnionFlowColors.unionGreen, disabledBackgroundColor: isDark ? AppColors.borderDark : AppColors.border, foregroundColor: AppColors.onPrimary, disabledForegroundColor: isDark ? AppColors.textSecondaryDark : AppColors.textSecondary, padding: const EdgeInsets.symmetric(vertical: 15), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(14)), elevation: enabled ? 2 : 0, shadowColor: UnionFlowColors.unionGreen.withOpacity(0.4), ), child: Text( label, style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w700, letterSpacing: 0.3, ), ), ), ), ], ), ); } }