Files
maps-saas/apps/siro_maps/lib/views/onboarding/onboarding_view.dart
T

236 lines
9.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../core/constants/app_colors.dart';
import '../map/map_view.dart';
class OnboardingView extends StatefulWidget {
const OnboardingView({super.key});
@override
State<OnboardingView> createState() => _OnboardingViewState();
}
class _OnboardingViewState extends State<OnboardingView> {
final PageController _pageController = PageController();
int _currentIndex = 0;
final List<Map<String, dynamic>> _slides = [
{
'icon': Icons.public_rounded,
'title': 'سيادة مكانية وملاحة عربية مستقلة',
'desc': 'بنية خرائط وملاحة سيادية متكاملة؛ ننهي التبعية لمزودي الخرائط الأجانب ونخدم الأسواق الإقليمية المحرومة من خرائط موثوقة.',
'badge': 'سيادة إقليمية',
},
{
'icon': Icons.alt_route_rounded,
'title': 'توجيه محلي فائق السرعة',
'desc': 'محرك ملاحة متطور يفهم طبيعة شبكات الطرق والمدن العربية، بزمن استجابة فائق ودقة توجيه عالية.',
'badge': 'أداء فائق',
},
{
'icon': Icons.security_rounded,
'title': 'أمان واستقلالية مطلقة',
'desc': 'لا تتبع عشوائي ولا ارتهان لعقوبات أو واجهات أجنبية، مع جاهزية كاملة للعمل عند انقطاع الإنترنت الدولي.',
'badge': 'حماية مشفرة',
},
];
Future<void> _completeOnboarding() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool('has_seen_onboarding', true);
if (mounted) {
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (_) => const MapView()),
);
}
}
void _onNext() {
if (_currentIndex < _slides.length - 1) {
_pageController.nextPage(
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOutCubic,
);
} else {
_completeOnboarding();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColors.canvasLight,
body: SafeArea(
child: Column(
children: [
// Top Bar
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 12),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'Siro Maps',
style: GoogleFonts.alexandria(
fontSize: 16,
fontWeight: FontWeight.w700,
color: AppColors.textPrimary,
),
),
TextButton(
onPressed: _completeOnboarding,
child: Text(
'تخطي',
style: GoogleFonts.alexandria(
fontSize: 13,
fontWeight: FontWeight.w600,
color: AppColors.appleBlue,
),
),
),
],
),
),
// PageView
Expanded(
child: PageView.builder(
controller: _pageController,
onPageChanged: (i) => setState(() => _currentIndex = i),
itemCount: _slides.length,
itemBuilder: (context, index) {
final slide = _slides[index];
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16),
child: Center(
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Icon Container
Container(
width: 90,
height: 90,
decoration: BoxDecoration(
color: AppColors.appleBlue.withValues(alpha: 0.08),
shape: BoxShape.circle,
),
child: Center(
child: Icon(
slide['icon'] as IconData,
size: 46,
color: AppColors.appleBlue,
),
),
),
const SizedBox(height: 24),
// Badge
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
decoration: BoxDecoration(
color: AppColors.surfaceMuted,
borderRadius: BorderRadius.circular(16),
border: Border.all(color: AppColors.borderSubtle),
),
child: Text(
slide['badge'] as String,
style: GoogleFonts.alexandria(
fontSize: 11,
fontWeight: FontWeight.w600,
color: AppColors.appleBlue,
),
),
),
const SizedBox(height: 14),
// Title
Text(
slide['title'] as String,
textAlign: TextAlign.center,
style: GoogleFonts.alexandria(
fontSize: 22,
fontWeight: FontWeight.w800,
color: AppColors.textPrimary,
height: 1.3,
),
),
const SizedBox(height: 12),
// Description
Text(
slide['desc'] as String,
textAlign: TextAlign.center,
style: GoogleFonts.alexandria(
fontSize: 13.5,
fontWeight: FontWeight.w400,
color: AppColors.textSecondary,
height: 1.5,
),
),
],
),
),
),
);
},
),
),
// Bottom Action & Indicator
Padding(
padding: const EdgeInsets.all(28),
child: Column(
children: [
// Dot Indicator
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: List.generate(
_slides.length,
(i) => AnimatedContainer(
duration: const Duration(milliseconds: 250),
margin: const EdgeInsets.symmetric(horizontal: 4),
width: _currentIndex == i ? 24 : 8,
height: 8,
decoration: BoxDecoration(
color: _currentIndex == i
? AppColors.appleBlue
: AppColors.borderGlass,
borderRadius: BorderRadius.circular(4),
),
),
),
),
const SizedBox(height: 32),
// CTA Button
SizedBox(
width: double.infinity,
height: 52,
child: ElevatedButton(
onPressed: _onNext,
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.appleBlue,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(999),
),
elevation: 0,
),
child: Text(
_currentIndex == _slides.length - 1
? 'ابدأ استكشاف الخريطة'
: 'متابعة',
style: GoogleFonts.alexandria(
fontSize: 15,
fontWeight: FontWeight.w700,
),
),
),
),
],
),
),
],
),
),
);
}
}