diff --git a/lib/helpers/widgets/expense/expense_main_components.dart b/lib/helpers/widgets/expense/expense_main_components.dart index 5349b2c..4fe712e 100644 --- a/lib/helpers/widgets/expense/expense_main_components.dart +++ b/lib/helpers/widgets/expense/expense_main_components.dart @@ -33,7 +33,7 @@ class ExpenseAppBar extends StatelessWidget implements PreferredSizeWidget { IconButton( icon: const Icon(Icons.arrow_back_ios_new, color: Colors.black, size: 20), - onPressed: () => Get.offNamed('/dashboard'), + onPressed: () => Get.offNamed('/dashboard/finance'), ), MySpacing.width(8), Expanded( diff --git a/lib/routes.dart b/lib/routes.dart index b289adc..d63efba 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -18,6 +18,7 @@ import 'package:marco/view/auth/mpin_auth_screen.dart'; import 'package:marco/view/directory/directory_main_screen.dart'; import 'package:marco/view/expense/expense_screen.dart'; import 'package:marco/view/document/user_document_screen.dart'; +import 'package:marco/view/finance/finance_screen.dart'; class AuthMiddleware extends GetMiddleware { @override @@ -58,6 +59,12 @@ getPageRoute() { name: '/dashboard/directory-main-page', page: () => DirectoryMainScreen(), middlewares: [AuthMiddleware()]), + + // Finance + GetPage( + name: '/dashboard/finance', + page: () => FinanceScreen(), + middlewares: [AuthMiddleware()]), // Expense GetPage( name: '/dashboard/expense-main-page', diff --git a/lib/view/dashboard/dashboard_screen.dart b/lib/view/dashboard/dashboard_screen.dart index 1211068..0e4af63 100644 --- a/lib/view/dashboard/dashboard_screen.dart +++ b/lib/view/dashboard/dashboard_screen.dart @@ -15,14 +15,13 @@ import 'package:marco/view/layouts/layout.dart'; import 'package:marco/helpers/widgets/dashbaord/expense_breakdown_chart.dart'; import 'package:marco/helpers/widgets/dashbaord/monthly_expense_dashboard_chart.dart'; - class DashboardScreen extends StatefulWidget { const DashboardScreen({super.key}); static const String employeesRoute = "/dashboard/employees"; static const String attendanceRoute = "/dashboard/attendance"; static const String directoryMainPageRoute = "/dashboard/directory-main-page"; - static const String expenseMainPageRoute = "/dashboard/expense-main-page"; + static const String financeMainPageRoute = "/dashboard/finance"; @override State createState() => _DashboardScreenState(); @@ -127,8 +126,8 @@ class _DashboardScreenState extends State with UIMixin { DashboardScreen.employeesRoute), _StatItem(LucideIcons.folder, "Directory", contentTheme.info, DashboardScreen.directoryMainPageRoute), - _StatItem(LucideIcons.badge_dollar_sign, "Expense", contentTheme.info, - DashboardScreen.expenseMainPageRoute), + _StatItem(LucideIcons.wallet, "Finance", contentTheme.info, + DashboardScreen.financeMainPageRoute), ]; final projectController = Get.find(); diff --git a/lib/view/finance/finance_screen.dart b/lib/view/finance/finance_screen.dart new file mode 100644 index 0000000..1bfde08 --- /dev/null +++ b/lib/view/finance/finance_screen.dart @@ -0,0 +1,160 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_lucide/flutter_lucide.dart'; +import 'package:get/get.dart'; +import 'package:marco/controller/project_controller.dart'; +import 'package:marco/helpers/utils/mixins/ui_mixin.dart'; +import 'package:marco/helpers/widgets/my_card.dart'; +import 'package:marco/helpers/widgets/my_container.dart'; +import 'package:marco/helpers/widgets/my_spacing.dart'; +import 'package:marco/helpers/widgets/my_text.dart'; + +class FinanceScreen extends StatefulWidget { + const FinanceScreen({super.key}); + + @override + State createState() => _FinanceScreenState(); +} + +class _FinanceScreenState extends State with UIMixin { + final projectController = Get.find(); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + title: const Text("Finance"), + centerTitle: true, + backgroundColor: Colors.white, + elevation: 0.5, + foregroundColor: Colors.black, + ), + body: SingleChildScrollView( + padding: const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildFinanceStatCards(context), + ], + ), + ), + ); + } + + Widget _buildFinanceStatCards(BuildContext context) { + final stats = [ + _FinanceStatItem( + LucideIcons.badge_dollar_sign, + "Expense", + contentTheme.info, + "/dashboard/expense-main-page", + ), + _FinanceStatItem( + LucideIcons.receipt_text, + "Payment Request", + contentTheme.primary, + "/dashboard/payment-request", + ), + _FinanceStatItem( + LucideIcons.wallet, + "Advance Payment", + contentTheme.warning, + "/dashboard/advance-payment", + ), + ]; + + final projectSelected = projectController.selectedProject != null; + + return LayoutBuilder( + builder: (context, constraints) { + int crossAxisCount = (constraints.maxWidth ~/ 100).clamp(2, 6); + double cardWidth = + (constraints.maxWidth - (crossAxisCount - 1) * 6) / crossAxisCount; + + return Wrap( + spacing: 6, + runSpacing: 6, + alignment: WrapAlignment.start, + children: stats + .map((stat) => _buildFinanceCard(stat, projectSelected, cardWidth)) + .toList(), + ); + }, + ); + } + + Widget _buildFinanceCard( + _FinanceStatItem statItem, bool isProjectSelected, double width) { + const double cardHeight = 80; + final bool isEnabled = isProjectSelected; + + return Opacity( + opacity: isEnabled ? 1.0 : 0.4, + child: IgnorePointer( + ignoring: !isEnabled, + child: InkWell( + borderRadius: BorderRadius.circular(8), + onTap: () => _onCardTap(statItem, isEnabled), + child: MyCard.bordered( + width: width, + height: cardHeight, + paddingAll: 12, + borderRadiusAll: 8, + border: Border.all(color: Colors.grey.withOpacity(0.15)), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + MyContainer.rounded( + paddingAll: 6, + color: statItem.color.withOpacity(0.1), + child: Icon( + statItem.icon, + size: 18, + color: statItem.color, + ), + ), + MySpacing.height(8), + MyText.bodySmall( + statItem.title, + fontWeight: 600, + color: Colors.black87, + textAlign: TextAlign.center, + ), + ], + ), + ), + ), + ), + ); + } + + void _onCardTap(_FinanceStatItem statItem, bool isEnabled) { + if (!isEnabled) { + Get.defaultDialog( + title: "No Project Selected", + middleText: "Please select a project before accessing this section.", + confirm: ElevatedButton( + onPressed: () => Get.back(), + child: const Text("OK"), + ), + ); + return; + } + + Get.toNamed(statItem.route); + } +} + +class _FinanceStatItem { + final IconData icon; + final String title; + final Color color; + final String route; + + _FinanceStatItem( + this.icon, + this.title, + this.color, + this.route, + ); +}