Files
rasadyar_application/packages/chicken/lib/presentation/pages/home/view.dart

618 lines
22 KiB
Dart
Raw Normal View History

2025-06-15 09:48:52 +03:30
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/data/models/response/inventory/inventory_model.dart';
import 'package:rasadyar_chicken/data/models/response/kill_house_distribution_info/kill_house_distribution_info.dart';
2025-06-30 09:11:33 +03:30
import 'package:rasadyar_chicken/presentation/widget/app_bar.dart';
2025-07-16 11:47:51 +03:30
import 'package:rasadyar_chicken/presentation/widget/widely_used/view.dart';
2025-06-15 09:48:52 +03:30
import 'package:rasadyar_core/core.dart';
import 'logic.dart';
class HomePage extends GetView<HomeLogic> {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColor.bgLight,
2025-06-30 09:33:14 +03:30
appBar: chickenAppBar(hasBack: false, hasFilter: false, hasSearch: false),
2025-06-15 09:48:52 +03:30
body: Column(
spacing: 8,
children: [
2025-06-30 09:28:45 +03:30
InkWell(
2025-06-30 09:33:14 +03:30
onTap: () {
controller.isExpanded.value = !controller.isExpanded.value;
},
child: Card(
margin: EdgeInsetsGeometry.all(6),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(width: 0.50, color: const Color(0xFFA9A9A9)),
),
2025-06-30 09:28:45 +03:30
2025-06-30 09:33:14 +03:30
child: ObxValue((data) {
return AnimatedSize(
duration: Duration(milliseconds: 300),
child: data.value
? Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
2025-06-30 09:28:45 +03:30
children: [
2025-06-30 09:33:14 +03:30
Row(
spacing: 8,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 40,
height: 40,
decoration: ShapeDecoration(
image: DecorationImage(
image: AssetImage(Assets.images.chicken.path),
fit: BoxFit.cover,
),
shape: RoundedRectangleBorder(
2025-07-08 16:20:55 +03:30
side: BorderSide(
width: 0.25,
color: const Color(0xFFB0B0B0),
),
2025-06-30 09:33:14 +03:30
borderRadius: BorderRadius.circular(4),
),
),
2025-06-30 09:28:45 +03:30
),
2025-06-30 09:33:14 +03:30
Text(
'مرغ گرم',
textAlign: TextAlign.right,
2025-07-08 16:20:55 +03:30
style: AppFonts.yekan16.copyWith(
color: AppColor.darkGreyDarkActive,
),
2025-06-30 09:33:14 +03:30
),
Spacer(),
AnimatedRotation(
turns: 180,
duration: Duration(milliseconds: 3000),
child: Icon(CupertinoIcons.chevron_up, size: 18),
),
],
2025-06-30 09:28:45 +03:30
),
2025-06-30 09:33:14 +03:30
SizedBox(height: 8),
_todayShipmentWidget(),
2025-06-15 09:48:52 +03:30
2025-06-30 09:33:14 +03:30
_inventoryWidget(),
2025-06-15 09:48:52 +03:30
2025-06-30 09:33:14 +03:30
Row(
2025-07-08 16:20:55 +03:30
children: [
Text(
'اطلاعات بارها',
textAlign: TextAlign.right,
style: AppFonts.yekan16,
),
],
2025-06-30 09:33:14 +03:30
),
2025-06-15 09:48:52 +03:30
2025-06-30 09:33:14 +03:30
_informationShipment(),
2025-06-15 09:48:52 +03:30
2025-06-30 09:33:14 +03:30
Row(
2025-07-08 16:20:55 +03:30
children: [
Text(
'اطلاعات توزیع',
textAlign: TextAlign.right,
style: AppFonts.yekan16,
),
],
2025-06-30 09:33:14 +03:30
),
2025-06-15 09:48:52 +03:30
2025-06-30 09:33:14 +03:30
distributionInformationWidget(),
],
),
)
: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.min,
2025-06-30 09:28:45 +03:30
children: [
2025-06-30 09:33:14 +03:30
Row(
spacing: 8,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Container(
width: 40,
height: 40,
decoration: ShapeDecoration(
image: DecorationImage(
image: AssetImage(Assets.images.chicken.path),
fit: BoxFit.cover,
),
shape: RoundedRectangleBorder(
2025-07-08 16:20:55 +03:30
side: BorderSide(
width: 0.25,
color: const Color(0xFFB0B0B0),
),
2025-06-30 09:33:14 +03:30
borderRadius: BorderRadius.circular(4),
),
),
2025-06-30 09:28:45 +03:30
),
2025-06-30 09:33:14 +03:30
Text(
'مرغ گرم',
textAlign: TextAlign.right,
2025-07-08 16:20:55 +03:30
style: AppFonts.yekan16.copyWith(
color: AppColor.darkGreyDarkActive,
),
2025-06-30 09:33:14 +03:30
),
Spacer(),
Icon(CupertinoIcons.chevron_down, size: 18),
],
2025-06-30 09:28:45 +03:30
),
2025-06-30 16:18:12 +03:30
_todayShipmentWidget(),
_inventoryWidget(),
2025-06-30 09:28:45 +03:30
],
),
2025-06-30 09:33:14 +03:30
),
);
}, controller.isExpanded),
),
),
2025-06-15 09:48:52 +03:30
2025-07-16 11:47:51 +03:30
WidelyUsedWidget(),
2025-06-15 09:48:52 +03:30
],
),
);
}
2025-06-15 17:16:04 +03:30
Widget distributionInformationWidget() {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 8, 0, 13),
child: ObxValue((data) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 8,
children: [
Expanded(
child: _informationIconCard(
title: 'توزیع داخل استان',
isLoading: data.value == null,
2025-06-22 16:51:22 +03:30
description: data.value?.freeSalesWeight.separatedByComma ?? '0',
2025-06-15 17:16:04 +03:30
iconPath: Assets.vec.truckSvg.path,
iconColor: const Color.fromRGBO(85, 97, 93, 1),
bgDescriptionColor: const Color(0xFFE6FAF5),
bgLabelColor: const Color(0xFFB0EFDF),
2025-06-15 09:48:52 +03:30
),
2025-06-15 17:16:04 +03:30
),
Expanded(
child: _informationIconCard(
title: 'توزیع خارج استان',
isLoading: data.value == null,
2025-06-22 16:51:22 +03:30
description: data.value?.stewardAllocationsWeight.separatedByComma ?? '0',
2025-06-15 17:16:04 +03:30
iconPath: Assets.vec.truckFastSvg.path,
iconColor: Color(0xFF647379),
bgDescriptionColor: const Color(0xFFEAEFFF),
bgLabelColor: const Color(0xFFD4DEFF),
2025-06-15 09:48:52 +03:30
),
),
2025-06-15 17:16:04 +03:30
Expanded(
child: _informationIconCard(
title: 'قطعه بندی',
description: '2،225،256',
iconPath: Assets.vec.convertCubeSvg.path,
iconColor: const Color(0xFF6F6164),
bgDescriptionColor: const Color(0xFFEDDCE0),
bgLabelColor: const Color(0xFFE0BCC5),
),
),
],
);
}, controller.killHouseDistributionInfo),
);
}
Widget _informationShipment() {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 8, 0, 13),
child: ObxValue((data) {
return Row(
spacing: 8,
children: [
Expanded(
child: _informationLabelCard(
title: 'داخل استان',
isLoading: data.value == null,
description: data.value != null
? ((data.value?.provinceGovernmentalCarcassesWeight ?? 0) +
2025-06-30 09:33:14 +03:30
(data.value?.provinceFreeCarcassesWeight ?? 0))
.separatedByComma
2025-06-15 17:16:04 +03:30
: '0',
iconPath: Assets.vec.a3dCubeSquareSvg.path,
iconColor: const Color(0xFF6C5D60),
bgDescriptionColor: const Color(0xFFEDDCE0),
bgLabelColor: const Color(0xFFDDC0C7),
),
),
Expanded(
child: _informationLabelCard(
title: 'خارج استان',
isLoading: data.value == null,
2025-06-22 16:51:22 +03:30
description: data.value?.freeBuyingCarcassesWeight.separatedByComma ?? '0',
2025-06-15 17:16:04 +03:30
iconPath: Assets.vec.cubeSearchSvg.path,
iconColor: Color(0xFF2D5FFF),
bgLabelColor: const Color(0xFFAFCBFF),
bgDescriptionColor: const Color(0xFFCEDFFF),
),
),
],
);
}, controller.rootLogic.inventoryModel),
2025-06-15 17:16:04 +03:30
);
}
Widget _inventoryWidget() {
return ObxValue((data) {
return Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 13),
child: Row(
spacing: 8,
children: [
Expanded(
child: _informationLabelCard(
title: 'مانده انبار',
isLoading: data.value == null,
2025-06-22 16:51:22 +03:30
description: data.value?.totalRemainWeight.separatedByComma ?? '0',
2025-06-15 17:16:04 +03:30
iconPath: Assets.vec.cubeSearchSvg.path,
iconColor: const Color(0xFF426060),
bgDescriptionColor: const Color(0xFFC7DFE0),
bgLabelColor: const Color(0xFFA5D1D2),
),
),
Expanded(
child: _informationLabelCard(
title: 'توزیع شده',
isLoading: data.value == null,
2025-06-22 16:51:22 +03:30
description: data.value?.realAllocatedWeight.separatedByComma ?? '0',
2025-06-15 17:16:04 +03:30
iconPath: Assets.vec.cubeRotateSvg.path,
iconColor: Color(0xFF5C4D64),
bgLabelColor: Color(0xFFC8B8D1),
bgDescriptionColor: Color(0xFFDAD4DD),
),
),
],
),
);
}, controller.rootLogic.inventoryModel);
2025-06-15 17:16:04 +03:30
}
Widget _todayShipmentWidget() {
2025-07-17 15:44:40 +03:30
return Padding(
padding: const EdgeInsets.fromLTRB(0, 10, 0, 13),
child: Row(
spacing: 8,
children: [
Expanded(
child: ObxValue(
(data) => _informationLabelCard(
title: 'بارهای امروز',
isLoading: data.value == null,
description: data.value?.separatedByComma ?? '0',
iconPath: Assets.vec.cubeSearchSvg.path,
iconColor: AppColor.blueNormal,
bgDescriptionColor: Colors.white,
bgLabelColor: Color(0xFFEAEFFF),
2025-06-15 17:16:04 +03:30
),
2025-07-17 15:44:40 +03:30
controller.totalWeightTodayBars,
2025-06-15 09:48:52 +03:30
),
2025-07-17 15:44:40 +03:30
),
Expanded(
child: ObxValue((data) {
return _informationLabelCard(
title: 'درانتظار تایید',
isLoading: data.value == null,
description: '(${data.value?.totalNotEnteredBars.separatedByComma ?? '0'})',
unit: '(${data.value?.totalNotEnteredKillHouseRequestsWeight.separatedByComma})کیلوگرم',
iconPath: Assets.vec.cubeRotateSvg.path,
iconColor: Color(0xFF8F4124),
bgLabelColor: Color(0xFFF59770),
bgDescriptionColor: Color(0xFFF6DFD8),
);
}, controller.barInformation),
),
],
),
);
2025-06-15 09:48:52 +03:30
}
Container _informationLabelCard({
required String title,
required String description,
String unit = 'کیلوگرم',
2025-06-15 17:16:04 +03:30
bool isLoading = false,
2025-06-15 09:48:52 +03:30
required String iconPath,
required Color iconColor,
required Color bgDescriptionColor,
required Color bgLabelColor,
}) {
return Container(
height: 82,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)),
clipBehavior: Clip.hardEdge,
child: Row(
children: [
// Left side with icon and title
Expanded(
child: Container(
height: 82,
decoration: BoxDecoration(
color: bgLabelColor,
2025-07-08 16:20:55 +03:30
borderRadius: BorderRadius.only(
topRight: Radius.circular(8),
bottomRight: Radius.circular(8),
),
2025-06-15 09:48:52 +03:30
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 4,
children: [
2025-07-08 16:20:55 +03:30
SvgGenImage.vec(iconPath).svg(
width: 24,
height: 24,
colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn),
),
2025-06-15 09:48:52 +03:30
Text(
title,
textAlign: TextAlign.right,
style: AppFonts.yekan14.copyWith(color: AppColor.mediumGreyDarkActive),
),
],
),
),
),
// Right side with description and unit
Expanded(
child: Container(
decoration: BoxDecoration(
color: bgDescriptionColor,
2025-07-08 16:20:55 +03:30
borderRadius: BorderRadius.only(
topLeft: Radius.circular(8),
bottomLeft: Radius.circular(8),
),
2025-06-15 09:48:52 +03:30
),
2025-06-15 17:16:04 +03:30
child: isLoading
? Center(child: CupertinoActivityIndicator())
: Column(
2025-06-30 09:33:14 +03:30
mainAxisAlignment: MainAxisAlignment.center,
spacing: 4,
children: [
Text(
description,
textAlign: TextAlign.right,
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkActive),
),
Text(
unit,
textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.mediumGreyDarkActive),
),
],
),
2025-06-15 09:48:52 +03:30
),
),
],
),
);
}
Container _informationIconCard({
required String title,
required String description,
String unit = 'کیلوگرم',
2025-06-15 17:16:04 +03:30
bool isLoading = false,
2025-06-15 09:48:52 +03:30
required String iconPath,
required Color iconColor,
required Color bgDescriptionColor,
required Color bgLabelColor,
}) {
return Container(
height: 110,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(8)),
clipBehavior: Clip.hardEdge,
child: Stack(
alignment: Alignment.topCenter,
children: [
Positioned(
bottom: 0,
right: 0,
left: 0,
child: Container(
height: 91,
decoration: BoxDecoration(
color: bgDescriptionColor,
borderRadius: BorderRadius.circular(8),
border: Border.all(width: 0.25, color: const Color(0xFFB4B4B4)),
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 4,
children: [
Text(
title,
textAlign: TextAlign.right,
style: AppFonts.yekan14.copyWith(color: AppColor.mediumGreyDarkActive),
),
2025-06-15 17:16:04 +03:30
isLoading
? Center(child: CupertinoActivityIndicator())
: Text(
2025-06-30 09:33:14 +03:30
description,
textAlign: TextAlign.right,
style: AppFonts.yekan16.copyWith(color: AppColor.mediumGreyDarkActive),
),
2025-06-15 09:48:52 +03:30
Text(
unit,
textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.mediumGreyDarkActive),
),
],
),
),
),
Positioned(
top: 0,
child: Container(
width: 32,
height: 32,
decoration: ShapeDecoration(
color: bgLabelColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
side: BorderSide(width: 0.25, color: const Color(0xFFD5D5D5)),
),
),
child: Center(
2025-07-08 16:20:55 +03:30
child: SvgGenImage.vec(iconPath).svg(
width: 24,
height: 24,
colorFilter: ColorFilter.mode(iconColor, BlendMode.srcIn),
),
2025-06-15 09:48:52 +03:30
),
),
),
],
),
);
}
2025-07-08 16:20:55 +03:30
Widget inventoryItem({
required bool isExpanded,
required int index,
required InventoryModel model,
}) {
2025-06-15 09:48:52 +03:30
return Column(
mainAxisAlignment: MainAxisAlignment.center,
spacing: 8,
children: [
buildRow('نام محصول', model.name ?? ''),
Visibility(
visible: isExpanded,
child: Column(
spacing: 8,
children: [
buildRow('وزن خریدهای دولتی داخل استان (کیلوگرم)', '0326598653'),
2025-07-08 16:20:55 +03:30
buildRow(
'وزن خریدهای آزاد داخل استان (کیلوگرم)',
model.receiveFreeCarcassesWeight.toString(),
),
buildRow(
'وزن خریدهای خارج استان (کیلوگرم)',
model.freeBuyingCarcassesWeight.toString(),
),
buildRow(
'کل ورودی به انبار (کیلوگرم)',
model.totalFreeBarsCarcassesWeight.toString(),
),
2025-06-15 09:48:52 +03:30
buildRow('کل فروش (کیلوگرم)', model.realAllocatedWeight.toString()),
buildRow('مانده انبار (کیلوگرم)', model.totalRemainWeight.toString()),
],
),
),
],
);
}
Widget buildRow(String title, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Flexible(
flex: 2,
child: Text(
title,
textAlign: TextAlign.right,
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover),
),
),
Flexible(
flex: 1,
child: Text(
value,
textAlign: TextAlign.center,
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDarkHover),
),
),
],
),
);
}
Widget broadcastInformationWidget(KillHouseDistributionInfo? model) {
return Container(
height: 140,
margin: const EdgeInsets.all(8),
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: AppColor.blueNormal, width: 1),
),
child: model != null
? Column(
2025-06-30 09:33:14 +03:30
crossAxisAlignment: CrossAxisAlignment.start,
spacing: 10,
children: [
Text(
'اطلاعات ارسالی',
textAlign: TextAlign.right,
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal),
),
const SizedBox(height: 12),
2025-07-08 16:20:55 +03:30
buildRow(
'فروش و توزیع داخل استان (کیلوگرم)',
model.stewardAllocationsWeight!.toInt().toString(),
),
buildRow(
'فروش و توزیع خارج استان (کیلوگرم)',
model.freeSalesWeight!.toInt().toString(),
),
2025-06-30 09:33:14 +03:30
],
)
2025-06-15 09:48:52 +03:30
: const Center(child: CircularProgressIndicator()),
);
}
2025-07-08 16:20:55 +03:30
Widget cardWidget({
required String title,
required String iconPath,
required VoidCallback onTap,
}) {
2025-06-15 09:48:52 +03:30
return Container(
width: Get.width / 4,
height: 130,
child: GestureDetector(
onTap: onTap,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(width: 1, color: AppColor.blueNormal),
),
child: Padding(
padding: EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SvgGenImage(iconPath).svg(width: 50, height: 50),
SizedBox(height: 4),
Text(
title,
textAlign: TextAlign.center,
style: AppFonts.yekan12.copyWith(color: AppColor.blueNormal),
),
],
),
),
),
),
);
}
}