// ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:flutter/material.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:qadirneyriz/global/global_state/global_state.dart'; import 'package:qadirneyriz/setting/setting.dart'; import 'package:qadirneyriz/utils/tools/tools.dart'; import 'package:qadirneyriz/widgets/card_meeting.dart'; import 'package:qadirneyriz/widgets/custom_appbar.dart'; import 'package:qadirneyriz/widgets/custom_button.dart'; import 'package:qadirneyriz/widgets/empty_widget.dart'; import 'package:qadirneyriz/widgets/error_widget.dart'; import 'package:qadirneyriz/widgets/today_widget.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:qadirneyriz/config/config.dart'; import 'package:qadirneyriz/screens/home/state.dart'; import 'package:qadirneyriz/utils/enums/status.dart'; import 'package:qadirneyriz/widgets/loading_widget.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @override State createState() => _HomeScreenState(); } class _HomeScreenState extends State { @override void initState() { super.initState(); HomeState homeState = Provider.of(context, listen: false); Future.delayed(Duration.zero, () async { await homeState.getTodayMeetings(); }); } @override Widget build(BuildContext context) { DateTime now = DateTime.now(); String dateMiladi = setting.userLocalDb.getUser().language == 'fa' ? Tools.convertToPersianDigits(DateFormat('yyyy-MM-dd').format(now)) : DateFormat('yyyy-MM-dd').format(now); String dateJalali = Tools.convertToPersianDigits( '${setting.timeNow.day} ${Tools.getMonthName(setting.timeNow.month)} ${setting.timeNow.year}'); return Consumer2( builder: (context, homeState, globalState, child) { switch (homeState.todayMettingsStatus) { case Status.ready: return RefreshIndicator( onRefresh: () async { await homeState.getTodayMeetings(); }, child: CustomScrollView( slivers: [ CustomAppbar(), SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.symmetric( horizontal: 20, vertical: 10), child: Container( decoration: BoxDecoration( color: const Color(0xffF4F9F6), boxShadow: [ BoxShadow( color: config.ui.mainGray.withOpacity(.1), spreadRadius: .1, offset: const Offset(0, 5), blurRadius: 6) ], borderRadius: BorderRadius.circular(25)), width: double.infinity, child: Padding( padding: const EdgeInsets.all(20), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Icon( Icons.edit_outlined, color: config.ui.mainGreen, ), const SizedBox( width: 10, ), Expanded( child: Text( style: const TextStyle(fontSize: 13), homeState.todayMeetingsModel!.note ?? ''), ), ], ), ), ), ), ), SliverToBoxAdapter( child: TodayWidget( formattedDate: setting.userLocalDb.getUser().language == 'en' ? dateMiladi : dateJalali), ), SliverToBoxAdapter( child: SizedBox( height: 170, child: homeState .todayMeetingsModel!.meetings!.isNotEmpty || homeState.todayMeetingsModel!.privateMeetings! .isNotEmpty ? ListView.builder( scrollDirection: Axis.horizontal, shrinkWrap: true, itemCount: homeState .todayMeetingsModel!.meetings!.length + homeState.todayMeetingsModel!.privateMeetings! .length, itemBuilder: (BuildContext context, int index) { // ترکیب دو لیست final meetingsLength = homeState .todayMeetingsModel!.meetings!.length; if (index < meetingsLength) { // آیتم از لیست `meetings` final meeting = homeState .todayMeetingsModel!.meetings![index]; return Padding( padding: const EdgeInsets.only( right: 5, left: 1), child: Stack( children: [ CustomCardMeeting( status: meeting.accepted ?? 0, titel: meeting.subject != null ? meeting.subject!.subject ?? '' : '', fromTime: meeting.azHour ?? '', toTime: meeting.taHour ?? "", location: meeting.location != null ? meeting.location!.address ?? '' : '', date: meeting.dateJalali ?? '', cardId: meeting.id ?? 0, ), Positioned( left: setting.userLocalDb .getUser() .language == 'fa' ? 20 : 280, top: 20, child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.green, ), child: Padding( padding: const EdgeInsets.all(5.0), child: Text( AppLocalizations.of(context)! .meetings, style: TextStyle( fontSize: 12, color: Colors.white), ), ), ), ), ], )); } else { // آیتم از لیست `privateMeetings` final privateMeeting = homeState .todayMeetingsModel! .privateMeetings![index - meetingsLength]; return Padding( padding: const EdgeInsets.only( right: 5, left: 1), child: Stack( children: [ CustomCardMeeting( cardId: privateMeeting.id ?? -1, titel: privateMeeting.subject != null ? privateMeeting .subject!.subject ?? '' : '', location: privateMeeting.location != null ? privateMeeting .location!.address ?? '' : '', status: privateMeeting.accepted ?? 0, fromTime: "${privateMeeting.azHour}", date: privateMeeting.dateJalali ?? '', toTime: privateMeeting.taHour ?? '', ), Positioned( left: setting.userLocalDb .getUser() .language == 'fa' ? 20 : 250, child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: Colors.green), child: Padding( padding: const EdgeInsets.all(5.0), child: Text( AppLocalizations.of(context)! .privatemeeting, style: TextStyle( fontSize: 12, color: Colors.white), ), )), top: 20, ), ], ), ); } }, ) : Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.error_outline, size: 40, color: config.ui.mainGray.withOpacity(.5)), const SizedBox( height: 20, ), Text( AppLocalizations.of(context)! .nomeetingfortoday, style: TextStyle( color: config.ui.mainGray.withOpacity(.5)), ), ], ), ), ), ), SliverPadding( padding: const EdgeInsets.symmetric( vertical: 30, horizontal: 10), sliver: SliverToBoxAdapter( child: StaggeredGrid.count( crossAxisCount: 4, mainAxisSpacing: 4, crossAxisSpacing: 4, children: [ StaggeredGridTile.count( crossAxisCellCount: 2, mainAxisCellCount: 1, child: ItemInGrid( icon: Icons.assessment, backColor: const Color(0xff03C85F), text: AppLocalizations.of(context)!.reports, onTap: () { context.pushNamed('navigate', pathParameters: {'tab': '3'}); }, ), ), StaggeredGridTile.count( crossAxisCellCount: 2, mainAxisCellCount: 2, child: ItemInGrid( icon: Icons.people, backColor: const Color(0xff04A54F), text: AppLocalizations.of(context)!.meetings, onTap: () { context.pushNamed('navigate', pathParameters: {'tab': '1'}); }, ), ), StaggeredGridTile.count( crossAxisCellCount: 2, mainAxisCellCount: 2, child: ItemInGrid( icon: Icons.calendar_today, backColor: const Color(0xff37A068), text: AppLocalizations.of(context)!.events, onTap: () { context.pushNamed('navigate', pathParameters: {'tab': '2'}); }, ), ), StaggeredGridTile.count( crossAxisCellCount: 2, mainAxisCellCount: 1, child: ItemInGrid( icon: Icons.exit_to_app, backColor: const Color(0xff00843D), text: AppLocalizations.of(context)!.exit, onTap: () { showModalBottomSheet( context: context, builder: (context) { return DraggableScrollableSheet( initialChildSize: .5, expand: false, snap: false, builder: (context, scrollController) { return Column( mainAxisSize: MainAxisSize.min, children: [ Padding( padding: const EdgeInsets.only( top: 8, bottom: 30), child: Container( width: 60, height: 4, decoration: BoxDecoration( color: Colors.black .withOpacity(.4), borderRadius: BorderRadius.circular( 10)), ), ), Text( AppLocalizations.of(context)! .exit, style: TextStyle( color: config.ui.mainGreen, fontSize: 18, fontWeight: FontWeight.w500), ), const SizedBox( height: 15, ), Text( AppLocalizations.of(context)! .areusurelog, style: TextStyle( color: Colors.black, fontSize: 14, ), ), const SizedBox( height: 30, ), logOutButton(), const SizedBox( height: 40, ) ], ); }, ); }, ); }, ), ), ], ), ), ), ], ), ); case Status.loading: return const LoadingWidget(); case Status.error: return CustomErrorWidget( onPressed: () async { await homeState.getTodayMeetings(refresh: true); }, ); case Status.empty: return EmptyStateWidget(); default: return Container(); } }, ); } Consumer logOutButton() { return Consumer( builder: (context, value, child) { switch (value.statusLogOut) { case Status.loading: return const LoadingWidget(); default: return Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ CustomButton( fontSize: 13, color: config.ui.mainGreen, onPressed: () { Navigator.pop(context); }, hieght: 50, // width: 150, text: AppLocalizations.of(context)!.no, ), const SizedBox( width: 10, ), CustomButton( fontSize: 13, hieght: 50, // width: 150, text: AppLocalizations.of(context)!.logout, textColor: Colors.black, color: const Color(0xffD0D5ED), onPressed: () async { final status = await value.logOut(); if (status == Status.error) { Tools.showCustomSnackBar(context, text: value.messageLogOut ?? AppLocalizations.of(context)!.error, isError: true); } else if (status == Status.ready) { final logOut = await setting.userLocalDb.logOut(); if (logOut) { context.goNamed('login'); Tools.showCustomSnackBar(context, text: value.messageLogOut ?? 'Done successfully', isError: false); } else { Tools.showCustomSnackBar(context, text: value.messageLogOut ?? AppLocalizations.of(context)!.error, isError: true); } } }, ), ], ); } }, ); } } class ItemInGrid extends StatelessWidget { final IconData icon; final Color backColor; final String text; final void Function() onTap; const ItemInGrid( {super.key, required this.icon, required this.backColor, required this.text, required this.onTap}); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(4.0), child: GestureDetector( onTap: onTap, child: Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(20), color: backColor, boxShadow: [ BoxShadow( color: config.ui.mainGray.withOpacity(.5), spreadRadius: .1, offset: const Offset(0, 2), blurRadius: 6) ], ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( icon, size: 40, color: Colors.white, ), const SizedBox( height: 8, ), Text( text, style: const TextStyle(color: Colors.white, fontSize: 16), ), ], ), ), ), ); } }