nhance_partner/lib/presentation/widgets/drawer_menu.dart
2026-04-08 15:55:08 +05:30

413 lines
13 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../../core/routing/routes.dart';
import 'package:go_router/go_router.dart';
import '../providers/userRoleProvider.dart';
import 'drawerContentWrapper.dart';
class DrawerMenu extends ConsumerStatefulWidget {
const DrawerMenu({super.key});
@override
ConsumerState<DrawerMenu> createState() => DrawerMenuState();
}
class DrawerMenuState extends ConsumerState<DrawerMenu> {
OverlayEntry? _overlayEntry;
void _showPopup(
BuildContext context,
Offset offset,
Size size,
String key,
dynamic roleId,
) {
_hidePopup(); // remove previous popup
_overlayEntry = OverlayEntry(
builder: (_) {
return Positioned(
left: offset.dx + size.width - 5,
top: offset.dy + (size.height / 2) - 20,
child: MouseRegion(
onExit: (_) => _hidePopup(), // hide when mouse leaves popup
child: Material(
elevation: 4,
borderRadius: BorderRadius.circular(16),
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(6),
color: const Color(0xFFDDF5F1),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (key == 'User') ...[
_buildPopupItem(
label: "Partner",
onTap: () => context.go(AppRoutes.agentLst),
),
const SizedBox(height: 5),
_buildPopupItem(
label: "Staff",
onTap: () => context.go(AppRoutes.staffLst),
),
],
if (key == 'Reports') ...[
if (roleId == 'manager' ||
roleId == 'Accounts' ||
roleId == 'agent') ...[
_buildPopupItem(
label: "Payout List",
onTap: () => context.go(
roleId == 'agent'
? AppRoutes.gridView
: AppRoutes.gridList,
),
),
const SizedBox(height: 5),
],
_buildPopupItem(
label: "Claims",
onTap: () => context.go(AppRoutes.claimlist),
),
const SizedBox(height: 5),
_buildPopupItem(
label: "Endorsement",
onTap: () => context.go(AppRoutes.Endorsement),
),
const SizedBox(height: 5),
_buildPopupItem(
label: "Policy",
onTap: () => context.go(AppRoutes.policylist),
),
],
],
),
),
),
),
);
},
);
Overlay.of(context, rootOverlay: true)?.insert(_overlayEntry!);
}
void _hidePopup() {
print('Hide');
_overlayEntry?.remove();
_overlayEntry = null;
}
@override
void dispose() {
_hidePopup(); // remove any popup when drawer is disposed
super.dispose();
}
@override
Widget build(BuildContext context) {
final roleId = ref.watch(userRoleProvider);
final currentPath = GoRouterState.of(context).matchedLocation;
print('RoleId - $roleId');
return Container(
color: const Color(0xFF425B5B),
padding: const EdgeInsets.all(13.0),
child: ListView(
padding: EdgeInsets.zero,
children: [
const SizedBox(height: 30),
// Dashboard
_buildMenuItem(
context: context,
icon: Image.asset(
"assets/drawer/drawerImg1.png",
height: 25,
width: 25,
),
label: "Dashboard",
isActive:
currentPath == AppRoutes.dashboard ||
currentPath == AppRoutes.partnerPortalDashboard,
onTap: () async {
_hidePopup();
final prefs = await SharedPreferences.getInstance();
await prefs.remove('dashboardKeyProvider');
await prefs.remove('dashboardStatusProvider');
await prefs.remove('dashboardStaffIdProvider');
final dashboardRoute = roleId == 'agent'
? AppRoutes.partnerPortalDashboard
: AppRoutes.dashboard;
context.go(dashboardRoute);
},
),
// Enquiry
_buildMenuItem(
context: context,
icon: Icon(Icons.list_alt_rounded, size: 30, color: Colors.black),
label: "Enquiry",
onTap: () async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove('dashboardKeyProvider');
await prefs.remove('dashboardStatusProvider');
await prefs.remove('dashboardStaffIdProvider');
_hidePopup();
if (roleId == 'agent') {
context.go(AppRoutes.enquiryLst);
}
// else if (roleId == 'handler') {
// context.go(AppRoutes.enquiryHandlerLst);
// }
else {
context.go(AppRoutes.enquiryForStaff);
}
},
),
// User (Manager Only)
if (roleId == 'manager')
_buildHoverMenu(
context: context,
icon: Icon(Icons.person_add_alt, size: 30),
label: "User",
popupKey: 'User',
),
// Reports (Not Staff)
if (roleId != 'staff')
_buildHoverMenu(
context: context,
icon: Image.asset(
"assets/drawer/drawerImg2.png",
height: 25,
width: 25,
),
label: "Reports",
popupKey: 'Reports',
),
if (roleId == 'manager')
_buildMenuItem(
context: context,
icon: Icon(Icons.access_time, size: 30, color: Colors.black),
label: "Staff Attendance",
onTap: () {
context.go(AppRoutes.allStaffAttendance);
},
),
if (roleId == 'Accounts') ...[
_buildMenuItem(
context: context,
icon: const Icon(Icons.payments_outlined, size: 30, color: Colors.black),
label: "Payout",
isActive: currentPath == AppRoutes.payoutList,
onTap: () => context.go(AppRoutes.payoutList),
),
_buildMenuItem(
context: context,
icon: const Icon(Icons.upload_file_outlined, size: 30, color: Colors.black),
label: "Payout Upload",
isActive: currentPath == AppRoutes.payoutUpload,
onTap: () => context.go(AppRoutes.payoutUpload),
),
_buildMenuItem(
context: context,
icon: const Icon(Icons.table_chart_outlined, size: 30, color: Colors.black),
label: "Payout Report",
isActive: currentPath == AppRoutes.payoutReport,
onTap: () => context.go(AppRoutes.payoutReport),
),
],
if (roleId == 'agent')
_buildMenuItem(
context: context,
icon: const Icon(Icons.table_chart_outlined, size: 30, color: Colors.black),
label: "Payout Report",
isActive: currentPath == AppRoutes.payoutReport,
onTap: () => context.go(AppRoutes.payoutReport),
),
],
),
);
}
Widget _buildMenuItem({
required BuildContext context,
required Widget icon,
required String label,
bool isActive = false,
required VoidCallback onTap,
}) {
return Column(
children: [
GestureDetector(
onTap: onTap,
child: MouseRegion(
onEnter: (_) => _hidePopup(), // hide any popup when hovering
child: DrawerContentWrapper(child: icon, isActive: isActive),
),
),
DrawerLabel(label, isActive: isActive),
],
);
}
Widget _buildHoverMenu({
required BuildContext context,
required Widget icon,
required String label,
required String popupKey,
}) {
return Column(
children: [
Builder(
builder: (itemContext) {
return MouseRegion(
onEnter: (_) {
final renderBox = itemContext.findRenderObject() as RenderBox;
final offset = renderBox.localToGlobal(Offset.zero);
final size = renderBox.size;
final roleId = ref.read(userRoleProvider);
_showPopup(context, offset, size, popupKey, roleId);
},
child: DrawerContentWrapper(child: icon),
);
},
),
DrawerLabel(label),
],
);
}
}
// Drawer label widget
class DrawerLabel extends StatelessWidget {
final String text;
final bool isActive;
const DrawerLabel(this.text, {super.key, this.isActive = false});
@override
Widget build(BuildContext context) {
// Split the text by space (e.g. "Staff Attendance" → ["Staff", "Attendance"])
final parts = text.split(' ');
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: parts.map((line) {
return Text(
line,
style: GoogleFonts.inter(
color: isActive ? const Color(0xFF0ABFA3) : Colors.white,
fontSize: 11.5,
fontWeight: isActive ? FontWeight.w700 : FontWeight.w400,
),
textAlign: TextAlign.center,
);
}).toList(),
);
}
// Widget build(BuildContext context) {
// return Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// SizedBox(
// width: 70,
// child: Align(
// alignment: Alignment.center,
// child: Text(
// text,
// style: GoogleFonts.inter(color: Colors.white, fontSize: 11.5),
// softWrap: true,
// maxLines: 2,
// ),
// ),
// ),
// const SizedBox(height: 20),
// ],
// );
// }
}
// Popup item
Widget _buildPopupItem({required String label, required VoidCallback onTap}) {
return _HoverableContainer(
label: label,
onTap: onTap,
normalColor: const Color(0xFFDDF5F1),
hoverColor: Colors.white,
);
}
// Hoverable container for popup items
class _HoverableContainer extends StatefulWidget {
final String label;
final VoidCallback onTap;
final Color normalColor;
final Color hoverColor;
const _HoverableContainer({
super.key,
required this.label,
required this.onTap,
required this.normalColor,
required this.hoverColor,
});
@override
_HoverableContainerState createState() => _HoverableContainerState();
}
class _HoverableContainerState extends State<_HoverableContainer> {
bool _isHovered = false;
@override
Widget build(BuildContext context) {
return MouseRegion(
onEnter: (_) => setState(() => _isHovered = true),
onExit: (_) => setState(() => _isHovered = false),
child: GestureDetector(
onTap: widget.onTap,
child: Container(
decoration: BoxDecoration(
color: _isHovered ? widget.hoverColor : widget.normalColor,
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
SizedBox(
width: 110,
child: Text(widget.label, style: _cardTextStyle),
),
const Icon(
Icons.arrow_forward_ios_rounded,
size: 12,
color: Colors.black,
),
],
),
),
),
);
}
}
TextStyle _cardTextStyle = GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w500,
);