import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:shared_preferences/shared_preferences.dart'; // don't forget import '../services/apiService.dart'; class CustomAppBar extends StatefulWidget implements PreferredSizeWidget { final String? logoUrl; final String? username; final List? actions; final bool showBackButton; const CustomAppBar({ super.key, this.logoUrl, this.username, this.actions, this.showBackButton = false, }); @override Size get preferredSize => const Size.fromHeight(kToolbarHeight); @override _CustomAppBarState createState() => _CustomAppBarState(); } class _CustomAppBarState extends State { final ApiService apiService = ApiService(); String? token; Map? userData; Map? fetchedUserData; Map userDetails = {}; Map? selectedOrg; Color? layoutColor; Color? bodyColor; Color _myTravelRequestColor = Color(0xFF475569); // Default color EdgeInsets _myTravelRequestPadding = EdgeInsets.symmetric(horizontal: 8, vertical: 4); Color _myApprovalsColor = Color(0xFF475569); // Default color void initState() { super.initState(); // initializeData(); WidgetsBinding.instance.addPostFrameCallback((_) { initializeData(); getOrganizationData(); }); } Future initializeData() async { print("initializeDatainitializeData"); token = await getToken(); fetchedUserData = await getUserData(); if (token == null || fetchedUserData == null) { print("Token or USerId missing"); return; } setState(() { userData = fetchedUserData; }); } Future getToken() async { final prefs = await SharedPreferences.getInstance(); return prefs.getString("auth_token"); } Future?> getUserData() async { final prefs = await SharedPreferences.getInstance(); final String? userDataString = prefs.getString('user_data'); if (userDataString != null) { try { userDetails = jsonDecode(userDataString); return { "user_id": userDetails["user_id"].toString(), "name": "${userDetails["first_name"]} ${userDetails["last_name"]}", "email": userDetails["email"] ?? "", "role": userDetails["role"] ?? "", }; } catch (e) { print("Error decoding user data: $e"); return null; } } return null; } Future getOrganizationData() async { try { print("getUpdatedServices"); final result = await apiService.fetchOrganization(); final prefs = await SharedPreferences.getInstance(); print("UUPdatedServices - $result"); setState(() { selectedOrg = result; layoutColor = selectedOrg?['layout_color'] != null ? Color(int.parse(selectedOrg!['layout_color'])) : Colors.white; bodyColor = selectedOrg?['color'] != null ? Color(int.parse( selectedOrg!['color'].toString().replaceFirst('0x', ''), radix: 16)) : Colors.blue; String? rawLogoPath = selectedOrg?['logo']; if (rawLogoPath != null && rawLogoPath.contains('/assets')) { const baseUrl = "https://apitest.tripapprovaltool.com"; final assetPath = rawLogoPath.split('/assets').last; selectedOrg!['logo'] = "$baseUrl/assets$assetPath"; } }); // Save to SharedPreferences await prefs.setString('layout_color', selectedOrg?['layout_color']); await prefs.setString('body_color', selectedOrg?['color']); await prefs.setString('body_color', selectedOrg?['plan_action']); print( "Layout Color- ${selectedOrg?['layout_color']} - $layoutColor ---------- bodyColor - $bodyColor"); } catch (e) { print("Error : $e"); } } @override Widget build(BuildContext context) { return AppBar( backgroundColor: Colors.white, surfaceTintColor: Colors.white, // elevation: 3, automaticallyImplyLeading: false, // leading: showBackButton // ? IconButton( // icon: const Icon(Icons.arrow_back, color: Colors.black87), // onPressed: () => Navigator.pop(context), // ) // : null, titleSpacing: 0, title: Padding( padding: EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.05), child: Row( children: [ Padding( padding: const EdgeInsets.all(10), // padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 10), child: selectedOrg?['logo'] != null ? ClipRect( child: Image.network( selectedOrg!['logo'], width: 100, height: 80, // fit: BoxFit.contain, errorBuilder: (context, error, stackTrace) { return const CircleAvatar( radius: 20, backgroundColor: Colors.redAccent, child: Icon(Icons.error, size: 10), ); }, ), ) : const CircleAvatar( radius: 20, backgroundColor: Colors.white, child: Icon( Icons.add_a_photo, size: 10, color: Colors.grey, ), ), ), SizedBox( width: MediaQuery.of(context).size.width * 0.25, ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (userData?["role"] == "Org Admin" || userData?["role"] == "Travel Admin") MouseRegion( cursor: SystemMouseCursors.click, onEnter: (_) { setState(() { // _myTravelRequestPadding = // EdgeInsets.symmetric(horizontal: 12, vertical: 78); // _myTravelRequestColor = // Color(0xFF114D8B); // Change color on hover }); }, onExit: (_) { setState(() { // _myTravelRequestPadding = EdgeInsets.symmetric( // horizontal: 8, vertical: 4); // Normal padding // _myTravelRequestColor = // Color(0xFF475569); // Revert color when hover ends }); }, child: InkWell( onTap: () { context.go('/listAllPlan'); }, child: Text( "All Trips", style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, // color: Color(0xFF475569), color: _myTravelRequestColor, fontFamily: "Inter", ), )), ), const SizedBox(width: 20), MouseRegion( cursor: SystemMouseCursors.click, onEnter: (_) { setState(() { // _myTravelRequestPadding = // EdgeInsets.symmetric(horizontal: 12, vertical: 78); // _myTravelRequestColor = // Color(0xFF114D8B); // Change color on hover }); }, onExit: (_) { setState(() { // _myTravelRequestPadding = EdgeInsets.symmetric( // horizontal: 8, vertical: 4); // Normal padding // _myTravelRequestColor = // Color(0xFF475569); // Revert color when hover ends }); }, child: InkWell( onTap: () { context.go('/listPlan'); }, child: Text( "My Travel Request", style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, // color: Color(0xFF475569), color: _myTravelRequestColor, fontFamily: "Inter", ), )), ), const SizedBox(width: 20), MouseRegion( cursor: SystemMouseCursors.click, onEnter: (_) { setState(() { _myApprovalsColor = Color(0xFF114D8B); // Change color on hover }); }, onExit: (_) { setState(() { _myApprovalsColor = Color(0xFF475569); // Revert color when hover ends }); }, child: InkWell( onTap: () { context.go('/ApprovalList'); }, child: Text( "My Approvals", style: TextStyle( fontSize: 12, fontWeight: FontWeight.w600, color: _myApprovalsColor, // color: Color(0xFF475569), fontFamily: "Inter", ), )), ), ], ), ], ), ), actions: [ Padding( padding: EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.05), child: Row( children: [ // if (userData?["role"] != "User") Builder( builder: (context) => PopupMenuButton( color: Colors.white, padding: EdgeInsets.zero, // icon: const Icon(Icons.arrow_drop_down, // size: 20, color: Colors.black87), offset: const Offset(0, 50), // 👈 shift it 50 pixels down onSelected: (String value) { switch (value) { case '/OrganizationSetup': context.go('/OrganizationSetup'); break; case '/listUser': context.go('/listUser'); break; case '/group': context.go('/group'); break; case '/PolicyList': context.go('/PolicyList'); case '/CreateUserDetails': context.go( "/CreateUserDetails", extra: { "selectedUser": userDetails, "isEditProfile": true, "isViewMode": true }, ); case '/logout': context.go('/'); break; } }, // itemBuilder: (BuildContext context) => // menuItems.map(buildMenuItem).toList(), itemBuilder: (BuildContext context) { final isUser = userData?["role"] == "User"; final filteredItems = isUser ? menuItems .where((item) => item['value'] == '/CreateUserDetails' || item['value'] == '/logout') .toList() : menuItems; // Create a new list starting with role display and divider return [ PopupMenuItem( enabled: false, // ❌ Not clickable child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( userData?["role"] ?? '', style: const TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: Colors.black, ), ), const Divider(), // 👈 Divider after role ], ), ), ...filteredItems .map(buildMenuItem) .toList(), // 👈 then normal items ]; }, // itemBuilder: (BuildContext context) { // final isUser = userData?["role"] == "User"; // final filteredItems = isUser // ? menuItems // .where((item) => // item['value'] == '/CreateUserDetails' || // item['value'] == '/logout') // .toList() // : menuItems; // // return filteredItems.map(buildMenuItem).toList(); // }, child: MouseRegion( cursor: SystemMouseCursors.click, child: Row( mainAxisSize: MainAxisSize.min, children: [ Text( userData?["name"] ?? "N/A", style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w500, fontFamily: "Roboto", color: Colors.black, ), ), const Icon( Icons.arrow_drop_down, size: 20, color: Colors.black87, ), ], ), ), ), ), const SizedBox(width: 8), ], ), ), ], bottom: PreferredSize( preferredSize: Size.fromHeight(1), child: Container( height: 1, color: Colors.grey.shade200, // Set the color of the bottom border ), ), ); } @override Size get preferredSize => const Size.fromHeight(kToolbarHeight); } final List> menuItems = [ { 'value': '/OrganizationSetup', 'icon': Icons.business, 'label': 'Organization' }, { 'value': '/listUser', 'icon': Icons.manage_accounts, 'label': 'User Management' }, {'value': '/group', 'icon': Icons.group, 'label': 'Group'}, {'value': '/PolicyList', 'icon': Icons.policy, 'label': 'Policy'}, { 'value': '/CreateUserDetails', 'icon': Icons.account_circle, 'label': 'My Profile' }, {'value': '/logout', 'icon': Icons.login_outlined, 'label': 'Logout'}, ]; PopupMenuItem buildMenuItem(Map item) { return PopupMenuItem( height: 40, // 👈 reduce PopupMenuItem height value: item['value'], padding: EdgeInsets.symmetric(horizontal: 12), // 👈 control left-right spacing child: Row( children: [ Icon(item['icon'], size: 18, color: Colors.black87), // 👈 smaller, cleaner icon SizedBox(width: 10), // 👈 small space between icon and text Text( item['label'], style: TextStyle( fontSize: 13, fontFamily: "Roboto", fontWeight: FontWeight.w400, color: Colors.black87, ), ), ], ), ); }