Merge branch 'main' of bitbucket.org:venbainformationtechnology/ts-tat
This commit is contained in:
commit
9f6cfedf42
883
lib/Screens/dashboard/status_dashboard_web.dart
Normal file
883
lib/Screens/dashboard/status_dashboard_web.dart
Normal file
@ -0,0 +1,883 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:html' as html;
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frontend/routes/custom_router.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../../config/apiUrl.dart';
|
||||
import '../../routes/custom_appBar.dart';
|
||||
import '../../routes/custom_drawer.dart';
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
|
||||
class StatusDashboard extends StatefulWidget {
|
||||
const StatusDashboard({super.key});
|
||||
|
||||
@override
|
||||
StatusDashboardState createState() => StatusDashboardState();
|
||||
}
|
||||
|
||||
class StatusDashboardState extends State<StatusDashboard> {
|
||||
Map<String, dynamic>? apiData;
|
||||
String? organizationId;
|
||||
late bool _dialogShown = false;
|
||||
bool loader = false;
|
||||
|
||||
late StreamSubscription<html.PopStateEvent> _popStateListener;
|
||||
String selectedView = 'Today';
|
||||
String AccessKeyFlag = "Both";
|
||||
Map<String, dynamic>? currentData;
|
||||
List typeData = [];
|
||||
List statusData = [];
|
||||
List<int> flightData = [];
|
||||
List<int> accommodationData = [];
|
||||
List<int> forexData = [];
|
||||
|
||||
final categoryIcons = {
|
||||
"flight": Icons.flight,
|
||||
"accommodation": Icons.hotel_outlined,
|
||||
"forex": Icons.attach_money,
|
||||
};
|
||||
|
||||
List<String> statusLabels = [
|
||||
"Pending Approval",
|
||||
"Partially Approved",
|
||||
"Approved",
|
||||
"Rejected",
|
||||
"Cancelled"
|
||||
];
|
||||
|
||||
// Extract counts for "Both" section
|
||||
List<int> getStatusValues(Map<String, dynamic> serviceData) {
|
||||
final both = serviceData['Both'] ?? {};
|
||||
return statusLabels.map((label) => (both[label] ?? 0) as int).toList();
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_checkAuthAndLoadData();
|
||||
|
||||
checkbackbutton();
|
||||
|
||||
// loadDashboardData();
|
||||
}
|
||||
|
||||
void checkbackbutton() async {
|
||||
// Push a dummy state so back button triggers popstate instead of navigating
|
||||
html.window.history.pushState(null, 'home', html.window.location.href);
|
||||
|
||||
_popStateListener = html.window.onPopState.listen((event) {
|
||||
if (!_dialogShown && mounted) {
|
||||
_showBackConfirmationDialog();
|
||||
}
|
||||
|
||||
// Re-push to prevent leaving
|
||||
html.window.history.pushState(null, 'home', html.window.location.href);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_popStateListener.cancel(); // ✅ Remove the browser popstate listener
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _showBackConfirmationDialog() {
|
||||
if (!mounted) return;
|
||||
|
||||
_dialogShown = true;
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder:
|
||||
(context) => AlertDialog(
|
||||
title: Text("Confirm"),
|
||||
content: Text("Do you want to logout?"),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context); // Close dialog
|
||||
_dialogShown = false;
|
||||
},
|
||||
child: Text("Cancel"),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () async {
|
||||
Navigator.pop(context); // Close dialog
|
||||
_dialogShown = false;
|
||||
await _logoutAndRedirect(context);
|
||||
},
|
||||
child: Text("Logout"),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _logoutAndRedirect(BuildContext context) async {
|
||||
print("logue 0");
|
||||
|
||||
// Example: clear session or shared preferences
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.clear();
|
||||
|
||||
context.go("/");
|
||||
|
||||
print("logue 1");
|
||||
}
|
||||
|
||||
void _checkAuthAndLoadData() async {
|
||||
final String? token = await getToken(); // Your async function to get token
|
||||
|
||||
if (token == null || token.isEmpty) {
|
||||
// Token doesn't exist → redirect to login
|
||||
context.go(
|
||||
"/",
|
||||
); // or use: router.go("/") if you're using `GoRouter` directly
|
||||
return;
|
||||
}
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
checkbackbutton();
|
||||
});
|
||||
// If token exists, load the dashboard data
|
||||
loadDashboardData();
|
||||
}
|
||||
|
||||
Future<void> loadDashboardData() async {
|
||||
try {
|
||||
final data = await fetchStatusDashboard();
|
||||
setState(() {
|
||||
apiData = data;
|
||||
});
|
||||
} catch (e) {
|
||||
print("Error loading dashboard: $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<String?> getToken() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString('auth_token');
|
||||
}
|
||||
|
||||
Future<String?> getOrgId() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final String? userDataString = prefs.getString('user_data');
|
||||
|
||||
if (userDataString != null) {
|
||||
try {
|
||||
final Map<String, dynamic> userData = jsonDecode(userDataString);
|
||||
return userData["org_id"]?.toString();
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> fetchStatusDashboard() async {
|
||||
organizationId = await getOrgId();
|
||||
|
||||
final String apiUrlData =
|
||||
'$apiUrl/api/plans/statusDashboard?org_id=$organizationId';
|
||||
final String? token = await getToken();
|
||||
|
||||
print("Fetch StatusDashboard -- 2KN Here : $token");
|
||||
|
||||
if (token == null) {
|
||||
throw Exception('Token not found. Please log in.');
|
||||
}
|
||||
|
||||
final response = await http.get(
|
||||
Uri.parse(apiUrlData),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
print("called api : $apiUrlData");
|
||||
if (response.statusCode == 200) {
|
||||
final apiData = json.decode(response.body);
|
||||
print("Fetch StatusDashboard -- Reponse Here : $apiData");
|
||||
return apiData; // Returning raw JSON list
|
||||
} else {
|
||||
throw Exception('Failed to load users');
|
||||
}
|
||||
}
|
||||
|
||||
Color getStatusColor(String status) {
|
||||
if (status == "Domestic") return Colors.white;
|
||||
if (status == "International") return Colors.white;
|
||||
if (status == "Partially Approved") return Colors.yellow.shade100;
|
||||
if (status == "Pending Approval") return Colors.greenAccent.shade100;
|
||||
if (status == "Approved") return Colors.green.shade100;
|
||||
if (status == "Completed") return Colors.green.shade500;
|
||||
if (status == "Rejected") return Colors.red.shade100;
|
||||
if (status == "Cancelled") return Colors.red.shade200;
|
||||
return Colors.grey.shade100;
|
||||
}
|
||||
|
||||
IconData getStatusIcon(String title) {
|
||||
switch (title) {
|
||||
case "Domestic":
|
||||
return Icons.directions_bus_filled_outlined;
|
||||
case "International":
|
||||
return Icons.airplanemode_active;
|
||||
case "Partially Approved":
|
||||
return Icons.pending;
|
||||
case "Approved":
|
||||
return Icons.check_circle_outline;
|
||||
case "Completed":
|
||||
return Icons.done_all;
|
||||
case "Rejected":
|
||||
return Icons.cancel_outlined;
|
||||
case "Cancelled":
|
||||
return Icons.cancel_schedule_send_outlined;
|
||||
|
||||
default:
|
||||
return Icons.info_outline;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final typeBasedCount = List<Map<String, dynamic>>.from(
|
||||
(apiData?['data']?['typeBasedCount']) ?? [],
|
||||
);
|
||||
|
||||
print("apiData - => $apiData");
|
||||
print("typeBasedCount => $typeBasedCount");
|
||||
|
||||
final statusBasedCount = List<Map<String, dynamic>>.from(
|
||||
(apiData?['data']?['statusBasedCount']) ?? [],
|
||||
);
|
||||
|
||||
final statusBasedTodayCount = List<Map<String, dynamic>>.from(
|
||||
(apiData?['data']?['statusBasedTodayCount']) ?? [],
|
||||
);
|
||||
|
||||
final statusBasedWeeklyCount = List<Map<String, dynamic>>.from(
|
||||
(apiData?['data']?['statusBasedWeeklyCount']) ?? [],
|
||||
);
|
||||
|
||||
final typeBasedTodayCount = List<Map<String, dynamic>>.from(
|
||||
(apiData?['data']?['typeBasedTodayCount']) ?? [],
|
||||
);
|
||||
|
||||
final typeBasedWeeklyCount = List<Map<String, dynamic>>.from(
|
||||
(apiData?['data']?['typeBasedWeeklyCount']) ?? [],
|
||||
);
|
||||
|
||||
final typeTodayBasedCount = List<Map<String, dynamic>>.from(
|
||||
(apiData?['data']?['typeTodayBasedCount']) ?? [],
|
||||
);
|
||||
|
||||
final typeWeeklyBasedCount = List<Map<String, dynamic>>.from(
|
||||
(apiData?['data']?['typeWeeklyBasedCount']) ?? [],
|
||||
);
|
||||
|
||||
final statusTodayBasedCount = List<Map<String, dynamic>>.from(
|
||||
(apiData?['data']?['statusTodayBasedCount']) ?? [],
|
||||
);
|
||||
|
||||
final statusWeeklyBasedCount = List<Map<String, dynamic>>.from(
|
||||
(apiData?['data']?['statusWeeklyBasedCount']) ?? [],
|
||||
);
|
||||
|
||||
final List todayList = List<Map<String, dynamic>>.from(
|
||||
apiData?['data']?['todayTripCounts'] ?? [],
|
||||
);
|
||||
|
||||
final List weekList = List<Map<String, dynamic>>.from(
|
||||
apiData?['data']?['weekTripCounts'] ?? [],
|
||||
);
|
||||
|
||||
// Merge all maps in the list into one map
|
||||
Map<String, dynamic> todayBasedCount = {};
|
||||
Map<String, dynamic> weekBasedCount = {};
|
||||
|
||||
for (final item in todayList) {
|
||||
todayBasedCount.addAll(item);
|
||||
}
|
||||
|
||||
for (final item in weekList) {
|
||||
weekBasedCount.addAll(item);
|
||||
}
|
||||
|
||||
setState(() {
|
||||
// currentData = selectedView == "Today" ? todayBasedCount : weekBasedCount;
|
||||
typeData = selectedView == "Today"
|
||||
? typeBasedTodayCount
|
||||
: typeBasedWeeklyCount ;
|
||||
statusData = selectedView == "Today"
|
||||
? statusBasedTodayCount
|
||||
: statusBasedWeeklyCount ;
|
||||
|
||||
flightData = selectedView == "Today"
|
||||
? getStatusValues(todayBasedCount['flight'] ?? {})
|
||||
: getStatusValues(weekBasedCount['flight'] ?? {});
|
||||
accommodationData = selectedView == "Today"
|
||||
? getStatusValues(todayBasedCount['acomodation'] ?? {})
|
||||
: getStatusValues(weekBasedCount['acomodation'] ?? {});
|
||||
forexData = selectedView == "Today"
|
||||
? getStatusValues(todayBasedCount['forex'] ?? {})
|
||||
: getStatusValues(weekBasedCount['forex'] ?? {});
|
||||
});
|
||||
|
||||
|
||||
print("statusBasedCount - => $statusBasedCount");
|
||||
print("Current Data - => $currentData");
|
||||
// 👇 Local function to create the card widget
|
||||
Widget buildInfoCard(String title, int count, double width) {
|
||||
print('title $title');
|
||||
final color = getStatusColor(title);
|
||||
final icon = getStatusIcon(title);
|
||||
return Card(
|
||||
elevation: 3,
|
||||
color: color,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
child: Container(
|
||||
width: width,
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
icon,
|
||||
size: 32,
|
||||
color:
|
||||
(title == 'Domestic' || title == 'International')
|
||||
? Colors.green
|
||||
: Colors.black54,
|
||||
), // 👈 Add Icon here
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
title,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize:
|
||||
(title == 'Domestic' || title == 'International')
|
||||
? 16
|
||||
: 14,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
count.toString(),
|
||||
style: const TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
// color: Colors.blue,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _handleBackButton() {
|
||||
final location = GoRouterState.of(context).uri.toString();
|
||||
|
||||
print("location - $location");
|
||||
if (location.contains('/StatusDashboard')) {
|
||||
// Do nothing or show "Press again to exit" toast
|
||||
print("Blocked back on dashboard");
|
||||
} else {
|
||||
print("dashboard ..");
|
||||
}
|
||||
}
|
||||
String capitalize(String s) => s[0].toUpperCase() + s.substring(1);
|
||||
|
||||
Widget toggleChip(String label) {
|
||||
bool isSelected = selectedView == label;
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
selectedView = label;
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
decoration: BoxDecoration(
|
||||
color: isSelected ? const Color(0xFF003A78) : Colors.transparent,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
height: 36,
|
||||
child: Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 10,
|
||||
color: isSelected ? Colors.white : Colors.black,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildTopCard({
|
||||
// required IconData icon,
|
||||
required Color color,
|
||||
required String label,
|
||||
required int count,
|
||||
required Color bgColor,
|
||||
}) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(1),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(1),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Tooltip(
|
||||
message: label ,
|
||||
child: Image.asset(
|
||||
label == 'Domestic'
|
||||
? 'assets/images/IconsImg/Domestic_new.png'
|
||||
: 'assets/images/IconsImg/International_new.png',
|
||||
// width: 65,
|
||||
// height: label == 'Domestic' ? 37 : 40,
|
||||
),
|
||||
),
|
||||
// Icon(icon, color: color, size: 40),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
count.toString(),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: bgColor,
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 10,
|
||||
color: color,
|
||||
// color: const Color(0xFFEAF3FB),
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget statusCard(String label, int count) {
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEAF3FB),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
count.toString(),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 18,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildCategoryCard(String title, IconData icon, List<String> statusLabels,List<int> values) {
|
||||
|
||||
final statusIcons = [
|
||||
Icons.calendar_today,
|
||||
Icons.assignment,
|
||||
Icons.verified,
|
||||
Icons.block,
|
||||
Icons.cancel,
|
||||
];
|
||||
|
||||
final statusColors = [
|
||||
Color(0xFFFBFFCA),
|
||||
Color(0xFFFFF1CD),// Colors.yellow.shade100, // Color(0xFFCAE77B),
|
||||
Color(0xFFDAFFE8),// Colors.green.shade100, // Color(0xFF72D480),
|
||||
Color(0xFFFFD6D3),// Colors.red.shade100, // Color(0xFFF88C8C),
|
||||
Color(0xFFFFA8A8), // Colors.red.shade200, // Color(0xFFE94B4B),
|
||||
];
|
||||
|
||||
final statusIconColors = [
|
||||
Color(0xFFB1BC1A),
|
||||
Color(0xFFCC9300),
|
||||
Color(0xFF509269),
|
||||
Color(0xFFD25E55),
|
||||
Color(0xFFAE0303),
|
||||
];
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// borderRadius: BorderRadius.circular(12),
|
||||
// ),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.blueGrey,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: const BoxDecoration(
|
||||
// color: Colors.blue,
|
||||
color: Color(0xFF004A8E),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: Colors.white,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(title, style: GoogleFonts.poppins(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold
|
||||
),),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
...List.generate(values.length, (index) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
// Icon(statusIcons[index], size: 15, color: statusIconColors[index]),
|
||||
Container(
|
||||
width: 28,
|
||||
height: 28,
|
||||
decoration: BoxDecoration(
|
||||
color: statusColors[index], // background color
|
||||
borderRadius: BorderRadius.circular(4), // square with slight rounding
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
statusIcons[index],
|
||||
size: 15,
|
||||
color: statusIconColors[index], // icon color
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(statusLabels[index], style: GoogleFonts.poppins(
|
||||
color: Colors.black87,
|
||||
),),
|
||||
],
|
||||
),
|
||||
Text(values[index].toString(), style: GoogleFonts.poppins(
|
||||
fontSize: 10,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),),
|
||||
],
|
||||
),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Widget buildCategoryCard(String title, IconData icon,statusLabels,statusvalue) {
|
||||
//
|
||||
//
|
||||
// return Container(
|
||||
// padding: const EdgeInsets.all(16),
|
||||
// // decoration: BoxDecoration(
|
||||
// // color: Colors.white,
|
||||
// // borderRadius: BorderRadius.circular(12),
|
||||
// // ),
|
||||
//
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Row(
|
||||
// children: [
|
||||
// Container(
|
||||
// padding: const EdgeInsets.all(8),
|
||||
// decoration: const BoxDecoration(
|
||||
// color: Colors.blue,
|
||||
// shape: BoxShape.circle,
|
||||
// ),
|
||||
// child: Icon(
|
||||
// icon,
|
||||
// color: Colors.white,
|
||||
// size: 20,
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(width: 10),
|
||||
// Text(title, style: GoogleFonts.poppins(
|
||||
// color: Colors.black87,
|
||||
// fontWeight: FontWeight.bold
|
||||
// ),),
|
||||
// ],
|
||||
// ),
|
||||
// const SizedBox(height: 12),
|
||||
// ...List.generate(statusvalue.length, (index) {
|
||||
// return Padding(
|
||||
// padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// Row(
|
||||
// children: [
|
||||
// // Icon(statusIcons[index], size: 20, color: statusColors[index]),
|
||||
// Container(
|
||||
// padding: const EdgeInsets.all(8),
|
||||
// decoration: BoxDecoration(
|
||||
// color: statusColors[index], // Background color behind the icon
|
||||
// borderRadius: BorderRadius.circular(10), // Rounded square
|
||||
// boxShadow: [
|
||||
// BoxShadow(
|
||||
// color: Colors.grey, // Shadow color
|
||||
// spreadRadius: 1,
|
||||
// blurRadius: 5,
|
||||
// offset: const Offset(0, 2), // Shadow position
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// child: Icon(
|
||||
// statusIcons[index],
|
||||
// color: statusIconColors[index],
|
||||
// size: 20,
|
||||
// // color: statusColors[index],
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(width: 6),
|
||||
// Text(statusLabels[index]),
|
||||
// ],
|
||||
// ),
|
||||
//
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }),
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInfo) {
|
||||
bool isDesktop =
|
||||
sizingInfo.deviceScreenType == DeviceScreenType.desktop;
|
||||
|
||||
return PopScope(
|
||||
canPop: false, // Allow back navigation only if not login screen
|
||||
onPopInvokedWithResult: (didPop, result) {
|
||||
if (didPop) return;
|
||||
_handleBackButton(); // Show exit confirmation dialog
|
||||
},
|
||||
child: Scaffold(
|
||||
backgroundColor: const Color(0xFFf5f5f5),
|
||||
appBar: CustomAppBar(isDesktop: isDesktop),
|
||||
drawer: CustomDrawer(isDesktop: false),
|
||||
body: Padding(
|
||||
padding:
|
||||
isDesktop
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal:
|
||||
MediaQuery.of(context).size.width *
|
||||
0.1, // 30% of screen width as horizontal padding
|
||||
vertical: 10, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(0),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return SingleChildScrollView(
|
||||
// child: ConstrainedBox(
|
||||
// constraints: BoxConstraints(
|
||||
// minHeight: constraints.maxHeight,
|
||||
// ),
|
||||
// ),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// First Row: Toggle Buttons Row
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Container(
|
||||
height: 36,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEAEAEA),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
toggleChip("Today"),
|
||||
toggleChip("This Week"),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Second Row: Domestic & International and Status
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// LEFT SIDE
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.blueGrey,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Row(
|
||||
children: [
|
||||
...typeData.map((item) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
buildTopCard(
|
||||
// icon: item['value'] == "Domestic"
|
||||
// ? Icons.home
|
||||
// : Icons.travel_explore,
|
||||
color: item['value'] == "Domestic"
|
||||
? Color(0xFF0DB04B)
|
||||
: Color(0xFF004A8E),
|
||||
label: item['value'],
|
||||
count: item['count'],
|
||||
bgColor: item['value'] == "Domestic"
|
||||
? const Color(0xFFD6FBE4)
|
||||
: const Color(0xFFD9E8FF),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
// RIGHT SIDE
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.blueGrey,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Status",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 19,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 23),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
...statusData.map((item) => statusCard(item['value'], item['count'])).toList(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Third Row: Flight, Accommodation, Forex
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(child: buildCategoryCard("Flight", Icons.flight,statusLabels,flightData)),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(child: buildCategoryCard("Accomodation", Icons.hotel_outlined,statusLabels,accommodationData)),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(child: buildCategoryCard("Forex", Icons.attach_money,statusLabels,forexData)),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -116,7 +116,7 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
"0x${layoutColor?.toARGB32().toRadixString(16).padLeft(8, '0').toUpperCase()}",
|
||||
"secondary_color":
|
||||
"0x${layoutSecondaryColor?.toARGB32().toRadixString(16).padLeft(8, '0').toUpperCase()}",
|
||||
"tertiary_color":
|
||||
"ternary_color":
|
||||
"0x${layoutTertiaryColor?.toARGB32().toRadixString(16).padLeft(8, '0').toUpperCase()}",
|
||||
"color":
|
||||
"0x${bodyColor?.toARGB32().toRadixString(16).padLeft(8, '0').toUpperCase()}",
|
||||
@ -430,6 +430,8 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
// Save back
|
||||
await prefs.setString('org_data', jsonEncode(orgData));
|
||||
await prefs.setString('layout_color', orgData['layout_color']);
|
||||
await prefs.setString('secondary_color', orgData['secondary_color']);
|
||||
await prefs.setString('ternary_color', orgData['ternary_color']);
|
||||
|
||||
print("✅ Updated org_data saved.");
|
||||
}
|
||||
|
||||
@ -73,6 +73,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
Map<String, String?> FirstAmendApproverAction = {};
|
||||
Map<String, String?> SecondAmendApproverAction = {};
|
||||
Map<String, String?> ThirdAmendApproverAction = {};
|
||||
Map<String, String?> FourthAmendApproverAction = {};
|
||||
Map<String, String?> SelectedParallelAmendProcess = {};
|
||||
Map<String, String> policyDetailsIdMap = {}; // new
|
||||
Map<String, String> policyIdMap = {}; // new
|
||||
@ -166,7 +167,8 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
FirstAmendApproverAction.putIfAbsent(id, () => "None");
|
||||
SecondAmendApproverAction.putIfAbsent(id, () => "None");
|
||||
ThirdAmendApproverAction.putIfAbsent(id, () => "None");
|
||||
SelectedParallelAmendProcess.putIfAbsent(id, () => "3");
|
||||
FourthAmendApproverAction.putIfAbsent(id, () => "None");
|
||||
SelectedParallelAmendProcess.putIfAbsent(id, () => "4");
|
||||
|
||||
// Step 5: Add default policy entry
|
||||
policyData?.add({
|
||||
@ -186,6 +188,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
"a1_amendment_action": FirstAmendApproverAction[id],
|
||||
"a2_amendment_action": SecondAmendApproverAction[id],
|
||||
"a3_amendment_action": ThirdAmendApproverAction[id],
|
||||
"a4_amendment_action": FourthAmendApproverAction[id],
|
||||
"amendment_parallel_process_from": SelectedParallelAmendProcess[id],
|
||||
"created_by": widget.userId,
|
||||
});
|
||||
@ -231,8 +234,10 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
item['a2_amendment_action']?.toString();
|
||||
ThirdAmendApproverAction[serviceId] =
|
||||
item['a3_amendment_action']?.toString();
|
||||
FourthAmendApproverAction[serviceId] =
|
||||
item['a4_amendment_action']?.toString();
|
||||
SelectedParallelAmendProcess[serviceId] =
|
||||
item['amendment_parallel_process_from']?.toString() ?? "3";
|
||||
item['amendment_parallel_process_from']?.toString() ?? "4";
|
||||
|
||||
if (item['policy_details_id'] != null) {
|
||||
policyDetailsIdMap[serviceId] = item['policy_details_id'].toString();
|
||||
@ -264,6 +269,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
(item) => item["service_id"] == serviceId,
|
||||
);
|
||||
|
||||
print(FirstApproverAction);
|
||||
Map<String, dynamic> data = {
|
||||
"service_id": serviceId,
|
||||
"cost": costController[serviceId]?.text,
|
||||
@ -282,6 +288,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
"a1_amendment_action": FirstAmendApproverAction[serviceId],
|
||||
"a2_amendment_action": SecondAmendApproverAction[serviceId],
|
||||
"a3_amendment_action": ThirdAmendApproverAction[serviceId],
|
||||
"a4_amendment_action": FourthAmendApproverAction[serviceId],
|
||||
"amendment_parallel_process_from":
|
||||
SelectedParallelAmendProcess[serviceId],
|
||||
"created_by": widget.userId,
|
||||
@ -303,6 +310,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
final aa1 = FirstAmendApproverAction[serviceId];
|
||||
final aa2 = SecondAmendApproverAction[serviceId];
|
||||
final aa3 = ThirdAmendApproverAction[serviceId];
|
||||
final aa4 = FourthAmendApproverAction[serviceId];
|
||||
// bool hasValue = cost.trim().isNotEmpty;
|
||||
// bool hasValue = cost.trim().isNotEmpty || travelClass!.isNotEmpty;
|
||||
bool hasValue =
|
||||
@ -313,15 +321,15 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
[a1, a2, a3].where((a) => a != null).length > 0 &&
|
||||
[a1, a2, a3].where((a) => a == null).length > 0;
|
||||
|
||||
bool allExceptionalActionsNull = ae1 == null && ae2 == null && ae3 == null;
|
||||
bool allExceptionalActionsNull = ae1 == null && ae2 == null && ae3 == null && ae4 == null;
|
||||
bool someExceptionalActionsMissing =
|
||||
[ae1, ae2, ae3].where((a) => a != null).length > 0 &&
|
||||
[ae1, ae2, ae3].where((a) => a == null).length > 0;
|
||||
[ae1, ae2, ae3, ae4].where((a) => a != null).length > 0 &&
|
||||
[ae1, ae2, ae3, ae4].where((a) => a == null).length > 0;
|
||||
|
||||
bool allAmendActionsNull = aa1 == null && aa2 == null && aa3 == null;
|
||||
bool allAmendActionsNull = aa1 == null && aa2 == null && aa3 == null && aa4 == null;
|
||||
bool someAmendActionsMissing =
|
||||
[aa1, aa2, aa3].where((a) => a != null).length > 0 &&
|
||||
[aa1, aa2, aa3].where((a) => a == null).length > 0;
|
||||
[aa1, aa2, aa3, aa4].where((a) => a != null).length > 0 &&
|
||||
[aa1, aa2, aa3, aa4].where((a) => a == null).length > 0;
|
||||
|
||||
if (someActionsMissing) {
|
||||
validationErrors[serviceId] = "All 3 approver actions must be selected.";
|
||||
@ -329,12 +337,12 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
}
|
||||
if (someExceptionalActionsMissing) {
|
||||
validationErrors[serviceId] =
|
||||
"All 3 exceptional approver actions must be selected.";
|
||||
"All 4 exceptional approver actions must be selected.";
|
||||
return;
|
||||
}
|
||||
if (someAmendActionsMissing) {
|
||||
validationErrors[serviceId] =
|
||||
"All 3 amendment approver actions must be selected.";
|
||||
"All 4 amendment approver actions must be selected.";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -460,6 +468,8 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
setState(() {
|
||||
// ServiceId = widget.selectedTabNotifier.value ?? "1";
|
||||
ServiceId = widget.selectedServiceDBValue;
|
||||
print("ServiceId");
|
||||
print(ServiceId);
|
||||
// Initialize controllers and variables if not present
|
||||
costController.putIfAbsent(ServiceId!, () => TextEditingController());
|
||||
classAction.putIfAbsent((widget.selectedServiceDBValue), () => "1");
|
||||
@ -479,7 +489,8 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
FirstAmendApproverAction.putIfAbsent(ServiceId!, () => "None");
|
||||
SecondAmendApproverAction.putIfAbsent(ServiceId!, () => "None");
|
||||
ThirdAmendApproverAction.putIfAbsent(ServiceId!, () => "None");
|
||||
SelectedParallelAmendProcess.putIfAbsent(ServiceId!, () => "3");
|
||||
FourthAmendApproverAction.putIfAbsent(ServiceId!, () => "None");
|
||||
SelectedParallelAmendProcess.putIfAbsent(ServiceId!, () => "4");
|
||||
});
|
||||
|
||||
widget.onPolicyDataChanged(policyData);
|
||||
@ -1223,7 +1234,8 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -1368,7 +1380,8 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -1517,7 +1530,8 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -1667,7 +1681,8 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -1911,7 +1926,8 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -2056,7 +2072,8 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -2205,7 +2222,8 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(10),
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -2354,6 +2372,161 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
"A4",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
CustomTextFieldUserWrapper(
|
||||
width:
|
||||
MediaQuery.of(
|
||||
context,
|
||||
).size.width *
|
||||
0.12,
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 35,
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem:
|
||||
FourthAmendApproverAction[ServiceId],
|
||||
// enabled: !isViewMode,
|
||||
popupProps: PopupProps.menu(
|
||||
// showSearchBox: true,
|
||||
fit:
|
||||
FlexFit
|
||||
.loose, // Allows flexible height
|
||||
constraints: BoxConstraints(
|
||||
maxHeight: 250,
|
||||
),
|
||||
itemBuilder:
|
||||
(
|
||||
context,
|
||||
item,
|
||||
isSelected,
|
||||
) => Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
vertical: 8.0,
|
||||
),
|
||||
child: Text(
|
||||
item,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
12, // 👈 Smaller text size here
|
||||
color:
|
||||
Colors
|
||||
.black, // You can customize this
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
items: [
|
||||
"Approval",
|
||||
"Notification",
|
||||
"None",
|
||||
],
|
||||
dropdownDecoratorProps:
|
||||
DropDownDecoratorProps(
|
||||
dropdownSearchDecoration:
|
||||
InputDecoration(
|
||||
border:
|
||||
InputBorder.none,
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(
|
||||
horizontal: 1,
|
||||
vertical: 5,
|
||||
),
|
||||
),
|
||||
),
|
||||
dropdownBuilder:
|
||||
(context, selectedItem) =>
|
||||
// Center-align selected item
|
||||
Text(
|
||||
selectedItem ?? "Select",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Color(0xFF114D8B),
|
||||
),
|
||||
),
|
||||
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
// Find the country_code based on selected country_name
|
||||
FourthAmendApproverAction[ServiceId!] =
|
||||
newValue;
|
||||
|
||||
// print("selectedUserType - $selectedUserType");
|
||||
|
||||
// if (selectedCountry!.isNotEmpty) {
|
||||
// errorMessages.remove("country_code");
|
||||
// }
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
SelectedParallelAmendProcess[ServiceId!] =
|
||||
"4";
|
||||
});
|
||||
print(
|
||||
"SelectedParallelAmendProcess - $SelectedParallelAmendProcess[ServiceId]",
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
height: 25,
|
||||
width: 25,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color:
|
||||
((SelectedParallelAmendProcess[ServiceId] ==
|
||||
"1") ||
|
||||
(SelectedParallelAmendProcess[ServiceId] ==
|
||||
"2") ||
|
||||
(SelectedParallelAmendProcess[ServiceId] ==
|
||||
"3") ||
|
||||
(SelectedParallelAmendProcess[ServiceId] ==
|
||||
"4"))
|
||||
? Colors.green
|
||||
: Colors.grey,
|
||||
width: 2,
|
||||
),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.check_circle,
|
||||
size: 20,
|
||||
color:
|
||||
((SelectedParallelAmendProcess[ServiceId] ==
|
||||
"1") ||
|
||||
(SelectedParallelAmendProcess[ServiceId] ==
|
||||
"2") ||
|
||||
(SelectedParallelAmendProcess[ServiceId] ==
|
||||
"3") ||
|
||||
(SelectedParallelAmendProcess[ServiceId] ==
|
||||
"4"))
|
||||
? Colors.green
|
||||
: Colors.grey,
|
||||
// color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -173,6 +173,8 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
|
||||
// Save to SharedPreferences
|
||||
await prefs.setString('layout_color', selectedOrg?['layout_color']);
|
||||
await prefs.setString('secondary_color', selectedOrg?['secondary_color']);
|
||||
await prefs.setString('ternary_color', selectedOrg?['ternary_color']);
|
||||
await prefs.setString('body_color', selectedOrg?['color']);
|
||||
await prefs.setString('body_color', selectedOrg?['plan_action']);
|
||||
|
||||
@ -222,6 +224,8 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
|
||||
// Save to SharedPreferences
|
||||
await prefs.setString('layout_color', selectedOrg?['layout_color']);
|
||||
await prefs.setString('secondary_color', selectedOrg?['secondary_color']);
|
||||
await prefs.setString('ternary_color', selectedOrg?['ternary_color']);
|
||||
await prefs.setString('body_color', selectedOrg?['color']);
|
||||
await prefs.setString('body_color', selectedOrg?['plan_action']);
|
||||
|
||||
@ -473,7 +477,10 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
child: Row(
|
||||
children: [
|
||||
// if (userData?["role"] != "User")
|
||||
Builder(
|
||||
ExcludeFocus(
|
||||
// Focus(
|
||||
// canRequestFocus: false,
|
||||
child:Builder(
|
||||
builder:
|
||||
(context) => PopupMenuButton<String>(
|
||||
color: Colors.white,
|
||||
@ -632,6 +639,7 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
],
|
||||
),
|
||||
@ -645,7 +653,7 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
color: layoutColor, // Set the color of the bottom border
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -128,6 +128,8 @@ class _CustomDrawerState extends State<CustomDrawer> {
|
||||
|
||||
// Save to SharedPreferences
|
||||
await prefs.setString('layout_color', selectedOrg?['layout_color']);
|
||||
await prefs.setString('secondary_color', selectedOrg?['secondary_color']);
|
||||
await prefs.setString('ternary_color', selectedOrg?['ternary_color']);
|
||||
await prefs.setString('body_color', selectedOrg?['color']);
|
||||
await prefs.setString('body_color', selectedOrg?['plan_action']);
|
||||
|
||||
|
||||
@ -19,6 +19,8 @@ class OrganizationSetting extends StatefulWidget {
|
||||
class OrganizationSettingState extends State<OrganizationSetting> {
|
||||
final ApiService apiService = ApiService();
|
||||
Color? layoutColor;
|
||||
Color? secondColor;
|
||||
Color? thridColor;
|
||||
|
||||
String? roleUser = "";
|
||||
|
||||
@ -29,6 +31,9 @@ class OrganizationSettingState extends State<OrganizationSetting> {
|
||||
|
||||
void loadInitialData() async {
|
||||
String? layoutString = await getLayoutColor();
|
||||
String? secondString = await getSecondaryColor();
|
||||
String? thridString = await getTernaryColor();
|
||||
|
||||
// String? bodyStringColor = await getBodyColor();
|
||||
roleUser = await getRoleUser();
|
||||
setState(() {
|
||||
@ -37,6 +42,15 @@ class OrganizationSettingState extends State<OrganizationSetting> {
|
||||
? Color(int.parse(layoutString))
|
||||
: Colors.redAccent;
|
||||
|
||||
secondColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(secondString!))
|
||||
: Colors.orange;
|
||||
|
||||
thridColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(thridString!))
|
||||
: Colors.orangeAccent;
|
||||
// bodyColor =
|
||||
// bodyStringColor != null
|
||||
// ? Color(int.parse(bodyStringColor))
|
||||
|
||||
@ -17,6 +17,16 @@ Future<String?> getLayoutColor() async {
|
||||
return prefs.getString("layout_color");
|
||||
}
|
||||
|
||||
Future<String?> getSecondaryColor() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString("secondary_color");
|
||||
}
|
||||
|
||||
Future<String?> getTernaryColor() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString("ternary_color");
|
||||
}
|
||||
|
||||
Future<String?> getBodyColor() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString("body_color");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user