import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:on_field_work/controller/dashboard/dashboard_controller.dart'; import 'package:on_field_work/helpers/widgets/my_text.dart'; import 'package:on_field_work/helpers/utils/utils.dart'; import 'package:on_field_work/helpers/widgets/my_custom_skeleton.dart'; import 'package:on_field_work/controller/expense/expense_screen_controller.dart'; import 'package:on_field_work/view/expense/expense_screen.dart'; import 'package:collection/collection.dart'; class ExpenseByStatusWidget extends StatelessWidget { final DashboardController controller; const ExpenseByStatusWidget({super.key, required this.controller}); Widget _buildStatusTile({ required IconData icon, required Color color, required String title, required String amount, required String count, required VoidCallback onTap, }) { return InkWell( onTap: onTap, borderRadius: BorderRadius.circular(8), child: Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: Row( children: [ CircleAvatar( backgroundColor: color.withOpacity(0.15), radius: 22, child: Icon(icon, color: color, size: 24), ), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ MyText.bodyMedium(title, fontWeight: 600), const SizedBox(height: 2), MyText.bodySmall(amount, color: Colors.indigo, fontWeight: 600), ], ), ), MyText.titleMedium(count, color: Colors.blue, fontWeight: 700), const Icon(Icons.chevron_right, color: Colors.blue, size: 24), ], ), ), ); } // Navigate with status filter Future _navigateToExpenseWithFilter( BuildContext context, String statusName) async { final expenseController = Get.put(ExpenseController()); // 1️⃣ Ensure global projects and master data are loaded if (expenseController.projectsMap.isEmpty) { await expenseController.fetchGlobalProjects(); } if (expenseController.expenseStatuses.isEmpty) { await expenseController.fetchMasterData(); } // 2️⃣ Auto-select current project from DashboardController final dashboardController = Get.find(); final currentProjectId = dashboardController.projectController.selectedProjectId.value; final projectName = expenseController.projectsMap.entries .firstWhereOrNull((entry) => entry.value == currentProjectId) ?.key; expenseController.selectedProject.value = projectName ?? ''; // 3️⃣ Select status filter final matchedStatus = expenseController.expenseStatuses.firstWhereOrNull( (e) => e.name.toLowerCase() == statusName.toLowerCase(), ); expenseController.selectedStatus.value = matchedStatus?.id ?? ''; // 4️⃣ Fetch expenses immediately with applied filters await expenseController.fetchExpenses(); // 5️⃣ Navigate to Expense screen Get.to(() => const ExpenseMainScreen()); } // Navigate without status filter Future _navigateToExpenseWithoutFilter() async { final expenseController = Get.put(ExpenseController()); // Ensure global projects loaded if (expenseController.projectsMap.isEmpty) { await expenseController.fetchGlobalProjects(); } // Auto-select current project final dashboardController = Get.find(); final currentProjectId = dashboardController.projectController.selectedProjectId.value; final projectName = expenseController.projectsMap.entries .firstWhereOrNull((entry) => entry.value == currentProjectId) ?.key; expenseController.selectedProject.value = projectName ?? ''; expenseController.selectedStatus.value = ''; // Fetch expenses with project filter (no status) await expenseController.fetchExpenses(); // Navigate to Expense screen Get.to(() => const ExpenseMainScreen()); } @override Widget build(BuildContext context) { return Obx(() { final data = controller.pendingExpensesData.value; if (controller.isPendingExpensesLoading.value) { return SkeletonLoaders.expenseByStatusSkeletonLoader(); } if (data == null) { return Center( child: MyText.bodyMedium("No expense status data available"), ); } return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(5), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.05), blurRadius: 6, spreadRadius: 1, offset: const Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ MyText.titleMedium("Expense - By Status", fontWeight: 700), const SizedBox(height: 16), // ✅ Status tiles _buildStatusTile( icon: Icons.currency_rupee, color: Colors.indigo, title: "Pending Payment", amount: Utils.formatCurrency(data.processPending.totalAmount), count: data.processPending.count.toString(), onTap: () { _navigateToExpenseWithFilter(context, 'Payment Pending'); }, ), _buildStatusTile( icon: Icons.check_circle_outline, color: Colors.orange, title: "Pending Approve", amount: Utils.formatCurrency(data.approvePending.totalAmount), count: data.approvePending.count.toString(), onTap: () { _navigateToExpenseWithFilter(context, 'Approval Pending'); }, ), _buildStatusTile( icon: Icons.search, color: Colors.grey.shade700, title: "Pending Review", amount: Utils.formatCurrency(data.reviewPending.totalAmount), count: data.reviewPending.count.toString(), onTap: () { _navigateToExpenseWithFilter(context, 'Review Pending'); }, ), _buildStatusTile( icon: Icons.insert_drive_file_outlined, color: Colors.cyan, title: "Draft", amount: Utils.formatCurrency(data.draft.totalAmount), count: data.draft.count.toString(), onTap: () { _navigateToExpenseWithFilter(context, 'Draft'); }, ), const SizedBox(height: 16), Divider(color: Colors.grey.shade300), const SizedBox(height: 12), // ✅ Total row tap navigation (no filter) InkWell( onTap: _navigateToExpenseWithoutFilter, borderRadius: BorderRadius.circular(8), child: Padding( padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 4), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ MyText.bodyMedium("Project Spendings:", fontWeight: 600), MyText.bodySmall("(All Processed Payments)", color: Colors.grey.shade600), ], ), Row( children: [ MyText.titleLarge( Utils.formatCurrency(data.totalAmount), color: Colors.blue, fontWeight: 600, ), const SizedBox(width: 6), const Icon(Icons.chevron_right, color: Colors.blue, size: 22), ], ) ], ), ), ), ], ), ); }); } }