import 'package:flutter/material.dart'; import '../theme.dart'; import 'baseline_screen.dart'; class OnboardingScreen extends StatefulWidget { const OnboardingScreen({super.key}); @override State createState() => _OnboardingScreenState(); } class _OnboardingScreenState extends State { final _controller = PageController(); int _currentPage = 0; final _slides = const [ _SlideData( icon: Icons.person_outline, title: 'Tell us your baseline', description: 'Age, sex, country, and any existing health conditions.', ), _SlideData( icon: Icons.checklist_outlined, title: 'Answer a few questions', description: 'Simple inputs about sleep, activity, and daily habits.', ), _SlideData( icon: Icons.insights_outlined, title: 'See your biggest lever', description: 'Discover which single change could add the most months to your life.', ), ]; @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Column( children: [ Expanded( child: PageView.builder( controller: _controller, itemCount: _slides.length, onPageChanged: (index) => setState(() => _currentPage = index), itemBuilder: (context, index) => _buildSlide(_slides[index]), ), ), Padding( padding: const EdgeInsets.all(32), child: Column( children: [ // Page indicators Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate( _slides.length, (index) => _buildDot(index), ), ), const SizedBox(height: 32), // Button SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _onButtonPressed, child: Text(_currentPage == _slides.length - 1 ? 'Get Started' : 'Next'), ), ), const SizedBox(height: 12), // Skip button (not on last page) if (_currentPage < _slides.length - 1) TextButton( onPressed: _skip, child: Text( 'Skip', style: TextStyle(color: AppColors.textTertiary), ), ) else const SizedBox(height: 40), ], ), ), ], ), ), ); } Widget _buildSlide(_SlideData slide) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 40), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( width: 120, height: 120, decoration: BoxDecoration( color: AppColors.primary.withAlpha(26), shape: BoxShape.circle, ), child: Icon( slide.icon, size: 56, color: AppColors.primary, ), ), const SizedBox(height: 48), Text( slide.title, style: Theme.of(context).textTheme.headlineLarge, textAlign: TextAlign.center, ), const SizedBox(height: 16), Text( slide.description, style: Theme.of(context).textTheme.bodyLarge?.copyWith( color: AppColors.textSecondary, ), textAlign: TextAlign.center, ), ], ), ); } Widget _buildDot(int index) { final isActive = index == _currentPage; return AnimatedContainer( duration: const Duration(milliseconds: 200), margin: const EdgeInsets.symmetric(horizontal: 4), width: isActive ? 24 : 8, height: 8, decoration: BoxDecoration( color: isActive ? AppColors.primary : AppColors.divider, borderRadius: BorderRadius.circular(4), ), ); } void _onButtonPressed() { if (_currentPage < _slides.length - 1) { _controller.nextPage( duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); } else { _navigateToBaseline(); } } void _skip() { _navigateToBaseline(); } void _navigateToBaseline() { Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (_) => const BaselineScreen()), ); } } class _SlideData { final IconData icon; final String title; final String description; const _SlideData({ required this.icon, required this.title, required this.description, }); }