import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:marco/controller/project_controller.dart'; import 'package:marco/controller/expense/expense_screen_controller.dart'; import 'package:marco/controller/permission_controller.dart'; import 'package:marco/helpers/widgets/my_text.dart'; import 'package:marco/helpers/widgets/my_custom_skeleton.dart'; import 'package:marco/model/expense/expense_list_model.dart'; import 'package:marco/model/expense/add_expense_bottom_sheet.dart'; import 'package:marco/view/expense/expense_filter_bottom_sheet.dart'; import 'package:marco/helpers/widgets/expense_main_components.dart'; import 'package:marco/helpers/utils/permission_constants.dart'; class ExpenseMainScreen extends StatefulWidget { const ExpenseMainScreen({super.key}); @override State createState() => _ExpenseMainScreenState(); } class _ExpenseMainScreenState extends State { bool isHistoryView = false; final searchController = TextEditingController(); final expenseController = Get.put(ExpenseController()); final projectController = Get.find(); final permissionController = Get.find(); @override void initState() { super.initState(); expenseController.fetchExpenses(); } void _refreshExpenses() => expenseController.fetchExpenses(); void _openFilterBottomSheet() { showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (_) => ExpenseFilterBottomSheet( expenseController: expenseController, scrollController: ScrollController(), ), ); } List _getFilteredExpenses() { final query = searchController.text.trim().toLowerCase(); final now = DateTime.now(); final filtered = expenseController.expenses.where((e) { return query.isEmpty || e.expensesType.name.toLowerCase().contains(query) || e.supplerName.toLowerCase().contains(query) || e.paymentMode.name.toLowerCase().contains(query); }).toList() ..sort((a, b) => b.transactionDate.compareTo(a.transactionDate)); return isHistoryView ? filtered .where((e) => e.transactionDate.isBefore(DateTime(now.year, now.month))) .toList() : filtered .where((e) => e.transactionDate.month == now.month && e.transactionDate.year == now.year) .toList(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: ExpenseAppBar(projectController: projectController), body: SafeArea( child: Column( children: [ SearchAndFilter( controller: searchController, onChanged: (_) => setState(() {}), onFilterTap: _openFilterBottomSheet, onRefreshTap: _refreshExpenses, expenseController: expenseController, ), ToggleButtonsRow( isHistoryView: isHistoryView, onToggle: (v) => setState(() => isHistoryView = v), ), Expanded( child: Obx(() { if (expenseController.isLoading.value && expenseController.expenses.isEmpty) { return SkeletonLoaders.expenseListSkeletonLoader(); } if (expenseController.errorMessage.isNotEmpty) { return Center( child: MyText.bodyMedium( expenseController.errorMessage.value, color: Colors.red, ), ); } final filteredList = _getFilteredExpenses(); return NotificationListener( onNotification: (ScrollNotification scrollInfo) { if (scrollInfo.metrics.pixels == scrollInfo.metrics.maxScrollExtent && !expenseController.isLoading.value) { expenseController.loadMoreExpenses(); } return false; }, child: ExpenseList( expenseList: filteredList, onViewDetail: () => expenseController.fetchExpenses(), ), ); }), ), ], ), ), // ✅ FAB only if user has expenseUpload permission floatingActionButton: permissionController.hasPermission(Permissions.expenseUpload) ? FloatingActionButton( backgroundColor: Colors.red, onPressed: showAddExpenseBottomSheet, child: const Icon(Icons.add, color: Colors.white), ) : null, ); } }