|
- import 'dart:io';
- import 'package:flutter/material.dart';
- import 'package:intl/intl.dart';
- import 'package:open_file/open_file.dart';
- import 'package:permission_handler/permission_handler.dart';
- import 'package:provider/provider.dart';
- import 'package:qadirneyriz/config/config.dart';
- import 'package:qadirneyriz/global/global_state/global_state.dart';
- import 'package:qadirneyriz/screens/report/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/ExpansionTileCustom.dart';
- import 'package:qadirneyriz/widgets/custom_appbar.dart';
- import 'package:qadirneyriz/widgets/custom_button.dart';
- import 'package:qadirneyriz/widgets/error_widget.dart';
- import 'package:qadirneyriz/widgets/loading_widget.dart';
- import 'package:qadirneyriz/widgets/picker.dart';
- import 'package:qadirneyriz/widgets/today_widget.dart';
- import 'package:flutter_gen/gen_l10n/app_localizations.dart';
-
- class ReportScreen extends StatefulWidget {
- const ReportScreen({super.key});
-
- @override
- State<ReportScreen> createState() => _ReportScreenState();
- }
-
- class _ReportScreenState extends State<ReportScreen> {
- @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 CustomScrollView(
- slivers: <Widget>[
- const CustomAppbar(),
- SliverToBoxAdapter(
- child: TodayWidget(
- formattedDate: setting.userLocalDb.getUser().language == 'en'
- ? dateMiladi
- : dateJalali),
- ),
- SliverFillRemaining(
- child: FiltersItemInReport(),
- )
- ],
- );
- }
- }
-
- class FiltersItemInReport extends StatefulWidget {
- const FiltersItemInReport({
- super.key,
- });
-
- @override
- State<FiltersItemInReport> createState() => _FiltersItemInReportState();
- }
-
- class _FiltersItemInReportState extends State<FiltersItemInReport> {
- ReportState? reportState;
- GlobalState? globalState;
- @override
- void initState() {
- reportState = Provider.of<ReportState>(context, listen: false);
- globalState = Provider.of<GlobalState>(context, listen: false);
- Future.delayed(Duration.zero, () async {
- await globalState!.getAllFiltersItems();
- });
- super.initState();
- }
-
- @override
- Widget build(BuildContext context) {
- List<MeetingsStatus> meetingStatuses = [
- MeetingsStatus(id: 1, title: AppLocalizations.of(context)!.donemeetings),
- MeetingsStatus(
- id: 2, title: AppLocalizations.of(context)!.adjournedmeetings),
- MeetingsStatus(
- id: 3, title: AppLocalizations.of(context)!.canceldmeetings),
- MeetingsStatus(
- id: 4, title: AppLocalizations.of(context)!.meetingswaitingtobeheld),
- ];
- return Consumer2<ReportState, GlobalState>(
- builder: (context, reportState, globalState, child) {
- switch (globalState.allFiltersStatus) {
- case Status.ready:
- return Column(
- children: [
- Expanded(
- child: SingleChildScrollView(
- child: Column(
- children: [
- Column(
- mainAxisSize: MainAxisSize.max,
- children: [
- ExpansionTileCustom(
- title: AppLocalizations.of(context)!.date,
- widgets: <Widget>[
- Row(
- crossAxisAlignment: CrossAxisAlignment.end,
- mainAxisAlignment:
- MainAxisAlignment.spaceBetween,
- children: [
- PickerCustom(
- showDate: reportState.fromDate.isNotEmpty
- ? reportState.fromDate
- : AppLocalizations.of(context)!
- .selectdate, // Show selected date or prompt
- onTap: () {
- showDialog(
- context: context,
- builder: (context) {
- return Dialog(
- child: Tools
- .shamsiDateCalendarWidget(
- context,
- (newDate) {
- String fromDateString =
- '${newDate.year}/${newDate.month}/${newDate.day}';
- reportState.setFromDates(
- fromDateString); // Update the selected date
- },
- ),
- );
- },
- );
- },
- ),
- Text(
- AppLocalizations.of(context)!.to,
- ),
- PickerCustom(
- showDate: reportState.toDate.isNotEmpty
- ? reportState.toDate
- : AppLocalizations.of(context)!
- .selectdate, // Show selected date or prompt
- onTap: () {
- showDialog(
- context: context,
- builder: (context) {
- return Dialog(
- child: Tools
- .shamsiDateCalendarWidget(
- context,
- (newDate) {
- String toDateString =
- '${newDate.year}/${newDate.month}/${newDate.day}';
- reportState.setToDates(
- toDateString); // Update the selected date
- },
- ),
- );
- },
- );
- },
- ),
- ],
- )
- ],
- ),
- ExpansionTileCustom(
- title: AppLocalizations.of(context)!.location,
- widgets: <Widget>[
- ListView.builder(
- primary: false,
- physics: NeverScrollableScrollPhysics(),
- shrinkWrap: true,
- itemCount: globalState.locationsModel!.length,
- itemBuilder:
- (BuildContext context, int index) {
- final items =
- globalState.locationsModel![index];
- return RadioListTile<int>(
- toggleable: true,
- groupValue:
- reportState.selectedLocationId,
- value: items.id ?? -1,
- title: Text(
- items.address ?? '',
- maxLines: 1,
- style: TextStyle(
- fontWeight: FontWeight.w100,
- fontSize: 14),
- overflow: TextOverflow.ellipsis,
- ),
- activeColor: config.ui.secendGreen,
- onChanged: (int? newValue) {
- reportState
- .selectLocation(newValue ?? null);
- },
- );
- },
- ),
- ],
- ),
- if (setting.userLocalDb.getUser().role != 1)
- ExpansionTileCustom(
- title: AppLocalizations.of(context)!
- .meetingmanager,
- widgets: <Widget>[
- ListView.builder(
- primary: false,
- physics: NeverScrollableScrollPhysics(),
- shrinkWrap: true,
- itemCount: globalState
- .meetingsManagerModel!.length,
- itemBuilder:
- (BuildContext context, int index) {
- final items = globalState
- .meetingsManagerModel![index];
- return RadioListTile<int>(
- toggleable: true,
- groupValue:
- reportState.selectedManagersId,
- value: items.id ?? -1,
- title: Text(
- items.name ?? '',
- style: TextStyle(
- fontWeight: FontWeight.w100,
- fontSize: 14),
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- ),
- activeColor: config.ui.secendGreen,
- onChanged: (int? newValue) {
- reportState
- .selectManager(newValue ?? null);
- },
- );
- },
- ),
- ],
- ),
- ExpansionTileCustom(
- title: AppLocalizations.of(context)!.subject,
- widgets: <Widget>[
- ListView.builder(
- primary: false,
- physics: NeverScrollableScrollPhysics(),
- shrinkWrap: true,
- itemCount: globalState.subjectsModel!.length,
- itemBuilder:
- (BuildContext context, int index) {
- final items =
- globalState.subjectsModel![index];
- return RadioListTile<int>(
- toggleable: true,
- groupValue: reportState.selectedSubjectId,
- value: items.id ?? -1,
- title: Text(
- items.subject ?? '',
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- style: TextStyle(
- fontWeight: FontWeight.w100,
- fontSize: 14),
- ),
- activeColor: config.ui.secendGreen,
- onChanged: (int? newValue) {
- reportState
- .selectSubject(newValue ?? null);
- },
- );
- },
- ),
- ],
- ),
- Divider(),
- if (setting.userLocalDb.getUser().role != 1)
- SizedBox(
- height: 300,
- child: ListView.builder(
- physics: NeverScrollableScrollPhysics(),
- shrinkWrap: true,
- primary: false,
- itemCount: meetingStatuses.length,
- itemBuilder:
- (BuildContext context, int index) {
- final items = meetingStatuses[index];
- return RadioListTile<int>(
- toggleable: true,
- groupValue: reportState.selectedStatusId,
- value: items.id,
- title: Text(
- items.title,
- maxLines: 1,
- style: TextStyle(
- fontWeight: FontWeight.w100,
- fontSize: 14),
- overflow: TextOverflow.ellipsis,
- ),
- activeColor: config.ui.secendGreen,
- onChanged: (int? newValue) {
- reportState.selectStatusMeeting(
- newValue ?? null);
- },
- );
- },
- ),
- ),
- Padding(
- padding: const EdgeInsets.symmetric(
- horizontal: 20, vertical: 50),
- child: downloadButton(reportState),
- )
- ],
- ),
- ],
- ),
- ),
- ),
- ],
- );
- case Status.loading:
- return const LoadingWidget();
- case Status.error:
- return CustomErrorWidget(
- onPressed: () async {
- await globalState.getAllFiltersItems(refresh: true);
- },
- );
- default:
- return Container();
- }
- },
- );
- }
-
- CustomButton downloadButton(ReportState state) {
- switch (state.statusDownload) {
- case Status.loading:
- return CustomButton(
- borderRadius: 15,
- hieght: 50,
- text: AppLocalizations.of(context)!.loading,
- width: double.infinity,
- );
-
- default:
- return CustomButton(
- borderRadius: 15,
- hieght: 50,
- text: AppLocalizations.of(context)!.downloadreport,
- width: double.infinity,
- onPressed: () async {
- bool hasPermission = await hasStoragePermission();
- if (!hasPermission) {
- Tools.showCustomSnackBar(context,
- text: 'Permission denied. Please allow storage access.',
- isError: true);
- return;
- }
-
- // Download the file
- await state.downloadReport(
- toDate: reportState!.toDate,
- fromDate: reportState!.fromDate,
- location: reportState!.selectedLocationId,
- subject: reportState!.selectedSubjectId,
- meetingManager: reportState!.selectedManagersId,
- status: reportState!.selectedStatusId);
-
- if (state.statusDownload == Status.ready) {
- await OpenFile.open(state.messageDownload);
- // print(status.message);
- } else {
- Tools.showCustomSnackBar(
- context,
- text: AppLocalizations.of(context)!.error,
- isError: true,
- );
- }
- },
- );
- }
- }
-
- Future<bool> hasStoragePermission() async {
- if (Platform.isAndroid) {
- final status = await Permission.storage.status;
- if (status != PermissionStatus.granted) {
- final result = await Permission.manageExternalStorage.request();
- if (result == PermissionStatus.granted) {
- return true;
- }
- } else {
- return true;
- }
- } else {
- return true;
- }
- return false;
- }
- }
-
- class LineButtomSheet extends StatelessWidget {
- const LineButtomSheet({
- super.key,
- });
-
- @override
- Widget build(BuildContext context) {
- return Container(
- margin: const EdgeInsets.only(top: 8.0),
- width: 30.0,
- height: 3.0,
- decoration: BoxDecoration(
- color: Colors.grey.shade400,
- borderRadius: BorderRadius.circular(24.0),
- ),
- );
- }
- }
-
- class MeetingsStatus {
- int id;
- String title;
- MeetingsStatus({
- required this.id,
- required this.title,
- });
- }
|