305 lines
14 KiB
Dart
305 lines
14 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:didvan/models/onboarding_entity.dart';
|
||
import 'package:didvan/routes/routes.dart';
|
||
import 'package:didvan/services/storage/storage.dart';
|
||
import 'package:didvan/views/onboarding/onboarding_indicator_painter.dart';
|
||
import 'package:flutter_svg/flutter_svg.dart';
|
||
|
||
final List<OnboardingEntity> onboardingPages = [
|
||
OnboardingEntity(
|
||
imagePath: 'lib/assets/images/onboarding/1.png',
|
||
title: 'چرا دیدوان؟',
|
||
description:
|
||
'جغرافیای زمانی هیچگاه نمیایستد و سفر به آینده یک سفر شگفتانگیز به جایی است که قسمتهایی از آن را قبلاً در گذشته دیدهایم، قسمتهایی از آن را طی مسیر به تدریج میبینیم و قسمتهایی از آن کاملاً بدیع هستند. برای سفر مطمئن در جغرافیای زمانی ما به سیستمهای پیشنگر نیاز داریم و یکی از ارکان این سیستمها، سامانههای رصد راهبردی هستند.',
|
||
),
|
||
OnboardingEntity(
|
||
imagePath: 'lib/assets/images/onboarding/2.png',
|
||
title: 'رادارهای استراتژیک',
|
||
description:
|
||
'رادارهای استراتژیک، قلب دیدوان هستند. رادارهایی که قرار است دید 360 درجهای برای مدیران ایجاد کنند و به صورت مستمر گزارشهایی تحلیلی را از محیطهای دور و نزدیک هر کسب و کار در اختیار مدیران قرار دهند. رادارها به صورت موضوعی شامل رادار روند، رادار ریسک، رادار تکنولوژی، رادار استارتآپ و ماژول فرصت و تهدید دسته بندی شدهاند و مدیران میتوانند پیرامون این گزارشات به بحث و تبادل نظر بپردازند.',
|
||
),
|
||
OnboardingEntity(
|
||
imagePath: 'lib/assets/images/onboarding/3.png',
|
||
title: 'استودیو دیدوان',
|
||
description:
|
||
'''در استودیو آینده شما میتوانید ویدیوهایی مستند از مسائلی مانند آموزش مفاهیم آیندهگرا، تحلیل روندها، تحلیل صنعت و یا هر نوع اطلاعاتی که میتواند برای تصمیمگیری مدیران ارشد راهگشا باشد را ببینید.
|
||
همچنین در بخش دیگر این استودیو و در قالب پادکست، اطلاعاتی از جنس مسائل پیش گفته که ارزش تبدیل به فایل صوتی دارند را، میشنوید.
|
||
''',
|
||
),
|
||
OnboardingEntity(
|
||
imagePath: 'lib/assets/images/onboarding/4.png',
|
||
title: 'نبض صنعت',
|
||
description: 'در دنیای امروز، تصمیمگیریهای کلیدی در صنایع مختلف به شدت وابسته به دادههای دقیق و بهروز شدهاند. این دادهها شامل اطلاعات اقتصادی، مالی، خرید و فروش، بازار سرمایه، ارزهای دیجیتال، شاخصهای کلان اقتصادی و دیگر حوزهها هستند. استفاده هوشمندانه از دادهها این امکان را به مدیران میدهد تا تصمیماتی آگاهانه بگیرند، ریسکها را کاهش دهند و عملکرد کلی خود را به سطحی بالاتر ارتقاء دهند.',
|
||
),
|
||
];
|
||
|
||
class OnboardingPage extends StatefulWidget {
|
||
const OnboardingPage({super.key});
|
||
|
||
@override
|
||
State<OnboardingPage> createState() => _OnboardingPageState();
|
||
}
|
||
|
||
class _OnboardingPageState extends State<OnboardingPage> {
|
||
final PageController _pageController = PageController();
|
||
int _currentPage = 0;
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
_pageController.addListener(() {
|
||
if (_pageController.page != null) {
|
||
setState(() {
|
||
_currentPage = _pageController.page!.round();
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
_pageController.dispose();
|
||
super.dispose();
|
||
}
|
||
|
||
void _onNextTap() async {
|
||
if (_currentPage < onboardingPages.length - 1) {
|
||
_pageController.nextPage(
|
||
duration: const Duration(milliseconds: 400),
|
||
curve: Curves.easeInOut,
|
||
);
|
||
} else {
|
||
await _completeOnboarding();
|
||
}
|
||
}
|
||
|
||
Future<void> _completeOnboarding() async {
|
||
await StorageService.setValue(key: 'hasSeenOnboarding', value: 'true');
|
||
if (mounted) {
|
||
Navigator.of(context).pushReplacementNamed(
|
||
Routes.authenticaion,
|
||
arguments: {'isResetPassword': false},
|
||
);
|
||
}
|
||
}
|
||
|
||
void _skipOnboarding() async {
|
||
await _completeOnboarding();
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final theme = Theme.of(context);
|
||
final colorScheme = theme.colorScheme;
|
||
|
||
return Scaffold(
|
||
backgroundColor: colorScheme.background,
|
||
body: SafeArea(
|
||
child: Stack(
|
||
children: [
|
||
Directionality(
|
||
textDirection: TextDirection.ltr,
|
||
child: PageView.builder(
|
||
controller: _pageController,
|
||
itemCount: onboardingPages.length,
|
||
itemBuilder: (context, index) {
|
||
final page = onboardingPages[index];
|
||
return Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 0),
|
||
child: Column(
|
||
children: [
|
||
Image.asset(
|
||
page.imagePath,
|
||
height: 350,
|
||
width: double.infinity,
|
||
fit: BoxFit.fitWidth,
|
||
errorBuilder: (context, error, stackTrace) {
|
||
return Container(
|
||
decoration: BoxDecoration(
|
||
color: colorScheme.primary.withOpacity(0.1),
|
||
borderRadius: BorderRadius.circular(24),
|
||
),
|
||
child: Center(
|
||
child: Icon(
|
||
Icons.image_outlined,
|
||
size: 80,
|
||
color: colorScheme.primary.withOpacity(0.3),
|
||
),
|
||
),
|
||
);
|
||
},
|
||
),
|
||
SizedBox(
|
||
width: 60,
|
||
height: 60,
|
||
child: Stack(
|
||
alignment: Alignment.center,
|
||
children: [
|
||
CustomPaint(
|
||
size: const Size(60, 60),
|
||
painter: OnboardingIndicatorPainter(
|
||
pageCount: onboardingPages.length,
|
||
currentPage: _currentPage,
|
||
activeColor:
|
||
const Color.fromARGB(255, 1, 35, 72),
|
||
inactiveColor:
|
||
const Color.fromARGB(255, 0, 126, 167)),
|
||
),
|
||
GestureDetector(
|
||
onTap: _onNextTap,
|
||
child: Container(
|
||
width: 60,
|
||
height: 45,
|
||
decoration: const BoxDecoration(
|
||
color: Color.fromARGB(255, 1, 35, 72),
|
||
shape: BoxShape.circle,
|
||
),
|
||
child: Center(
|
||
child: SvgPicture.asset(
|
||
'lib/assets/icons/Arrow - Right 2.svg',
|
||
width: 25,
|
||
height: 25,
|
||
colorFilter: const ColorFilter.mode(
|
||
Colors.white,
|
||
BlendMode.srcIn,
|
||
),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
Expanded(
|
||
flex: 2,
|
||
child: Padding(
|
||
padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
|
||
child: Column(
|
||
mainAxisAlignment: MainAxisAlignment.start,
|
||
crossAxisAlignment: CrossAxisAlignment.end,
|
||
children: [
|
||
Text(
|
||
page.title,
|
||
textAlign: TextAlign.start,
|
||
style:
|
||
theme.textTheme.headlineMedium?.copyWith(
|
||
fontWeight: FontWeight.bold,
|
||
fontSize: 22,
|
||
color: const Color.fromARGB(255, 0, 126, 167),
|
||
),
|
||
),
|
||
const SizedBox(height: 13),
|
||
Text(
|
||
page.description,
|
||
textDirection: TextDirection.rtl,
|
||
textAlign: TextAlign.start,
|
||
style: theme.textTheme.bodyMedium?.copyWith(
|
||
color: const Color.fromARGB(255, 41, 41, 41),
|
||
height: 1.6,
|
||
fontSize: 15
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
},
|
||
),
|
||
),
|
||
|
||
if (_currentPage > 0)
|
||
Positioned(
|
||
top: 16,
|
||
left: 16,
|
||
child: Container(
|
||
height: 40,
|
||
width: 40,
|
||
decoration: const BoxDecoration(
|
||
color: Color.fromARGB(230, 234, 234, 233),
|
||
shape: BoxShape.rectangle,
|
||
borderRadius: BorderRadius.all(Radius.circular(4)),
|
||
),
|
||
child: Center(
|
||
child: IconButton(
|
||
icon: SvgPicture.asset('lib/assets/icons/arrow-left.svg'),
|
||
onPressed: () {
|
||
_pageController.previousPage(
|
||
duration: const Duration(milliseconds: 400),
|
||
curve: Curves.easeInOut,
|
||
);
|
||
},
|
||
),
|
||
),
|
||
),
|
||
),
|
||
|
||
Positioned(
|
||
bottom: 40,
|
||
left: 24,
|
||
right: 24,
|
||
child: Column(
|
||
children: [
|
||
Row(
|
||
children: [
|
||
Expanded(
|
||
flex: 4,
|
||
child: ElevatedButton(
|
||
onPressed: _onNextTap,
|
||
style: ElevatedButton.styleFrom(
|
||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||
backgroundColor: colorScheme.primary,
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(12),
|
||
),
|
||
),
|
||
child: Text(
|
||
'بعدی',
|
||
style: theme.textTheme.titleMedium?.copyWith(
|
||
color: Colors.white,
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
),
|
||
),
|
||
),
|
||
const SizedBox(width: 16),
|
||
Expanded(
|
||
flex: 2,
|
||
child: OutlinedButton(
|
||
onPressed: _skipOnboarding,
|
||
style: OutlinedButton.styleFrom(
|
||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||
side: BorderSide(
|
||
color: colorScheme.primary.withOpacity(0.3),
|
||
),
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(16),
|
||
),
|
||
),
|
||
child: Padding(
|
||
padding: const EdgeInsets.all(5.0),
|
||
child: Text(
|
||
'صرف نظر کردن',
|
||
style: theme.textTheme.titleMedium?.copyWith(
|
||
color: Colors.black,
|
||
fontSize: 12,
|
||
fontWeight: FontWeight.bold,
|
||
),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|