didvan-app/lib/views/onboarding/onboarding_page.dart

306 lines
13 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/2.png',
title: 'رصدخانه استراتژیک',
description:
'ارائه گزارش‌های تحلیلی از محیط‌های دور و نزدیک صنعت و آخرین اخبار مرتبط با محیط رقابتی، ایجاد دید ۳۶۰ درجه محیطی در قالب ماهنامه‌های تحلیلی، رادارهای روند، ریسک، استارت‌آپ، تکنولوژی، شناسایی فرصت‌ها و تهدیدها و سامانه هم اندیشی سها.',
),
OnboardingEntity(
imagePath: 'lib/assets/images/onboarding/4.png',
title: 'نبض صنعت',
description:
'ارائه داده‌های دقیق و به‌روز از کل زنجیره صنعت فولاد از مواد اولیه تا محصولات نهایی، شاخص‌های کلان اقتصادی، بازار سرمایه و دیگر اطلاعات لازم به منظور تصمیم‌گیری آگاهانه، کاهش ریسک و ارتقای عملکرد مدیران.',
),
OnboardingEntity(
imagePath: 'lib/assets/images/onboarding/3.png',
title: 'استودیو آینده',
description:
'ارائه مفاهیم آینده‌گرا، تحلیل روندها، تحلیل صنعت و یا هر نوع اطلاعات مورد نیاز برای تصمیم‌گیری مدیران ارشد در قالب ویدیوکست، پادکست و اینفوگرافی.',
),
OnboardingEntity(
imagePath: 'lib/assets/images/onboarding/1.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: 50,
height: 50,
child: Stack(
alignment: Alignment.center,
children: [
CustomPaint(
size: const Size(50, 50),
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: 50,
height: 35,
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,
),
),
),
),
),
],
),
),
const SizedBox(
height: 10,
),
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: 14),
),
],
),
),
),
],
),
);
},
),
),
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: 30,
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,
),
),
),
),
),
],
),
],
),
),
],
),
),
);
}
}