// ignore_for_file: public_member_api_docs, sort_constructors_first import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:qadirneyriz/config/config.dart'; import 'package:qadirneyriz/screens/meeting/diolog_meetings_filters.dart'; import 'package:qadirneyriz/screens/meeting/state.dart'; import 'package:qadirneyriz/setting/setting.dart'; import 'package:qadirneyriz/utils/enums/status.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/empty_widget.dart'; import 'package:qadirneyriz/widgets/error_widget.dart'; import 'package:qadirneyriz/widgets/icon_button.dart'; import 'package:qadirneyriz/widgets/loading_widget.dart'; import 'package:qadirneyriz/widgets/today_widget.dart'; class MeetingsScreen extends StatefulWidget { const MeetingsScreen({super.key}); @override State createState() => _MeetingsScreenState(); } class _MeetingsScreenState extends State { late ScrollController _scrollController; late MeetingsState meetingsState; @override void initState() { _scrollController = ScrollController(); _scrollController.addListener(_scrollListener); meetingsState = Provider.of(context, listen: false); Future.delayed(Duration.zero, () async { await meetingsState.getMeetings(); meetingsState.clearFilters(); }); super.initState(); } @override void dispose() { _scrollController.dispose(); super.dispose(); } _scrollListener() async { if (_scrollController.offset >= _scrollController.position.maxScrollExtent && !_scrollController.position.outOfRange) { if (!meetingsState.pageEndedMeetings) { await meetingsState.nextPageMeetings( toDate: meetingsState.toDate, fromDate: meetingsState.fromDate, location: meetingsState.selectedLocationId, subject: meetingsState.selectedSubjectId, meetingManager: meetingsState.selectedManagersId, meetingStatus: meetingsState.selectedStatusId); } } } @override Widget build(BuildContext context) { DateTime now = DateTime.now(); String dateMiladi = DateFormat('yyyy-MM-dd').format(now); String dateJalali = '${setting.timeNow.day} ${Tools.getMonthName(setting.timeNow.month)} ${setting.timeNow.year}'; // فرمت کردن تاریخ return Consumer( builder: (context, value, child) { return RefreshIndicator( onRefresh: () async { await meetingsState.getMeetings(); }, child: CustomScrollView( physics: AlwaysScrollableScrollPhysics(), controller: _scrollController, slivers: [ const CustomAppbar(), SliverToBoxAdapter( child: TodayWidget( formattedDate: setting.userLocalDb.getUser().language == 'en' ? dateMiladi : dateJalali), ), SliverToBoxAdapter( child: Padding( padding: const EdgeInsets.symmetric(vertical: 30, horizontal: 15), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( style: const TextStyle(fontSize: 14), AppLocalizations.of(context)!.meetings, ), IconButtonCustom( iconColor: value.hasActiveFilters() ? Colors.white : config.ui.secendGreen, backColor: value.hasActiveFilters() ? config.ui.secendGreen : Colors.white, icon: FontAwesomeIcons.sliders, onTap: () { showModalBottomSheet( isScrollControlled: true, useSafeArea: true, context: context, builder: (context) { return DiologMeetingsFilters(); }, ); }, ) ], ), ), ), meetingsList(value), (value.paginationMeetings == Status.ready || value.paginationMeetings == Status.empty) ? const SliverToBoxAdapter() : const SliverToBoxAdapter( child: Center( child: LoadingWidget( size: 10, ), ), ) ], ), ); }, ); } Widget meetingsList(MeetingsState state) { switch (state.statusMeetings) { case Status.ready: return SliverList.builder( itemBuilder: (context, index) { final userRole = setting.userLocalDb.getUser().role; final items = state.meetingsModel!.data![index]; return Padding( padding: const EdgeInsets.all(8.0), child: CustomCardMeeting( status: items.accepted ?? 0, titel: items.subject != null ? items.subject!.subject ?? '' : '', fromTime: items.azHour ?? '', toTime: items.taHour ?? "", location: items.location != null ? items.location!.address ?? '' : '', date: items.dateJalali ?? '', cardId: items.id ?? 0, onSelectedMoreButton: (value) async { switch (value) { case 'edit': await context.pushNamed('meetingedit', pathParameters: {'id': items.id.toString()}); meetingsState.getMeetings(); case 'confirm': acceptMeeting(state, context, items.id ?? -1); case 'cancel': cancelMeeting(state, context, items.id ?? -1); case 'report': if (userRole == 1 && items.description != null) { await context.pushNamed( 'meetinsammary', extra: items, // `items` should be a Datum instance ); await meetingsState.getMeetings(); } else if (userRole == 1 && items.description == null) { Tools.showCustomSnackBar( text: AppLocalizations.of(context)!.thereisnosummary, isError: true, context, ); } else { await context.pushNamed( 'meetinsammary', extra: items, // `items` should be a Datum instance ); await meetingsState.getMeetings(); } default: } }, itemBuilderMoreButton: (context) => [ if (userRole == 0 || userRole == 2) PopupMenuItem( value: 'edit', child: Row( children: [ Icon( Icons.edit, color: Colors.green, size: 17, ), SizedBox(width: 8), Text( AppLocalizations.of(context)!.editmeeting, style: TextStyle(fontSize: 12), ), ], ), ), if ((userRole == 0 || userRole == 2) && items.accepted == 0) PopupMenuItem( enabled: state.statusAcceptMeeting != Status.loading, value: 'confirm', child: Row( children: [ Icon( Icons.check_circle, color: Colors.green, size: 17, ), SizedBox(width: 8), Text( AppLocalizations.of(context)!.acceptmeeting, style: TextStyle(fontSize: 12), ), ], ), ), if ((userRole == 0 || userRole == 2) && items.accepted == 0) PopupMenuItem( enabled: state.statusCancelMeeting != Status.loading, value: 'cancel', child: Row( children: [ Icon( Icons.cancel, color: Colors.green, size: 17, ), SizedBox(width: 8), Text( AppLocalizations.of(context)!.cancelmeeting, style: TextStyle(fontSize: 12), ), ], ), ), PopupMenuItem( value: 'report', child: Row( children: [ Icon( Icons.receipt_long, color: Colors.green, size: 17, ), SizedBox(width: 8), Text( AppLocalizations.of(context)!.meetingsummary, style: TextStyle(fontSize: 12), ), ], ), ), ]), ); }, itemCount: state.meetingsModel!.data!.length, ); case Status.loading: return SliverFillRemaining(child: const LoadingWidget()); case Status.error: return SliverFillRemaining( child: CustomErrorWidget( onPressed: () async { await state.getMeetings(refresh: true); }, ), ); case Status.empty: return SliverFillRemaining(child: EmptyStateWidget()); default: return Container(); } } void cancelMeeting( MeetingsState state, BuildContext context, int cardId) async { final status = await state.cancelMeeting(id: cardId); if (status == Status.ready) { Tools.showCustomSnackBar( text: AppLocalizations.of(context)!.meetingcanceled, isError: false, context, ); await meetingsState.getMeetings(); } else { Tools.showCustomSnackBar( text: AppLocalizations.of(context)!.error, isError: true, context, ); } } void acceptMeeting( MeetingsState state, BuildContext context, int cardId) async { final status = await state.acceptMeeting(id: cardId); if (status == Status.ready) { Tools.showCustomSnackBar( text: AppLocalizations.of(context)!.meetingaccepted, isError: false, context, ); await meetingsState.getMeetings(); } else { Tools.showCustomSnackBar( text: AppLocalizations.of(context)!.error, isError: true, context, ); } } }