import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:go_router/go_router.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:real_estate_mobile/core/constants/app_colors.dart'; class OnboardingScreen extends StatefulWidget { const OnboardingScreen({super.key}); @override State createState() => _OnboardingScreenState(); } class _OnboardingScreenState extends State { final PageController _pageController = PageController(); int _currentPage = 0; static const _pages = [ _OnboardingData( bgAsset: 'assets/images/onboarding_1_bg.svg', iconAsset: 'assets/images/onboarding_1_icon.svg', iconWidth: 110, iconHeight: 100, title: 'Connect with Top Professionals', subtitle: 'Agents can highlight their specializations for buyers to find faster than ever', ), _OnboardingData( bgAsset: 'assets/images/onboarding_2_bg.svg', iconAsset: 'assets/images/onboarding_2_icon.svg', iconWidth: 83, iconHeight: 75, title: 'Real help. Real professionals. Instantly.', subtitle: 'Chat with agents instantly and find your service provider with ease', ), ]; Future _completeOnboarding() async { final prefs = await SharedPreferences.getInstance(); await prefs.setBool('onboarding_completed', true); if (mounted) { context.go('/home'); } } void _nextPage() { if (_currentPage < _pages.length - 1) { _pageController.nextPage( duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); } else { _completeOnboarding(); } } @override void dispose() { _pageController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( body: Container( width: double.infinity, height: double.infinity, decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ AppColors.gradientStart, // #C4D9D4 AppColors.gradientEnd, // #F0F5FC ], ), ), child: SafeArea( child: Column( children: [ // Skip button - top right Align( alignment: Alignment.centerRight, child: GestureDetector( onTap: _completeOnboarding, child: const Padding( padding: EdgeInsets.only(right: 24, top: 16), child: Text( 'Skip', style: TextStyle( fontFamily: 'Fractul', fontSize: 16, fontWeight: FontWeight.w700, color: AppColors.accentOrange, letterSpacing: 0.24, ), ), ), ), ), // Main content - PageView Expanded( child: PageView.builder( controller: _pageController, itemCount: _pages.length, onPageChanged: (index) { setState(() => _currentPage = index); }, itemBuilder: (context, index) { return _OnboardingPage(data: _pages[index]); }, ), ), // Pagination dots Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(_pages.length, (index) { final isActive = index == _currentPage; return Container( margin: const EdgeInsets.symmetric(horizontal: 6), width: isActive ? 32 : 8, height: 8, decoration: BoxDecoration( color: isActive ? AppColors.accentOrange : const Color(0xFFBCBCBC), borderRadius: BorderRadius.circular(9999), ), ); }), ), const SizedBox(height: 40), // Next / Get Started button Padding( padding: const EdgeInsets.fromLTRB(24, 0, 24, 48), child: SizedBox( width: double.infinity, height: 56, child: DecoratedBox( decoration: BoxDecoration( color: AppColors.accentOrange, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: AppColors.accentOrange.withValues(alpha: 0.2), blurRadius: 15, offset: const Offset(0, 10), spreadRadius: -3, ), BoxShadow( color: AppColors.accentOrange.withValues(alpha: 0.2), blurRadius: 6, offset: const Offset(0, 4), spreadRadius: -4, ), ], ), child: Material( color: Colors.transparent, child: InkWell( onTap: _nextPage, borderRadius: BorderRadius.circular(12), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( _currentPage < _pages.length - 1 ? 'Next' : 'Get Started', style: const TextStyle( fontFamily: 'Fractul', fontSize: 18, fontWeight: FontWeight.w700, color: Colors.white, ), ), const SizedBox(width: 8), SvgPicture.asset( 'assets/icons/arrow_right_white.svg', width: 16, height: 16, ), ], ), ), ), ), ), ), ], ), ), ), ); } } class _OnboardingPage extends StatelessWidget { final _OnboardingData data; const _OnboardingPage({required this.data}); @override Widget build(BuildContext context) { // Scale the illustration to ~38% of screen height so it shrinks on small // devices, leaving room for the title + subtitle without overflow. final screenHeight = MediaQuery.of(context).size.height; final illustrationHeight = (screenHeight * 0.38).clamp(220.0, 346.0); return SingleChildScrollView( physics: const ClampingScrollPhysics(), child: Column( children: [ // Illustration section Padding( padding: const EdgeInsets.only(top: 8), child: SizedBox( width: MediaQuery.of(context).size.width - 24, height: illustrationHeight, child: Stack( alignment: Alignment.center, children: [ // Background oval/pill shape with orange gradient Positioned.fill( child: SvgPicture.asset( data.bgAsset, fit: BoxFit.contain, ), ), // Blurred decoration - bottom right Positioned( right: 20, bottom: 20, child: Container( width: 120, height: 120, decoration: BoxDecoration( shape: BoxShape.circle, color: AppColors.accentOrange.withValues(alpha: 0.2), boxShadow: [ BoxShadow( color: AppColors.accentOrange .withValues(alpha: 0.15), blurRadius: 40, spreadRadius: 0, ), ], ), ), ), // Blurred decoration - top left Positioned( left: 0, top: 0, child: Container( width: 120, height: 120, decoration: BoxDecoration( shape: BoxShape.circle, color: AppColors.accentOrange.withValues(alpha: 0.1), boxShadow: [ BoxShadow( color: AppColors.accentOrange .withValues(alpha: 0.08), blurRadius: 40, spreadRadius: 0, ), ], ), ), ), // Main icon + small icons Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( data.iconAsset, width: data.iconWidth, height: data.iconHeight, ), const SizedBox(height: 12), // Small property icons row Row( mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( 'assets/images/onboarding_small_icon_1.svg', width: 27, height: 27, ), const SizedBox(width: 8), SvgPicture.asset( 'assets/images/onboarding_small_icon_2.svg', width: 31.5, height: 31.5, ), const SizedBox(width: 8), SvgPicture.asset( 'assets/images/onboarding_small_icon_3.svg', width: 24, height: 27, ), ], ), ], ), ], ), ), ), // Text content section Padding( padding: const EdgeInsets.fromLTRB(24, 16, 24, 16), child: Column( mainAxisSize: MainAxisSize.min, children: [ // Title Text( data.title, textAlign: TextAlign.center, style: const TextStyle( fontFamily: 'Fractul', fontSize: 26, fontWeight: FontWeight.w700, color: Color(0xFF0F172A), height: 1.25, letterSpacing: -0.8, ), ), const SizedBox(height: 12), // Subtitle Text( data.subtitle, textAlign: TextAlign.center, style: const TextStyle( fontFamily: 'SourceSerif4', fontSize: 15, fontWeight: FontWeight.w400, color: Color(0xFF475569), height: 1.5, ), ), ], ), ), ], ), ); } } class _OnboardingData { final String bgAsset; final String iconAsset; final double iconWidth; final double iconHeight; final String title; final String subtitle; const _OnboardingData({ required this.bgAsset, required this.iconAsset, required this.iconWidth, required this.iconHeight, required this.title, required this.subtitle, }); }