ts-tat/lib/routes/custom_appBar.dart
2025-05-03 17:59:17 +05:30

478 lines
16 KiB
Dart

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<Widget>? 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<CustomAppBar> {
final ApiService apiService = ApiService();
String? token;
Map<String, dynamic>? userData;
Map<String, dynamic>? fetchedUserData;
Map<String, dynamic> userDetails = {};
Map<String, dynamic>? 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<void> 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<String?> getToken() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString("auth_token");
}
Future<Map<String, dynamic>?> 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<void> 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<String>(
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<String>(
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<Map<String, dynamic>> 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<String> buildMenuItem(Map<String, dynamic> item) {
return PopupMenuItem<String>(
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,
),
),
],
),
);
}