import 'package:flutter/material.dart'; import 'package:smooth_page_indicator/smooth_page_indicator.dart'; import 'package:uuid/uuid.dart'; import '../../theme/app_theme.dart'; import '../../models/user_profile.dart'; import '../home/home_screen.dart'; import '../husband/husband_home_screen.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../providers/user_provider.dart'; import '../../services/notification_service.dart'; class OnboardingScreen extends ConsumerStatefulWidget { const OnboardingScreen({super.key}); @override ConsumerState createState() => _OnboardingScreenState(); } class _OnboardingScreenState extends ConsumerState { final PageController _pageController = PageController(); int _currentPage = 0; bool _isNavigating = false; // Debounce flag // Form data UserRole _role = UserRole.wife; String _name = ''; RelationshipStatus _relationshipStatus = RelationshipStatus.single; FertilityGoal? _fertilityGoal; int _averageCycleLength = 28; DateTime? _lastPeriodStart; bool _isIrregularCycle = false; int _minCycleLength = 25; int _maxCycleLength = 35; bool _isPadTrackingEnabled = false; // Connection options bool _useExampleData = false; bool _skipPartnerConnection = false; @override void dispose() { _pageController.dispose(); super.dispose(); } void _nextPage() async { if (_isNavigating) return; _isNavigating = true; // Husband Flow: Role (0) -> Name (1) -> Connect (2) -> Finish // Wife Flow: Role (0) -> Name (1) -> Relationship (2) -> [Fertility (3)] -> Cycle (4) -> [Connect (5) if married] int nextPage = _currentPage + 1; // Logic for skipping pages if (_role == UserRole.husband) { if (_currentPage == 2) { // Finish after connect page await _completeOnboarding(); return; } } else { // Wife flow if (_currentPage == 2 && _relationshipStatus != RelationshipStatus.married) { // Skip fertility goal (page 3) if not married nextPage = 4; } if (_currentPage == 4 && _relationshipStatus != RelationshipStatus.married) { // Skip connect page (page 5) if not married - finish now await _completeOnboarding(); return; } if (_currentPage == 5) { // Finish after connect page (married wife) await _completeOnboarding(); return; } } final maxPages = _role == UserRole.husband ? 2 : 5; if (nextPage <= maxPages) { await _pageController.animateToPage( nextPage, duration: const Duration(milliseconds: 400), curve: Curves.easeInOut, ); } else { await _completeOnboarding(); } // Reset debounce after animation Future.delayed(const Duration(milliseconds: 500), () { if (mounted) setState(() => _isNavigating = false); }); } void _previousPage() async { if (_isNavigating) return; _isNavigating = true; int prevPage = _currentPage - 1; // Logic for reverse skipping if (_role == UserRole.wife) { if (_currentPage == 4 && _relationshipStatus != RelationshipStatus.married) { // Skip back over fertility goal (page 3) prevPage = 2; } } if (prevPage >= 0) { await _pageController.animateToPage( prevPage, duration: const Duration(milliseconds: 400), curve: Curves.easeInOut, ); } // Reset debounce after animation Future.delayed(const Duration(milliseconds: 500), () { if (mounted) setState(() => _isNavigating = false); }); } Future _completeOnboarding() async { final userProfile = UserProfile( id: const Uuid().v4(), name: _name, role: _role, relationshipStatus: _role == UserRole.husband ? RelationshipStatus.married : _relationshipStatus, fertilityGoal: (_role == UserRole.wife && _relationshipStatus == RelationshipStatus.married) ? _fertilityGoal : null, averageCycleLength: _averageCycleLength, lastPeriodStartDate: _lastPeriodStart, isIrregularCycle: _isIrregularCycle, hasCompletedOnboarding: true, useExampleData: _useExampleData, isPadTrackingEnabled: _isPadTrackingEnabled, createdAt: DateTime.now(), updatedAt: DateTime.now(), ); await ref.read(userProfileProvider.notifier).updateProfile(userProfile); // Generate example data if requested if (_useExampleData) { await ref .read(cycleEntriesProvider.notifier) .generateExampleData(userProfile.id); } // Trigger partner connection notification if applicable if (!_skipPartnerConnection && !_useExampleData) { await NotificationService().showPartnerUpdateNotification( title: 'Connection Successful!', body: 'You are now connected with your partner. Tap to start sharing.', ); } if (mounted) { // Navigate to appropriate home screen if (_role == UserRole.husband) { Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (_) => const HusbandHomeScreen(), ), ); } else { Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (_) => const HomeScreen()), ); } } } @override Widget build(BuildContext context) { final theme = Theme.of(context); // final isDark = theme.brightness == Brightness.dark; - unused final isDark = theme.brightness == Brightness.dark; // Different background color for husband flow final isHusband = _role == UserRole.husband; final bgColor = isHusband ? (isDark ? const Color(0xFF1A1C1E) : AppColors.warmCream) : theme.scaffoldBackgroundColor; return Scaffold( backgroundColor: bgColor, body: SafeArea( child: Column( children: [ // Progress indicator (hide on role page 0) if (_currentPage > 0) Padding( padding: const EdgeInsets.all(24), child: SmoothPageIndicator( controller: _pageController, count: isHusband ? 3 : (_relationshipStatus == RelationshipStatus.married ? 6 : 5), effect: WormEffect( dotHeight: 8, dotWidth: 8, spacing: 12, activeDotColor: isHusband ? AppColors.navyBlue : AppColors.sageGreen, dotColor: theme.colorScheme.outline.withValues(alpha: 0.2), ), ), ), // Pages Expanded( child: PageView( controller: _pageController, physics: const NeverScrollableScrollPhysics(), // Disable swipe onPageChanged: (index) { setState(() => _currentPage = index); }, children: [ _buildRolePage(), // Page 0 _buildNamePage(), // Page 1 if (_role == UserRole.husband) _buildHusbandConnectPage() // Page 2 (Husband only) else ...[ _buildRelationshipPage(), // Page 2 (Wife only) _buildFertilityGoalPage(), // Page 3 (Wife married only) _buildCyclePage(), // Page 4 (Wife only) if (_relationshipStatus == RelationshipStatus.married) _buildWifeConnectPage(), // Page 5 (Wife married only) ], ], ), ), ], ), ), ); } Widget _buildRolePage() { final theme = Theme.of(context); return Padding( padding: const EdgeInsets.all(32), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 80, height: 80, decoration: BoxDecoration( gradient: LinearGradient( colors: [ AppColors.blushPink, AppColors.rose.withValues(alpha: 0.7) ], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.circular(20), ), child: const Icon( Icons.favorite_rounded, size: 40, color: Colors.white, ), ), const SizedBox(height: 32), Text( 'Who is this app for?', textAlign: TextAlign.center, style: theme.textTheme.displayMedium?.copyWith( fontSize: 28, fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface, ), ), const SizedBox(height: 48), _buildRoleOption(UserRole.wife, 'For Her', 'Track cycle, health, and faith', Icons.female), const SizedBox(height: 16), _buildRoleOption(UserRole.husband, 'For Him', 'Support your wife and grow together', Icons.male), const Spacer(), SizedBox( width: double.infinity, height: 54, child: ElevatedButton( onPressed: _nextPage, style: ElevatedButton.styleFrom( backgroundColor: _role == UserRole.husband ? AppColors.navyBlue : AppColors.sageGreen, ), child: const Text('Continue'), ), ), ], ), ); } Widget _buildRoleOption( UserRole role, String title, String subtitle, IconData icon) { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; final isSelected = _role == role; // Dynamic colors based on role selection final activeColor = role == UserRole.wife ? AppColors.sageGreen : AppColors.navyBlue; final activeBg = activeColor.withValues(alpha: isDark ? 0.3 : 0.1); return GestureDetector( onTap: () => setState(() => _role = role), child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: isSelected ? activeBg : theme.cardTheme.color, borderRadius: BorderRadius.circular(16), border: Border.all( color: isSelected ? activeColor : theme.colorScheme.outline.withValues(alpha: 0.1), width: isSelected ? 2 : 1, ), ), child: Row( children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isSelected ? activeColor : theme.colorScheme.surfaceContainerHighest, shape: BoxShape.circle, ), child: Icon( icon, color: isSelected ? Colors.white : theme.colorScheme.onSurfaceVariant, size: 24, ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: theme.textTheme.titleLarge?.copyWith( fontSize: 18, fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface, ), ), const SizedBox(height: 4), Text( subtitle, style: theme.textTheme.bodyMedium?.copyWith( color: theme.colorScheme.onSurfaceVariant, ), ), ], ), ), if (isSelected) Icon(Icons.check_circle, color: activeColor), ], ), ), ); } Widget _buildNamePage() { final theme = Theme.of(context); final isHusband = _role == UserRole.husband; final activeColor = isHusband ? AppColors.navyBlue : AppColors.sageGreen; return Padding( padding: const EdgeInsets.all(32), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 40), Text( isHusband ? 'What\'s your name, sir?' : 'What\'s your name?', style: theme.textTheme.displaySmall?.copyWith( fontSize: 28, fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface, ), ), const SizedBox(height: 8), Text( 'We\'ll use this to personalize the app.', style: theme.textTheme.bodyMedium?.copyWith( color: theme.colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 32), TextField( onChanged: (value) => setState(() => _name = value), decoration: InputDecoration( hintText: 'Enter your name', prefixIcon: Icon( Icons.person_outline, color: theme.colorScheme.onSurfaceVariant, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: activeColor, width: 2), ), ), style: theme.textTheme.bodyLarge, textCapitalization: TextCapitalization.words, ), const Spacer(), Row( children: [ Expanded( child: SizedBox( height: 54, child: OutlinedButton( onPressed: _previousPage, style: OutlinedButton.styleFrom( foregroundColor: activeColor, side: BorderSide(color: activeColor), ), child: const Text('Back'), ), ), ), const SizedBox(width: 16), Expanded( child: SizedBox( height: 54, child: ElevatedButton( onPressed: (_name.isNotEmpty && !_isNavigating) ? _nextPage : null, style: ElevatedButton.styleFrom( backgroundColor: activeColor, ), child: Text(isHusband ? 'Finish Setup' : 'Continue'), ), ), ), ], ), ], ), ); } Widget _buildRelationshipPage() { final theme = Theme.of(context); return Padding( padding: const EdgeInsets.all(32), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 40), Text( 'Tell us about yourself', style: theme.textTheme.displaySmall?.copyWith( fontSize: 28, fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface, ), ), const SizedBox(height: 32), _buildRelationshipOption(RelationshipStatus.single, 'Single', 'Wellness focus', Icons.person_outline), const SizedBox(height: 12), _buildRelationshipOption(RelationshipStatus.engaged, 'Engaged', 'Prepare for marriage', Icons.favorite_border), const SizedBox(height: 12), _buildRelationshipOption(RelationshipStatus.married, 'Married', 'Fertility & intimacy', Icons.favorite), const Spacer(), Row( children: [ Expanded( child: SizedBox( height: 54, child: OutlinedButton( onPressed: _previousPage, style: OutlinedButton.styleFrom( foregroundColor: AppColors.sageGreen, side: const BorderSide(color: AppColors.sageGreen)), child: const Text('Back'), ), ), ), const SizedBox(width: 16), Expanded( child: SizedBox( height: 54, child: ElevatedButton( onPressed: !_isNavigating ? _nextPage : null, child: const Text('Continue'), ), ), ), ], ), ], ), ); } Widget _buildRelationshipOption( RelationshipStatus status, String title, String subtitle, IconData icon) { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; final isSelected = _relationshipStatus == status; return GestureDetector( onTap: () => setState(() => _relationshipStatus = status), child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: isSelected ? AppColors.sageGreen.withValues(alpha: isDark ? 0.3 : 0.1) : theme.cardTheme.color, borderRadius: BorderRadius.circular(12), border: Border.all( color: isSelected ? AppColors.sageGreen : theme.colorScheme.outline.withValues(alpha: 0.1), width: isSelected ? 2 : 1, ), ), child: Row( children: [ Icon(icon, color: isSelected ? AppColors.sageGreen : theme.colorScheme.onSurfaceVariant), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface)), Text(subtitle, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.onSurfaceVariant)), ], ), ), if (isSelected) const Icon(Icons.check_circle, color: AppColors.sageGreen), ], ), ), ); } Widget _buildFertilityGoalPage() { final theme = Theme.of(context); return Padding( padding: const EdgeInsets.all(32), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 40), Text('What\'s your goal?', style: theme.textTheme.displaySmall?.copyWith( fontSize: 28, fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface)), const SizedBox(height: 32), _buildGoalOption(FertilityGoal.tryingToConceive, 'Trying to Conceive', 'Track fertile days', Icons.child_care_outlined), const SizedBox(height: 12), _buildGoalOption( FertilityGoal.tryingToAvoid, 'Natural Family Planning', 'Track fertility signs', Icons.calendar_today_outlined), const SizedBox(height: 12), _buildGoalOption(FertilityGoal.justTracking, 'Just Tracking', 'Monitor cycle health', Icons.insights_outlined), const Spacer(), Row( children: [ Expanded( child: SizedBox( height: 54, child: OutlinedButton( onPressed: _previousPage, style: OutlinedButton.styleFrom( foregroundColor: AppColors.sageGreen, side: const BorderSide(color: AppColors.sageGreen)), child: const Text('Back'), ), ), ), const SizedBox(width: 16), Expanded( child: SizedBox( height: 54, child: ElevatedButton( onPressed: (_fertilityGoal != null && !_isNavigating) ? _nextPage : null, child: const Text('Continue'), ), ), ), ], ), ], ), ); } Widget _buildGoalOption( FertilityGoal goal, String title, String subtitle, IconData icon) { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; final isSelected = _fertilityGoal == goal; return GestureDetector( onTap: () => setState(() => _fertilityGoal = goal), child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: isSelected ? AppColors.sageGreen.withValues(alpha: isDark ? 0.3 : 0.1) : theme.cardTheme.color, borderRadius: BorderRadius.circular(12), border: Border.all( color: isSelected ? AppColors.sageGreen : theme.colorScheme.outline.withValues(alpha: 0.1), width: isSelected ? 2 : 1, ), ), child: Row( children: [ Icon(icon, color: isSelected ? AppColors.sageGreen : theme.colorScheme.onSurfaceVariant), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(title, style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface)), Text(subtitle, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.onSurfaceVariant)), ], ), ), if (isSelected) const Icon(Icons.check_circle, color: AppColors.sageGreen), ], ), ), ); } Widget _buildCyclePage() { final theme = Theme.of(context); // final isDark = theme.brightness == Brightness.dark; - unused // final isDark = theme.brightness == Brightness.dark; return Padding( padding: const EdgeInsets.all(32), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 40), Text('About your cycle', style: theme.textTheme.displaySmall?.copyWith( fontSize: 28, fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface)), const SizedBox(height: 32), Text('Average cycle length', style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w500, color: theme.colorScheme.onSurface)), Row( children: [ Expanded( child: Slider( value: _averageCycleLength.toDouble(), min: 21, max: 40, divisions: 19, activeColor: AppColors.sageGreen, onChanged: (value) => setState(() => _averageCycleLength = value.round()), ), ), Text('$_averageCycleLength days', style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w600, color: AppColors.sageGreen)), ], ), // Irregular Cycle Checkbox CheckboxListTile( title: Text('My cycles are irregular', style: theme.textTheme.bodyLarge ?.copyWith(color: theme.colorScheme.onSurface)), value: _isIrregularCycle, onChanged: (val) => setState(() => _isIrregularCycle = val ?? false), activeColor: AppColors.sageGreen, contentPadding: EdgeInsets.zero, controlAffinity: ListTileControlAffinity.leading, ), if (_isIrregularCycle) ...[ const SizedBox(height: 8), Text('Cycle range (shortest to longest)', style: theme.textTheme.titleSmall?.copyWith( fontWeight: FontWeight.w500, color: theme.colorScheme.onSurface)), Row( children: [ Expanded( child: RangeSlider( values: RangeValues( _minCycleLength.toDouble(), _maxCycleLength.toDouble()), min: 21, max: 45, divisions: 24, activeColor: AppColors.sageGreen, labels: RangeLabels( '$_minCycleLength days', '$_maxCycleLength days'), onChanged: (values) { setState(() { _minCycleLength = values.start.round(); _maxCycleLength = values.end.round(); }); }, ), ), ], ), Center( child: Text('$_minCycleLength - $_maxCycleLength days', style: theme.textTheme.bodyMedium?.copyWith( fontWeight: FontWeight.w600, color: AppColors.sageGreen)), ), ], // Enable Supply Tracking Checkbox CheckboxListTile( title: Text('Enable supply tracking', style: theme.textTheme.bodyLarge ?.copyWith(color: theme.colorScheme.onSurface)), value: _isPadTrackingEnabled, onChanged: (val) => setState(() => _isPadTrackingEnabled = val ?? false), activeColor: AppColors.sageGreen, contentPadding: EdgeInsets.zero, controlAffinity: ListTileControlAffinity.leading, ), const SizedBox(height: 24), Text('Last period start date', style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w500, color: theme.colorScheme.onSurface)), const SizedBox(height: 8), GestureDetector( onTap: () async { final date = await showDatePicker( context: context, initialDate: _lastPeriodStart ?? DateTime.now(), firstDate: DateTime.now().subtract(const Duration(days: 60)), lastDate: DateTime.now(), builder: (context, child) { return Theme( data: theme.copyWith( colorScheme: theme.colorScheme.copyWith( primary: AppColors.sageGreen, onPrimary: Colors.white, ), ), child: child!, ); }, ); if (date != null) setState(() => _lastPeriodStart = date); }, child: Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: theme.cardTheme.color, borderRadius: BorderRadius.circular(12), border: Border.all( color: theme.colorScheme.outline.withValues(alpha: 0.1))), child: Row( children: [ Icon(Icons.calendar_today, color: theme.colorScheme.onSurfaceVariant), const SizedBox(width: 12), Text( _lastPeriodStart != null ? "${_lastPeriodStart!.month}/${_lastPeriodStart!.day}/${_lastPeriodStart!.year}" : "Select Date", style: theme.textTheme.bodyLarge ?.copyWith(color: theme.colorScheme.onSurface)), ], ), ), ), const Spacer(), Row( children: [ Expanded( child: SizedBox( height: 54, child: OutlinedButton( onPressed: _previousPage, style: OutlinedButton.styleFrom( foregroundColor: AppColors.sageGreen, side: const BorderSide(color: AppColors.sageGreen)), child: const Text('Back'), ), ), ), const SizedBox(width: 16), Expanded( child: SizedBox( height: 54, child: ElevatedButton( onPressed: (_lastPeriodStart != null && !_isNavigating) ? _nextPage : null, child: const Text('Get Started'), ), ), ), ], ), ], ), ); } /// Husband Connect Page - Choose to connect with wife or use example data Widget _buildHusbandConnectPage() { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; return Padding( padding: const EdgeInsets.all(32), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 40), Container( width: 64, height: 64, decoration: BoxDecoration( color: AppColors.navyBlue.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(16), ), child: const Icon(Icons.link, size: 32, color: AppColors.navyBlue), ), const SizedBox(height: 24), Text( 'Connect with your wife', style: theme.textTheme.displaySmall?.copyWith( fontSize: 28, fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface, ), ), const SizedBox(height: 8), Text( 'See her cycle info and prayer requests to support her better.', style: theme.textTheme.bodyMedium?.copyWith( color: theme.colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 32), // Option 1: Connect with Wife (placeholder for now) _buildConnectOption( icon: Icons.qr_code_scanner, title: 'Connect with Wife', subtitle: 'Enter connection code from her app', isSelected: !_useExampleData, onTap: () => setState(() => _useExampleData = false), color: AppColors.navyBlue, isDark: isDark, ), const SizedBox(height: 16), // Option 2: Use Example Data _buildConnectOption( icon: Icons.auto_awesome, title: 'Use Example Data', subtitle: 'Explore the app with sample data', isSelected: _useExampleData, onTap: () => setState(() => _useExampleData = true), color: AppColors.navyBlue, isDark: isDark, ), const Spacer(), Row( children: [ Expanded( child: SizedBox( height: 54, child: OutlinedButton( onPressed: _previousPage, style: OutlinedButton.styleFrom( foregroundColor: AppColors.navyBlue, side: const BorderSide(color: AppColors.navyBlue), ), child: const Text('Back'), ), ), ), const SizedBox(width: 16), Expanded( child: SizedBox( height: 54, child: ElevatedButton( onPressed: !_isNavigating ? _nextPage : null, style: ElevatedButton.styleFrom( backgroundColor: AppColors.navyBlue, ), child: const Text('Finish Setup'), ), ), ), ], ), ], ), ); } /// Wife Connect Page - Invite husband or skip Widget _buildWifeConnectPage() { final theme = Theme.of(context); final isDark = theme.brightness == Brightness.dark; return Padding( padding: const EdgeInsets.all(32), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const SizedBox(height: 40), Container( width: 64, height: 64, decoration: BoxDecoration( color: AppColors.sageGreen.withValues(alpha: 0.1), borderRadius: BorderRadius.circular(16), ), child: const Icon(Icons.favorite, size: 32, color: AppColors.sageGreen), ), const SizedBox(height: 24), Text( 'Invite your husband', style: theme.textTheme.displaySmall?.copyWith( fontSize: 28, fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface, ), ), const SizedBox(height: 8), Text( 'Share your cycle info and prayer requests so he can support you.', style: theme.textTheme.bodyMedium?.copyWith( color: theme.colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 32), // Option 1: Invite Husband _buildConnectOption( icon: Icons.share, title: 'Invite Husband', subtitle: 'Generate a connection code to share', isSelected: !_skipPartnerConnection, onTap: () => setState(() => _skipPartnerConnection = false), color: AppColors.sageGreen, isDark: isDark, ), const SizedBox(height: 16), // Option 2: Skip for Now _buildConnectOption( icon: Icons.schedule, title: 'Skip for Now', subtitle: 'You can invite him later in settings', isSelected: _skipPartnerConnection, onTap: () => setState(() => _skipPartnerConnection = true), color: AppColors.sageGreen, isDark: isDark, ), const Spacer(), Row( children: [ Expanded( child: SizedBox( height: 54, child: OutlinedButton( onPressed: _previousPage, style: OutlinedButton.styleFrom( foregroundColor: AppColors.sageGreen, side: const BorderSide(color: AppColors.sageGreen), ), child: const Text('Back'), ), ), ), const SizedBox(width: 16), Expanded( child: SizedBox( height: 54, child: ElevatedButton( onPressed: !_isNavigating ? _nextPage : null, child: const Text('Get Started'), ), ), ), ], ), ], ), ); } /// Helper for connection option cards Widget _buildConnectOption({ required IconData icon, required String title, required String subtitle, required bool isSelected, required VoidCallback onTap, required Color color, required bool isDark, }) { final theme = Theme.of(context); return GestureDetector( onTap: onTap, child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: isSelected ? color.withValues(alpha: isDark ? 0.3 : 0.1) : theme.cardTheme.color, borderRadius: BorderRadius.circular(12), border: Border.all( color: isSelected ? color : theme.colorScheme.outline.withValues(alpha: 0.1), width: isSelected ? 2 : 1, ), ), child: Row( children: [ Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isSelected ? color : theme.colorScheme.surfaceContainerHighest, borderRadius: BorderRadius.circular(8), ), child: Icon( icon, color: isSelected ? Colors.white : theme.colorScheme.onSurfaceVariant, size: 20, ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: theme.textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w600, color: theme.colorScheme.onSurface, ), ), Text( subtitle, style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.onSurfaceVariant, ), ), ], ), ), if (isSelected) Icon(Icons.check_circle, color: color), ], ), ), ); } }