2025-07-26 15:47:22 +03:30
|
|
|
|
import 'package:flutter/cupertino.dart';
|
|
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
|
|
import 'package:rasadyar_core/core.dart';
|
|
|
|
|
|
import 'package:rasadyar_inspection/presentation/widget/custom_chips.dart';
|
|
|
|
|
|
|
|
|
|
|
|
import 'logic.dart';
|
|
|
|
|
|
|
|
|
|
|
|
class StatisticsPage extends GetView<StatisticsLogic> {
|
|
|
|
|
|
const StatisticsPage({super.key});
|
|
|
|
|
|
|
|
|
|
|
|
@override
|
|
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
|
|
return Padding(
|
|
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
|
|
child: Column(
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Padding(
|
|
|
|
|
|
padding: EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
|
|
|
|
|
child: Row(
|
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
|
|
|
|
spacing: 10,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Expanded(
|
|
|
|
|
|
child: Container(
|
|
|
|
|
|
height: 32.h,
|
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
|
border: Border.all(color: AppColor.blueNormal, width: 1),
|
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
|
),
|
|
|
|
|
|
padding: EdgeInsets.symmetric(horizontal: 11.w, vertical: 4.h),
|
|
|
|
|
|
child: Row(
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Assets.vec.calendarSvg.svg(
|
|
|
|
|
|
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
|
|
|
|
|
|
),
|
|
|
|
|
|
SizedBox(width: 4.w),
|
|
|
|
|
|
Text('از', style: AppFonts.yekan16.copyWith(color: AppColor.blueNormal)),
|
|
|
|
|
|
SizedBox(width: 22.w),
|
|
|
|
|
|
|
|
|
|
|
|
Text(
|
|
|
|
|
|
'1404/12/12',
|
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
|
style: AppFonts.yekan16.copyWith(color: AppColor.lightGreyNormalActive),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
Expanded(
|
|
|
|
|
|
child: Container(
|
|
|
|
|
|
height: 32.h,
|
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
|
border: Border.all(color: AppColor.blueNormal, width: 1),
|
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
|
),
|
|
|
|
|
|
padding: EdgeInsets.symmetric(horizontal: 11.w, vertical: 4.h),
|
|
|
|
|
|
child: Row(
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Assets.vec.calendarSvg.svg(
|
|
|
|
|
|
colorFilter: ColorFilter.mode(AppColor.blueNormal, BlendMode.srcIn),
|
|
|
|
|
|
),
|
|
|
|
|
|
SizedBox(width: 4.w),
|
|
|
|
|
|
Text('تا', style: AppFonts.yekan16.copyWith(color: AppColor.blueNormal)),
|
|
|
|
|
|
SizedBox(width: 22.w),
|
|
|
|
|
|
|
|
|
|
|
|
Text(
|
|
|
|
|
|
'1404/12/12',
|
|
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
|
style: AppFonts.yekan16.copyWith(color: AppColor.lightGreyNormalActive),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
|
|
|
|
SizedBox(height: 16.h),
|
|
|
|
|
|
|
|
|
|
|
|
Container(
|
|
|
|
|
|
height: 80.h,
|
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
|
border: Border.all(color: AppColor.lightGreyNormalHover, width: 1),
|
|
|
|
|
|
),
|
|
|
|
|
|
child: Padding(
|
|
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
|
|
child: Column(
|
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
|
spacing: 8,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Row(
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Text(
|
|
|
|
|
|
'فیلتر تراکنش ها',
|
|
|
|
|
|
textAlign: TextAlign.right,
|
|
|
|
|
|
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
Expanded(
|
|
|
|
|
|
child: ListView.separated(
|
|
|
|
|
|
shrinkWrap: true,
|
|
|
|
|
|
physics: const BouncingScrollPhysics(),
|
|
|
|
|
|
scrollDirection: Axis.horizontal,
|
|
|
|
|
|
itemBuilder: (context, index) => ObxValue((selectedIndex) {
|
|
|
|
|
|
return customChip(
|
|
|
|
|
|
title: controller.transactionFilters[index],
|
|
|
|
|
|
isSelected: selectedIndex.contains(index),
|
|
|
|
|
|
index: index,
|
|
|
|
|
|
onTap: (data) => controller.onTransactionFilterSelected(data),
|
|
|
|
|
|
);
|
|
|
|
|
|
}, controller.transactionFiltersSelected),
|
|
|
|
|
|
separatorBuilder: (context, index) => SizedBox(width: 8),
|
|
|
|
|
|
itemCount: controller.transactionFilters.length,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
SizedBox(height: 8.h),
|
|
|
|
|
|
Container(
|
|
|
|
|
|
height: 80.h,
|
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
|
border: Border.all(color: AppColor.lightGreyNormalHover, width: 1),
|
|
|
|
|
|
),
|
|
|
|
|
|
child: Padding(
|
|
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
|
|
child: Column(
|
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
|
|
|
spacing: 8,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Row(
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Text(
|
|
|
|
|
|
'فیلتر شهرستان',
|
|
|
|
|
|
textAlign: TextAlign.right,
|
|
|
|
|
|
style: AppFonts.yekan14.copyWith(color: AppColor.blueNormal),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
Expanded(child: _provinceDropdownWidget()),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
SizedBox(height: 8.h),
|
|
|
|
|
|
Container(
|
2025-07-27 09:26:48 +03:30
|
|
|
|
|
2025-07-26 15:47:22 +03:30
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
|
border: Border.all(color: AppColor.lightGreyNormalHover, width: 1),
|
|
|
|
|
|
),
|
2025-07-27 09:26:48 +03:30
|
|
|
|
padding: EdgeInsets.all(8),
|
|
|
|
|
|
child: Column(
|
|
|
|
|
|
spacing: 8,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Row(
|
|
|
|
|
|
spacing: 8,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Expanded(
|
|
|
|
|
|
child: ObxValue(
|
|
|
|
|
|
(data) => _informationLabelCard(
|
|
|
|
|
|
title: 'تعداد تراکنش ها',
|
|
|
|
|
|
titleColor: AppColor.blueNormal,
|
|
|
|
|
|
isLoading: data.value == null,
|
2025-09-16 15:47:35 +03:30
|
|
|
|
description: 25369654.separatedByCommaFa,
|
2025-07-27 09:26:48 +03:30
|
|
|
|
iconPath: Assets.vec.cubeScanSvg.path,
|
|
|
|
|
|
bgDescriptionColor: Colors.white,
|
|
|
|
|
|
gradient: LinearGradient(
|
|
|
|
|
|
begin: Alignment.topCenter,
|
|
|
|
|
|
end: Alignment.bottomCenter,
|
|
|
|
|
|
colors: [AppColor.blueLight, Colors.white],
|
|
|
|
|
|
),
|
2025-07-26 15:47:22 +03:30
|
|
|
|
),
|
2025-07-27 09:26:48 +03:30
|
|
|
|
controller.s1,
|
2025-07-26 15:47:22 +03:30
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
|
2025-07-27 09:26:48 +03:30
|
|
|
|
Expanded(
|
|
|
|
|
|
child: ObxValue((data) {
|
|
|
|
|
|
return _informationLabelCard(
|
|
|
|
|
|
title: 'جمع تراکنش ها',
|
|
|
|
|
|
isLoading: data.value == null,
|
2025-09-16 15:47:35 +03:30
|
|
|
|
description: data.value.separatedByCommaFa ?? '0',
|
2025-07-27 09:26:48 +03:30
|
|
|
|
unit: 'ريال',
|
|
|
|
|
|
iconPath: Assets.vec.cubeCardSvg.path,
|
|
|
|
|
|
bgDescriptionColor: Colors.white,
|
|
|
|
|
|
titleColor: AppColor.greenDarkHover,
|
|
|
|
|
|
gradient: LinearGradient(
|
|
|
|
|
|
begin: Alignment.topCenter,
|
|
|
|
|
|
end: Alignment.bottomCenter,
|
|
|
|
|
|
colors: [AppColor.greenLightHover, Colors.white],
|
|
|
|
|
|
),
|
|
|
|
|
|
);
|
|
|
|
|
|
}, controller.s2),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
Row(
|
|
|
|
|
|
spacing: 16,
|
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
RElevated(
|
|
|
|
|
|
width: 160.w,
|
|
|
|
|
|
height: 40.h,
|
|
|
|
|
|
backgroundColor: AppColor.greenNormal,
|
|
|
|
|
|
onPressed: () {},
|
|
|
|
|
|
child: Row(
|
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Assets.vec.excelDownloadSvg.svg(
|
|
|
|
|
|
width: 24.w,
|
|
|
|
|
|
height: 24.h,
|
|
|
|
|
|
colorFilter: const ColorFilter.mode(Colors.white, BlendMode.srcIn),
|
|
|
|
|
|
),
|
|
|
|
|
|
SizedBox(width: 4.w),
|
|
|
|
|
|
Text('EXCEL', style: AppFonts.yekan14.copyWith(color: Colors.white)),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
ROutlinedElevated(
|
|
|
|
|
|
width: 160.w,
|
|
|
|
|
|
height: 40.h,
|
|
|
|
|
|
borderColor: AppColor.error,
|
|
|
|
|
|
child: Row(
|
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Assets.vec.pdfDownloadSvg.svg(
|
|
|
|
|
|
width: 24.w,
|
|
|
|
|
|
height: 24.h,
|
|
|
|
|
|
colorFilter: const ColorFilter.mode(AppColor.error, BlendMode.srcIn),
|
|
|
|
|
|
),
|
|
|
|
|
|
SizedBox(width: 4.w),
|
|
|
|
|
|
Text('PDF', style: AppFonts.yekan14.copyWith(color: AppColor.error)),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
2025-07-26 15:47:22 +03:30
|
|
|
|
),
|
|
|
|
|
|
),
|
2025-07-27 09:26:48 +03:30
|
|
|
|
SizedBox(height: 8.h),
|
2025-07-26 15:47:22 +03:30
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Widget _provinceDropdownWidget() {
|
|
|
|
|
|
return ObxValue((data) {
|
|
|
|
|
|
return OverlayDropdownWidget<String>(
|
|
|
|
|
|
items: data,
|
|
|
|
|
|
onChanged: (value) {
|
|
|
|
|
|
controller.iranProvincesSelected.value = value;
|
|
|
|
|
|
controller.iranProvincesSelected.refresh();
|
|
|
|
|
|
},
|
|
|
|
|
|
selectedItem: controller.iranProvincesSelected.value,
|
|
|
|
|
|
itemBuilder: (item) => Text(
|
|
|
|
|
|
item ?? 'بدون نام',
|
|
|
|
|
|
style: AppFonts.yekan14.copyWith(color: AppColor.lightGreyDarker),
|
|
|
|
|
|
),
|
|
|
|
|
|
labelBuilder: (item) =>
|
|
|
|
|
|
Text('انتخاب استان', style: AppFonts.yekan14.copyWith(color: AppColor.textColorLight)),
|
|
|
|
|
|
);
|
|
|
|
|
|
}, controller.iranProvinces);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Container _informationLabelCard({
|
|
|
|
|
|
required String title,
|
|
|
|
|
|
required String description,
|
|
|
|
|
|
required String iconPath,
|
|
|
|
|
|
required Color bgDescriptionColor,
|
|
|
|
|
|
String? unit,
|
|
|
|
|
|
bool isLoading = false,
|
|
|
|
|
|
Color? iconColor,
|
|
|
|
|
|
Color? titleColor,
|
|
|
|
|
|
Color? bgLabelColor,
|
|
|
|
|
|
LinearGradient? gradient,
|
|
|
|
|
|
}) {
|
|
|
|
|
|
return Container(
|
|
|
|
|
|
height: 82.h,
|
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
|
borderRadius: BorderRadius.circular(8),
|
|
|
|
|
|
border: Border.all(color: AppColor.lightGreyNormalHover, width: 1),
|
|
|
|
|
|
),
|
|
|
|
|
|
clipBehavior: Clip.hardEdge,
|
|
|
|
|
|
child: Row(
|
|
|
|
|
|
children: [
|
|
|
|
|
|
// Left side with icon and title
|
|
|
|
|
|
Expanded(
|
2025-07-27 09:26:48 +03:30
|
|
|
|
flex: 91,
|
2025-07-26 15:47:22 +03:30
|
|
|
|
child: Container(
|
|
|
|
|
|
height: 82.h,
|
2025-07-27 09:26:48 +03:30
|
|
|
|
padding: EdgeInsets.all(4),
|
2025-07-26 15:47:22 +03:30
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
|
color: gradient == null ? bgLabelColor : null,
|
|
|
|
|
|
borderRadius: BorderRadius.only(
|
|
|
|
|
|
topRight: Radius.circular(8),
|
|
|
|
|
|
bottomRight: Radius.circular(8),
|
|
|
|
|
|
),
|
|
|
|
|
|
gradient: gradient,
|
|
|
|
|
|
),
|
|
|
|
|
|
child: Column(
|
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
2025-07-27 09:26:48 +03:30
|
|
|
|
spacing: 8,
|
2025-07-26 15:47:22 +03:30
|
|
|
|
children: [
|
|
|
|
|
|
SvgGenImage.vec(iconPath).svg(
|
|
|
|
|
|
width: 24,
|
|
|
|
|
|
height: 24,
|
|
|
|
|
|
colorFilter: iconColor != null
|
|
|
|
|
|
? ColorFilter.mode(iconColor, BlendMode.srcIn)
|
|
|
|
|
|
: null,
|
|
|
|
|
|
),
|
|
|
|
|
|
Text(
|
|
|
|
|
|
title,
|
|
|
|
|
|
textAlign: TextAlign.right,
|
|
|
|
|
|
style: AppFonts.yekan10.copyWith(
|
|
|
|
|
|
color: titleColor ?? AppColor.mediumGreyDarkActive,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
// Right side with description and unit
|
|
|
|
|
|
Expanded(
|
2025-07-27 09:26:48 +03:30
|
|
|
|
flex: 109,
|
2025-07-26 15:47:22 +03:30
|
|
|
|
child: Container(
|
|
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
|
|
color: bgDescriptionColor,
|
|
|
|
|
|
borderRadius: BorderRadius.only(
|
|
|
|
|
|
topLeft: Radius.circular(8),
|
|
|
|
|
|
bottomLeft: Radius.circular(8),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
child: isLoading
|
|
|
|
|
|
? Center(child: CupertinoActivityIndicator())
|
|
|
|
|
|
: Column(
|
|
|
|
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
|
|
|
|
spacing: 4,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
Text(
|
|
|
|
|
|
description,
|
2025-07-27 09:26:48 +03:30
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
|
style: AppFonts.yekan14.copyWith(color: AppColor.mediumGreyDarkActive),
|
2025-07-26 15:47:22 +03:30
|
|
|
|
),
|
|
|
|
|
|
Visibility(
|
|
|
|
|
|
visible: unit != null,
|
|
|
|
|
|
child: Text(
|
2025-07-27 09:26:48 +03:30
|
|
|
|
unit ?? '',
|
2025-07-26 15:47:22 +03:30
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
|
|
style: AppFonts.yekan12.copyWith(color: AppColor.mediumGreyDarkActive),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
],
|
|
|
|
|
|
),
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|