UI_USR_MNGMT_APPROVER
This commit is contained in:
parent
d2b3b792d9
commit
1b6188c584
@ -52,14 +52,14 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
"Partially Approved",
|
||||
"Approved",
|
||||
"Rejected",
|
||||
"Cancelled"
|
||||
"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();
|
||||
}
|
||||
// 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() {
|
||||
@ -150,8 +150,7 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
checkbackbutton();
|
||||
});
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
|
||||
isLoading = true;
|
||||
});
|
||||
// If token exists, load the dashboard data
|
||||
loadDashboardData();
|
||||
@ -320,25 +319,27 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
|
||||
setState(() {
|
||||
// currentData = selectedView == "Today" ? todayBasedCount : weekBasedCount;
|
||||
typeData = selectedView == "Today"
|
||||
? typeBasedTodayCount
|
||||
: typeBasedWeeklyCount ;
|
||||
statusData = selectedView == "Today"
|
||||
? statusBasedTodayCount
|
||||
: statusBasedWeeklyCount ;
|
||||
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'] ?? {});
|
||||
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
|
||||
@ -403,6 +404,7 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
print("dashboard ..");
|
||||
}
|
||||
}
|
||||
|
||||
String capitalize(String s) => s[0].toUpperCase() + s.substring(1);
|
||||
|
||||
Widget toggleChip(String label) {
|
||||
@ -450,7 +452,7 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
child: Column(
|
||||
children: [
|
||||
Tooltip(
|
||||
message: label ,
|
||||
message: label,
|
||||
child: Image.asset(
|
||||
label == 'Domestic'
|
||||
? 'assets/images/IconsImg/Domestic_new.png'
|
||||
@ -501,7 +503,8 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center, // vertically center everything
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center, // vertically center everything
|
||||
children: [
|
||||
Text(
|
||||
count.toString(),
|
||||
@ -529,8 +532,40 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildCategoryCard(String title, IconData icon, List<String> statusLabels,List<int> values) {
|
||||
Widget statusCardContainer(bool isDesktop, List<Widget> cards) {
|
||||
return isDesktop
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children:
|
||||
cards
|
||||
.map(
|
||||
(card) => Padding(
|
||||
padding: const EdgeInsets.only(right: 12.0),
|
||||
child: card,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children:
|
||||
cards
|
||||
.map(
|
||||
(card) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 12.0),
|
||||
child: card,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildCategoryCard(
|
||||
String title,
|
||||
IconData icon,
|
||||
List<String> statusLabels,
|
||||
List<int> values,
|
||||
) {
|
||||
final statusIcons = [
|
||||
Icons.calendar_today,
|
||||
Icons.assignment,
|
||||
@ -541,9 +576,9 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
|
||||
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(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),
|
||||
];
|
||||
|
||||
@ -584,17 +619,16 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
color: Color(0xFF004A8E),
|
||||
shape: BoxShape.circle,
|
||||
),
|
||||
child: Icon(
|
||||
icon,
|
||||
color: Colors.white,
|
||||
size: 20,
|
||||
),
|
||||
child: Icon(icon, color: Colors.white, size: 20),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Text(title, style: GoogleFonts.poppins(
|
||||
Text(
|
||||
title,
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold
|
||||
),),
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
@ -612,7 +646,9 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
height: 28,
|
||||
decoration: BoxDecoration(
|
||||
color: statusColors[index], // background color
|
||||
borderRadius: BorderRadius.circular(4), // square with slight rounding
|
||||
borderRadius: BorderRadius.circular(
|
||||
4,
|
||||
), // square with slight rounding
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Icon(
|
||||
@ -622,16 +658,20 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(statusLabels[index], style: GoogleFonts.poppins(
|
||||
color: Colors.black87,
|
||||
),),
|
||||
Text(
|
||||
statusLabels[index],
|
||||
style: GoogleFonts.poppins(color: Colors.black87),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(values[index].toString(), style: GoogleFonts.poppins(
|
||||
fontSize: 10,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),),
|
||||
Text(
|
||||
values[index].toString(),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 10,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@ -736,251 +776,383 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
appBar: CustomAppBar(isDesktop: isDesktop),
|
||||
drawer: CustomDrawer(isDesktop: false),
|
||||
body: Padding(
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.symmetric(vertical: 5)
|
||||
: EdgeInsets.zero,
|
||||
padding:
|
||||
isDesktop
|
||||
? const EdgeInsets.symmetric(vertical: 5)
|
||||
: EdgeInsets.zero,
|
||||
child: Center(
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: 1200,
|
||||
),
|
||||
constraints: BoxConstraints(maxWidth: 1200),
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15.0), // ✅ Scroll content padding
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 15.0,
|
||||
), // ✅ Scroll content padding
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
isLoading ? Center(child: CircularProgressIndicator()) :
|
||||
LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// First Row: Toggle Buttons Row
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
isLoading
|
||||
? Center(child: CircularProgressIndicator())
|
||||
: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
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
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
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),
|
||||
),
|
||||
],
|
||||
// First Row: Toggle Buttons Row
|
||||
const SizedBox(height: 10),
|
||||
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"),
|
||||
],
|
||||
),
|
||||
),
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Row(
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Second Row: Domestic & International and Status
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
...typeData.map((item) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
buildTopCard(
|
||||
color: item['value'] == "Domestic"
|
||||
? Color(0xFF0DB04B)
|
||||
: Color(0xFF004A8E),
|
||||
label: item['value'],
|
||||
count: item['count'],
|
||||
bgColor: item['value'] == "Domestic"
|
||||
? const Color(0xFFD6FBE4)
|
||||
: const Color(0xFFD9E8FF),
|
||||
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),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
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,
|
||||
padding: const EdgeInsets.all(
|
||||
15,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
...typeData.map((item) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
buildTopCard(
|
||||
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(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
...statusData.map((item) => statusCard(item['value'], item['count'], isDesktop)).toList(),
|
||||
],
|
||||
const SizedBox(width: 20),
|
||||
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: 10,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment
|
||||
.spaceAround,
|
||||
children: [
|
||||
...statusData
|
||||
.map(
|
||||
(
|
||||
item,
|
||||
) => statusCard(
|
||||
item['value'],
|
||||
item['count'],
|
||||
isDesktop,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
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(
|
||||
color: item['value'] == "Domestic"
|
||||
? const Color(0xFF0DB04B)
|
||||
: const Color(0xFF004A8E),
|
||||
label: item['value'],
|
||||
count: item['count'],
|
||||
bgColor: item['value'] == "Domestic"
|
||||
? const Color(0xFFD6FBE4)
|
||||
: const Color(0xFFD9E8FF),
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius:
|
||||
BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.blueGrey,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
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,
|
||||
padding: const EdgeInsets.all(
|
||||
15,
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
...typeData.map((item) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
buildTopCard(
|
||||
color:
|
||||
item['value'] ==
|
||||
"Domestic"
|
||||
? const Color(
|
||||
0xFF0DB04B,
|
||||
)
|
||||
: const Color(
|
||||
0xFF004A8E,
|
||||
),
|
||||
label:
|
||||
item['value'],
|
||||
count:
|
||||
item['count'],
|
||||
bgColor:
|
||||
item['value'] ==
|
||||
"Domestic"
|
||||
? const Color(
|
||||
0xFFD6FBE4,
|
||||
)
|
||||
: const Color(
|
||||
0xFFD9E8FF,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 23),
|
||||
Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: [
|
||||
...statusData.map((item) => statusCard(item['value'], item['count'], isDesktop)).toList(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
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),
|
||||
Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: [
|
||||
...statusData
|
||||
.map(
|
||||
(
|
||||
item,
|
||||
) => statusCard(
|
||||
item['value'],
|
||||
item['count'],
|
||||
isDesktop,
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Third Row: Flight, Accommodation, Forex
|
||||
isDesktop
|
||||
? 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)),
|
||||
// Third Row: Flight, Accommodation, Forex
|
||||
isDesktop
|
||||
? 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,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: buildCategoryCard(
|
||||
"Flight",
|
||||
Icons.flight,
|
||||
statusLabels,
|
||||
flightData,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: buildCategoryCard(
|
||||
"Accomodation",
|
||||
Icons.hotel_outlined,
|
||||
statusLabels,
|
||||
accommodationData,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: buildCategoryCard(
|
||||
"Forex",
|
||||
Icons.attach_money,
|
||||
statusLabels,
|
||||
forexData,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: buildCategoryCard("Flight", Icons.flight, statusLabels, flightData)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: buildCategoryCard("Accomodation", Icons.hotel_outlined, statusLabels, accommodationData)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: buildCategoryCard("Forex", Icons.attach_money, statusLabels, forexData)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
) ,
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2,11 +2,12 @@ import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class AccomodationListWidget extends StatelessWidget {
|
||||
import '../../utils/auth_utils.dart';
|
||||
|
||||
class AccomodationListWidget extends StatefulWidget {
|
||||
final List<Map<String, dynamic>> accommodationList;
|
||||
final Function(bool, Map<String, dynamic>, String) onOpen;
|
||||
final Function(Map<String, dynamic>) onDeleteAccommodation;
|
||||
|
||||
final Function(String, bool) onAddNew;
|
||||
final bool isViewMode;
|
||||
|
||||
@ -19,12 +20,57 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
required this.isViewMode,
|
||||
});
|
||||
|
||||
@override
|
||||
State<AccomodationListWidget> createState() => _AccomodationListWidgetState();
|
||||
}
|
||||
|
||||
class _AccomodationListWidgetState extends State<AccomodationListWidget> {
|
||||
Color? layoutColor;
|
||||
Color? secondColor;
|
||||
Color? thridColor;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
loadInitialData();
|
||||
}
|
||||
|
||||
void loadInitialData() async {
|
||||
String? layoutString = await getLayoutColor();
|
||||
String? secondString = await getSecondaryColor();
|
||||
String? thridString = await getTernaryColor();
|
||||
|
||||
// String? bodyStringColor = await getBodyColor();
|
||||
|
||||
setState(() {
|
||||
layoutColor =
|
||||
layoutString != null
|
||||
? 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))
|
||||
// : Colors.white;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isDesktop = MediaQuery.of(context).size.width > 1024;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
padding:
|
||||
isDesktop ? const EdgeInsets.all(16.0) : const EdgeInsets.all(5.0),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 16.0),
|
||||
child: Column(
|
||||
@ -34,7 +80,7 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if ((!isDesktop) && accommodationList.isNotEmpty)
|
||||
if ((!isDesktop) && widget.accommodationList.isNotEmpty)
|
||||
Text(
|
||||
" ",
|
||||
style: const TextStyle(
|
||||
@ -44,17 +90,19 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
),
|
||||
|
||||
MouseRegion(
|
||||
cursor: isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
cursor:
|
||||
widget.isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
|
||||
child: GestureDetector(
|
||||
onTap: isViewMode
|
||||
? null
|
||||
: () {
|
||||
print("New data");
|
||||
onAddNew("Accomodation", true);
|
||||
},
|
||||
onTap:
|
||||
widget.isViewMode
|
||||
? null
|
||||
: () {
|
||||
print("New data");
|
||||
widget.onAddNew("Accomodation", true);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
@ -68,7 +116,7 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
Icons.add_circle_sharp,
|
||||
size: 30,
|
||||
color: Color(0xFF114D8B),
|
||||
)
|
||||
),
|
||||
// Container(
|
||||
// decoration: BoxDecoration(
|
||||
// shape: BoxShape.circle,
|
||||
@ -147,9 +195,9 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
// Scroll behavior based on device
|
||||
|
||||
_buildData(context, isDesktop)
|
||||
// Scroll behavior based on device
|
||||
_buildData(context, isDesktop),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -158,7 +206,9 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
|
||||
Widget _buildData(BuildContext context, bool isDesktop) {
|
||||
List<Map<String, dynamic>> filteredList =
|
||||
accommodationList.where((item) => item["is_active"] == "1").toList();
|
||||
widget.accommodationList
|
||||
.where((item) => item["is_active"] == "1")
|
||||
.toList();
|
||||
print("filteredList- $filteredList");
|
||||
|
||||
// String formatDate(String dateString) {
|
||||
@ -191,8 +241,11 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
|
||||
if (hour == 24 && minute == 0) {
|
||||
// 24:00 is treated as 00:00 on the next day
|
||||
dateTime = DateTime(now.year, now.month, now.day)
|
||||
.add(const Duration(days: 1));
|
||||
dateTime = DateTime(
|
||||
now.year,
|
||||
now.month,
|
||||
now.day,
|
||||
).add(const Duration(days: 1));
|
||||
} else {
|
||||
if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
|
||||
throw FormatException("Invalid hour or minute");
|
||||
@ -235,14 +288,18 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
// color: Colors.orange.shade50,
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
blurRadius: 3,
|
||||
offset: Offset(0, 1),
|
||||
),
|
||||
],
|
||||
color: isDesktop ? Colors.white : thridColor,
|
||||
// color: Colors.white,
|
||||
boxShadow:
|
||||
isDesktop
|
||||
? [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
blurRadius: 3,
|
||||
offset: Offset(0, 1),
|
||||
),
|
||||
]
|
||||
: [],
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Colors.white70, // Change color to match your theme
|
||||
@ -251,7 +308,7 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(12),
|
||||
padding: isDesktop ? EdgeInsets.all(12) : EdgeInsets.all(8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -261,26 +318,28 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
Text(
|
||||
item["hotel_name"]!,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: !isDesktop ? Color(0xFF114D8B) : Color(0xFF575A74),)
|
||||
fontSize: 14,
|
||||
fontWeight:
|
||||
isDesktop ? FontWeight.w800 : FontWeight.w500,
|
||||
color: !isDesktop ? Colors.black : Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () => onOpen(true, item, "Accomodation"),
|
||||
onTap: () => widget.onOpen(true, item, "Accomodation"),
|
||||
child: Tooltip(
|
||||
message: 'Edit Accomodation Details',
|
||||
child: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Color(0xFF114D8B),
|
||||
color: isDesktop ? Color(0xFF114D8B) : Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
GestureDetector(
|
||||
onTap: () => onDeleteAccommodation(item),
|
||||
onTap: () => widget.onDeleteAccommodation(item),
|
||||
child: Tooltip(
|
||||
message: 'Delete Accommodation Details',
|
||||
child: Image.asset(
|
||||
@ -293,170 +352,176 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
color: Colors.blueGrey.shade50,
|
||||
),
|
||||
// Divider(color: Colors.blueGrey.shade50),
|
||||
SizedBox(height: 4),
|
||||
isDesktop
|
||||
? Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" DestinationCity",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Check (in) ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Check (out) ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" DestinationCity",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Check (in) ",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Check (out) ",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
isDesktop
|
||||
? Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["destination_city"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["destination_city"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["checkin_date"]!)} ${formatTime(item["checkin_time"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["checkin_date"]!)} ${formatTime(item["checkin_time"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["checkout_date"]!)} ${formatTime(item["checkout_time"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["checkout_date"]!)} ${formatTime(item["checkout_time"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _buildComments(
|
||||
"Comments:", item["comments"] ?? "N/A"),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _buildComments(
|
||||
"Comments:",
|
||||
item["comments"] ?? "N/A",
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
),
|
||||
],
|
||||
)
|
||||
: Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Wrap(
|
||||
spacing: 20, // horizontal space between items
|
||||
runSpacing: 10, // vertical space between rows
|
||||
children: [
|
||||
_buildInfoColumn("City", item["destination_city"]),
|
||||
_buildInfoColumn("Check (In)", "${formatDate(item["checkin_date"]!)} ${formatTime(item["checkin_time"]!)}"),
|
||||
_buildInfoColumn("Check (Out)", "${formatDate(item["checkout_date"]!)} ${formatTime(item["checkout_time"]!)}"),
|
||||
// City - long name handled with flexible space
|
||||
// Expanded(
|
||||
// flex: 3,
|
||||
// child: _buildInfoColumn("City", item["destination_city"]),
|
||||
// ),
|
||||
|
||||
// SizedBox(width: 8),
|
||||
|
||||
// Check In and Check Out stacked right side
|
||||
// Expanded(
|
||||
// flex: 4,
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.end,
|
||||
// children: [
|
||||
// _buildInfoColumn(
|
||||
// "Check In",
|
||||
// "${formatDate(item["checkin_date"]!)} ${formatTime(item["checkin_time"]!)}",
|
||||
// ),
|
||||
// SizedBox(height: 6),
|
||||
// _buildInfoColumn(
|
||||
// "Check Out",
|
||||
// "${formatDate(item["checkout_date"]!)} ${formatTime(item["checkout_time"]!)}",
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
_buildRow(
|
||||
"Destination City",
|
||||
item["destination_city"],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
const Text(
|
||||
"Comment",
|
||||
style: TextStyle(fontWeight: FontWeight.w500),
|
||||
SizedBox(height: 5),
|
||||
_buildDateTimeRow(
|
||||
"Check (in)",
|
||||
formatDate(item["checkin_date"]!),
|
||||
formatTime(item["checkin_time"]!),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
if (item["comments"] != null && item["comments"].toString().trim().isNotEmpty)
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Color(0xFF7098DD), width: 1),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
item["comments"],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
)
|
||||
else
|
||||
const Text( "N/A", style: TextStyle(fontSize: 12), ),
|
||||
],
|
||||
)
|
||||
// Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// _buildRow("City:", item["destination_city"]),
|
||||
// SizedBox(width: 10),
|
||||
// SizedBox(width: 10),
|
||||
// _buildDateTimeRow(
|
||||
// "Check-in:",
|
||||
// formatDate(item["checkin_date"]!),
|
||||
// item["checkin_time"]!,
|
||||
// ),
|
||||
// SizedBox(width: 10),
|
||||
// _buildRow(
|
||||
// "Date(out):", formatDate(item["checkout_date"]!)),
|
||||
// SizedBox(width: 10),
|
||||
// _buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// ],
|
||||
// )
|
||||
SizedBox(height: 5),
|
||||
_buildDateTimeRow(
|
||||
"Check (out)",
|
||||
formatDate(item["checkout_date"]!),
|
||||
formatTime(item["checkout_time"]!),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
_buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
// Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Wrap(
|
||||
// spacing: 20, // horizontal space between items
|
||||
// runSpacing: 10, // vertical space between rows
|
||||
// children: [
|
||||
// _buildInfoColumn("City", item["destination_city"]),
|
||||
// _buildInfoColumn("Check (In)", "${formatDate(item["checkin_date"]!)} ${formatTime(item["checkin_time"]!)}"),
|
||||
// _buildInfoColumn("Check (Out)", "${formatDate(item["checkout_date"]!)} ${formatTime(item["checkout_time"]!)}"),
|
||||
// // City - long name handled with flexible space
|
||||
// // Expanded(
|
||||
// // flex: 3,
|
||||
// // child: _buildInfoColumn("City", item["destination_city"]),
|
||||
// // ),
|
||||
//
|
||||
// // SizedBox(width: 8),
|
||||
//
|
||||
// // Check In and Check Out stacked right side
|
||||
// // Expanded(
|
||||
// // flex: 4,
|
||||
// // child: Column(
|
||||
// // crossAxisAlignment: CrossAxisAlignment.end,
|
||||
// // children: [
|
||||
// // _buildInfoColumn(
|
||||
// // "Check In",
|
||||
// // "${formatDate(item["checkin_date"]!)} ${formatTime(item["checkin_time"]!)}",
|
||||
// // ),
|
||||
// // SizedBox(height: 6),
|
||||
// // _buildInfoColumn(
|
||||
// // "Check Out",
|
||||
// // "${formatDate(item["checkout_date"]!)} ${formatTime(item["checkout_time"]!)}",
|
||||
// // ),
|
||||
// // ],
|
||||
// // ),
|
||||
// // ),
|
||||
// ],
|
||||
// ),
|
||||
// const SizedBox(height: 10),
|
||||
// const Text(
|
||||
// "Comment",
|
||||
// style: TextStyle(fontWeight: FontWeight.w500),
|
||||
// ),
|
||||
// const SizedBox(height: 5),
|
||||
// if (item["comments"] != null && item["comments"].toString().trim().isNotEmpty)
|
||||
// Container(
|
||||
// width: double.infinity,
|
||||
// padding: const EdgeInsets.all(8),
|
||||
// decoration: BoxDecoration(
|
||||
// border: Border.all(color: Color(0xFF7098DD), width: 1),
|
||||
// borderRadius: BorderRadius.circular(6),
|
||||
// ),
|
||||
// child: Text(
|
||||
// item["comments"],
|
||||
// style: const TextStyle(fontSize: 12),
|
||||
// ),
|
||||
// )
|
||||
// else
|
||||
// const Text( "N/A", style: TextStyle(fontSize: 12), ),
|
||||
// ],
|
||||
// )
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -485,31 +550,35 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: exceedsLimit
|
||||
? Tooltip(
|
||||
message: wrapText(value, 50),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade200, // Black background
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
textStyle:
|
||||
TextStyle(color: Colors.black), // Tooltip text color
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(value.substring(0, limit) + "...",
|
||||
child:
|
||||
exceedsLimit
|
||||
? Tooltip(
|
||||
message: wrapText(value, 50),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade200, // Black background
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
color: Colors.black,
|
||||
), // Tooltip text color
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(
|
||||
value.substring(0, limit) + "...",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -531,87 +600,92 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
),
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black87),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// Widget _buildRow(String title, String value) {
|
||||
// // Define character limits based on title
|
||||
// Map<String, int> limits = {
|
||||
// // "Special Request:": 30,
|
||||
// "Comments:": 10,
|
||||
// // Add more keys and limits if needed
|
||||
// };
|
||||
//
|
||||
// int limit = limits[title] ?? 50; // Default limit if title not found
|
||||
// bool exceedsLimit = value.length > limit;
|
||||
//
|
||||
// String wrapText(String text, int maxLineLength) {
|
||||
// final pattern = RegExp('.{1,$maxLineLength}(\\s+|\$)');
|
||||
// return pattern.allMatches(text).map((m) => m.group(0)!).join('\n');
|
||||
// }
|
||||
//
|
||||
// return Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Text(
|
||||
// title,
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Expanded(
|
||||
// child: exceedsLimit
|
||||
// ? Tooltip(
|
||||
// message: wrapText(value, 50),
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.grey.shade200, // Black background
|
||||
// borderRadius: BorderRadius.circular(6),
|
||||
// ),
|
||||
// textStyle:
|
||||
// TextStyle(color: Colors.black), // Tooltip text color
|
||||
// padding: EdgeInsets.all(8),
|
||||
// preferBelow: false,
|
||||
// child: Text(value.substring(0, limit) + "...",
|
||||
// style: TextStyle(fontSize: 12),
|
||||
// overflow: TextOverflow.ellipsis),
|
||||
// )
|
||||
// : Text(
|
||||
// value,
|
||||
// style: TextStyle(fontSize: 12),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
Widget _buildRow(String title, String value) {
|
||||
// Define character limits based on title
|
||||
Map<String, int> limits = {
|
||||
// "Special Request:": 30,
|
||||
"Comments:": 10,
|
||||
// Add more keys and limits if needed
|
||||
};
|
||||
|
||||
// Widget _buildDateTimeRow(String title, String date, String time) {
|
||||
// return Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Text(
|
||||
// title,
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Expanded(
|
||||
// child: Text(
|
||||
// "$date, $time",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
int limit = limits[title] ?? 50; // Default limit if title not found
|
||||
bool exceedsLimit = value.length > limit;
|
||||
|
||||
String wrapText(String text, int maxLineLength) {
|
||||
final pattern = RegExp('.{1,$maxLineLength}(\\s+|\$)');
|
||||
return pattern.allMatches(text).map((m) => m.group(0)!).join('\n');
|
||||
}
|
||||
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
||||
children: [
|
||||
SizedBox(
|
||||
// color: Colors.yellowAccent.shade100,
|
||||
width: 100,
|
||||
child: Expanded(
|
||||
child: Text(
|
||||
title,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Expanded(child: Text(value, style: TextStyle(fontSize: 12))),
|
||||
// Expanded(
|
||||
// child:
|
||||
// exceedsLimit
|
||||
// ? Tooltip(
|
||||
// message: wrapText(value, 50),
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.grey.shade200, // Black background
|
||||
// borderRadius: BorderRadius.circular(6),
|
||||
// ),
|
||||
// textStyle: TextStyle(
|
||||
// color: Colors.black,
|
||||
// ), // Tooltip text color
|
||||
// padding: EdgeInsets.all(8),
|
||||
// preferBelow: false,
|
||||
// child: Text(
|
||||
// value.substring(0, limit) + "...",
|
||||
// style: TextStyle(fontSize: 12),
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// ),
|
||||
// )
|
||||
// : Text(value, style: TextStyle(fontSize: 12)),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDateTimeRow(String title, String date, String time) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: Text(
|
||||
title,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Expanded(
|
||||
child: Text("$date, $time", style: GoogleFonts.poppins(fontSize: 12)),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
|
||||
class FlightListWidget extends StatefulWidget {
|
||||
final bool hasAction;
|
||||
@ -32,6 +33,9 @@ class FlightListWidget extends StatefulWidget {
|
||||
|
||||
class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
ApiService apiService = ApiService();
|
||||
Color? layoutColor;
|
||||
Color? secondColor;
|
||||
Color? thridColor;
|
||||
|
||||
// late Map<String, String> countryMap;
|
||||
Map<String, String> countryMap = {};
|
||||
@ -40,6 +44,36 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
loadCountryList(); // Call your method here
|
||||
loadInitialData();
|
||||
}
|
||||
|
||||
void loadInitialData() async {
|
||||
String? layoutString = await getLayoutColor();
|
||||
String? secondString = await getSecondaryColor();
|
||||
String? thridString = await getTernaryColor();
|
||||
|
||||
// String? bodyStringColor = await getBodyColor();
|
||||
|
||||
setState(() {
|
||||
layoutColor =
|
||||
layoutString != null
|
||||
? 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))
|
||||
// : Colors.white;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> loadCountryList() async {
|
||||
@ -169,7 +203,8 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
// );
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
padding:
|
||||
isDesktop ? const EdgeInsets.all(16.0) : const EdgeInsets.all(5.0),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 16.0),
|
||||
child: Column(
|
||||
@ -192,16 +227,18 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
// Right side: either "Add" icon or nothing
|
||||
if (widget.flightList.isNotEmpty)
|
||||
MouseRegion(
|
||||
cursor: widget.isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
cursor:
|
||||
widget.isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: widget.isViewMode
|
||||
? null
|
||||
: () {
|
||||
widget.onAddNew("Flight", true);
|
||||
print("New data");
|
||||
},
|
||||
onTap:
|
||||
widget.isViewMode
|
||||
? null
|
||||
: () {
|
||||
widget.onAddNew("Flight", true);
|
||||
print("New data");
|
||||
},
|
||||
child: Icon(
|
||||
Icons.add_circle_sharp,
|
||||
size: 30,
|
||||
@ -210,7 +247,7 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
),
|
||||
)
|
||||
else if (!isDesktop)
|
||||
// Centered "No Data Found" message for mobile and empty list
|
||||
// Centered "No Data Found" message for mobile and empty list
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Text(
|
||||
@ -223,8 +260,7 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@ -235,7 +271,6 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Widget _buildData(BuildContext context, bool isDesktop) {
|
||||
@ -347,22 +382,26 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
// color: isDesktop ? Colors.white : Color(0xFFFFF0F5),
|
||||
color: isDesktop ? Colors.white : thridColor,
|
||||
// color: Colors.orange.shade50,
|
||||
color: Colors.white,
|
||||
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
blurRadius: 2,
|
||||
offset: Offset(0, 2), // down
|
||||
),
|
||||
// Top shadow
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
blurRadius: 0.5,
|
||||
offset: Offset(0, -1), // up
|
||||
),
|
||||
],
|
||||
// color: Colors.white,
|
||||
boxShadow:
|
||||
isDesktop
|
||||
? [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
blurRadius: 2,
|
||||
offset: Offset(0, 2), // down
|
||||
),
|
||||
// Top shadow
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
blurRadius: 0.5,
|
||||
offset: Offset(0, -1), // up
|
||||
),
|
||||
]
|
||||
: [],
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Colors.white70, // Change color to match your theme
|
||||
@ -371,49 +410,56 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(12),
|
||||
padding: isDesktop ? EdgeInsets.all(12) : EdgeInsets.all(5),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
tripTypeName ?? "N/A",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: !isDesktop ? Color(0xFF114D8B) : Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () => widget.onOpen(true, item, "Flight"),
|
||||
child: Tooltip(
|
||||
message: 'Edit Flight Details',
|
||||
child: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Color(0xFF114D8B),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||
child: Row(
|
||||
children: [
|
||||
Text(
|
||||
tripTypeName ?? "N/A",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight:
|
||||
isDesktop ? FontWeight.w800 : FontWeight.w500,
|
||||
color: !isDesktop ? Colors.black : Color(0xFF575A74),
|
||||
|
||||
// Color(0xFF114D8B)
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
GestureDetector(
|
||||
onTap: () => widget.onDeleteFlight(item),
|
||||
child: Tooltip(
|
||||
message: 'Delete Flight Details',
|
||||
child: Image.asset(
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Colors.red,
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () => widget.onOpen(true, item, "Flight"),
|
||||
child: Tooltip(
|
||||
message: 'Edit Flight Details',
|
||||
child: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color:
|
||||
isDesktop ? Color(0xFF114D8B) : Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
SizedBox(width: 10),
|
||||
GestureDetector(
|
||||
onTap: () => widget.onDeleteFlight(item),
|
||||
child: Tooltip(
|
||||
message: 'Delete Flight Details',
|
||||
child: Image.asset(
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(color: Colors.blueGrey.shade50),
|
||||
// Divider(color: Colors.blueGrey.shade50),
|
||||
SizedBox(height: 4),
|
||||
if (isDesktop)
|
||||
Row(
|
||||
@ -600,10 +646,9 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
item["trips"] != null &&
|
||||
item["trips"].isNotEmpty)
|
||||
...item["trips"].map<Widget>((trip) {
|
||||
|
||||
String fromPlaceCountry =
|
||||
countryMap[trip["from_place"]?.toString()] ??
|
||||
"Unknown Country";
|
||||
"Unknown Country";
|
||||
|
||||
final parts = fromPlaceCountry.split('\n');
|
||||
final cityAndCode = parts[0];
|
||||
@ -618,7 +663,7 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
|
||||
String toPlaceCountry =
|
||||
countryMap[trip["to_place"]?.toString()] ??
|
||||
"Unknown Country";
|
||||
"Unknown Country";
|
||||
|
||||
final toparts = toPlaceCountry.split('\n');
|
||||
final tocityAndCode = toparts[0];
|
||||
@ -631,41 +676,44 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
final tocity = tocityMatch?.group(1) ?? '';
|
||||
final tocode = tocityMatch?.group(2) ?? '';
|
||||
|
||||
// return Padding(
|
||||
// padding: const EdgeInsets.symmetric(vertical: 6.0),
|
||||
// child: Container(
|
||||
// decoration: BoxDecoration(
|
||||
// border: Border.all(color: Colors.grey.shade300),
|
||||
// borderRadius: BorderRadius.circular(6),
|
||||
// color: Colors.grey.shade50,
|
||||
// ),
|
||||
// padding: const EdgeInsets.all(8),
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// _buildKeyValueRow(
|
||||
// "Class",
|
||||
// getRequestForClass(trip["class"].toString()) ??
|
||||
// "N/A",
|
||||
// ),
|
||||
// _buildKeyValueRow(
|
||||
// "Sector",
|
||||
// "$fromcity ($fromcode), $fromairport → $tocity ($tocode), $toairport",
|
||||
// ),
|
||||
//
|
||||
// _buildKeyValueRow(
|
||||
// "Date",
|
||||
// formatDate(trip["date"] ?? ""),
|
||||
// ),
|
||||
// _buildKeyValueRow(
|
||||
// "Time",
|
||||
// formatTime(trip["time"] ?? ""),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6.0),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.grey.shade300),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
color: Colors.grey.shade50,
|
||||
),
|
||||
padding: const EdgeInsets.all(8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildKeyValueRow(
|
||||
"Class",
|
||||
getRequestForClass(trip["class"].toString()) ??
|
||||
"N/A",
|
||||
),
|
||||
_buildKeyValueRow(
|
||||
"From",
|
||||
"$fromcity ($fromcode), $fromairport ",
|
||||
),
|
||||
_buildKeyValueRow(
|
||||
"To",
|
||||
"$tocity ($tocode), $toairport",
|
||||
),
|
||||
|
||||
_buildKeyValueRow(
|
||||
"Date",
|
||||
formatDate(trip["date"] ?? ""),
|
||||
),
|
||||
_buildKeyValueRow(
|
||||
"Time",
|
||||
formatTime(trip["time"] ?? ""),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// return Padding(
|
||||
// padding: const EdgeInsets.symmetric(vertical: 6.0),
|
||||
@ -701,9 +749,13 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
// ),
|
||||
// ),
|
||||
// const Padding(
|
||||
// padding: EdgeInsets.symmetric(horizontal: 6),
|
||||
// padding: EdgeInsets.symmetric(
|
||||
// horizontal: 6,
|
||||
// ),
|
||||
// child: Image(
|
||||
// image: AssetImage('assets/images/IconsImg/Frame.png'),
|
||||
// image: AssetImage(
|
||||
// 'assets/images/IconsImg/Frame.png',
|
||||
// ),
|
||||
// width: 18,
|
||||
// height: 18,
|
||||
// ),
|
||||
@ -738,68 +790,67 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
// ),
|
||||
// );
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6.0),
|
||||
child: Container(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Wrap(
|
||||
crossAxisAlignment: WrapCrossAlignment.center,
|
||||
spacing: 4,
|
||||
runSpacing: 4,
|
||||
children: [
|
||||
Text(
|
||||
'${getRequestForClass(trip["class"].toString()) ?? "N/A"} (',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
fromcode,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
const Padding(
|
||||
padding: EdgeInsets.symmetric(horizontal: 4),
|
||||
child: Image(
|
||||
image: AssetImage('assets/images/IconsImg/Frame.png'),
|
||||
width: 18,
|
||||
height: 18,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'$tocode)',
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 14,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 6),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'${formatDate(trip["date"] ?? "")} ${formatTime(trip["time"] ?? "")}',
|
||||
textAlign: TextAlign.right,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// return Padding(
|
||||
// padding: const EdgeInsets.symmetric(vertical: 6.0),
|
||||
// child: Container(
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Wrap(
|
||||
// crossAxisAlignment: WrapCrossAlignment.center,
|
||||
// spacing: 4,
|
||||
// runSpacing: 4,
|
||||
// children: [
|
||||
// Text(
|
||||
// '${getRequestForClass(trip["class"].toString()) ?? "N/A"} (',
|
||||
// style: const TextStyle(
|
||||
// fontWeight: FontWeight.bold,
|
||||
// fontSize: 14,
|
||||
// color: Colors.black87,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// fromcode,
|
||||
// style: const TextStyle(
|
||||
// fontWeight: FontWeight.bold,
|
||||
// fontSize: 14,
|
||||
// color: Colors.black87,
|
||||
// ),
|
||||
// ),
|
||||
// const Padding(
|
||||
// padding: EdgeInsets.symmetric(horizontal: 4),
|
||||
// child: Image(
|
||||
// image: AssetImage('assets/images/IconsImg/Frame.png'),
|
||||
// width: 18,
|
||||
// height: 18,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// '$tocode)',
|
||||
// style: const TextStyle(
|
||||
// fontWeight: FontWeight.bold,
|
||||
// fontSize: 14,
|
||||
// color: Colors.black87,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// const SizedBox(height: 6),
|
||||
// Align(
|
||||
// alignment: Alignment.centerRight,
|
||||
// child: Text(
|
||||
// '${formatDate(trip["date"] ?? "")} ${formatTime(trip["time"] ?? "")}',
|
||||
// textAlign: TextAlign.right,
|
||||
// style: const TextStyle(
|
||||
// fontSize: 13,
|
||||
// color: Colors.black87,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
}).toList(),
|
||||
],
|
||||
),
|
||||
@ -816,12 +867,12 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 80, // adjust width as needed
|
||||
width: 70, // adjust width as needed
|
||||
child: Text(
|
||||
"$key:",
|
||||
"$key",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -5,8 +5,9 @@ import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../services/apiService.dart';
|
||||
import '../../utils/auth_utils.dart';
|
||||
|
||||
class ForexListWidget extends StatelessWidget {
|
||||
class ForexListWidget extends StatefulWidget {
|
||||
final List<Map<String, dynamic>> forexList;
|
||||
final Function(bool, Map<String, dynamic>, String) onOpen;
|
||||
final Function(Map<String, dynamic>) onDeleteForex;
|
||||
@ -16,15 +17,60 @@ class ForexListWidget extends StatelessWidget {
|
||||
final Function(String, bool) onAddNew;
|
||||
final bool isViewMode;
|
||||
|
||||
const ForexListWidget(
|
||||
{super.key,
|
||||
required this.forexList,
|
||||
required this.onOpen,
|
||||
required this.onDeleteForex,
|
||||
required this.apiCountryData,
|
||||
required this.onAddNew,
|
||||
required this.apiData,
|
||||
required this.isViewMode});
|
||||
const ForexListWidget({
|
||||
super.key,
|
||||
required this.forexList,
|
||||
required this.onOpen,
|
||||
required this.onDeleteForex,
|
||||
required this.apiCountryData,
|
||||
required this.onAddNew,
|
||||
required this.apiData,
|
||||
required this.isViewMode,
|
||||
});
|
||||
|
||||
@override
|
||||
State<ForexListWidget> createState() => _ForexListWidgetState();
|
||||
}
|
||||
|
||||
class _ForexListWidgetState extends State<ForexListWidget> {
|
||||
Color? layoutColor;
|
||||
Color? secondColor;
|
||||
Color? thridColor;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
loadInitialData();
|
||||
}
|
||||
|
||||
void loadInitialData() async {
|
||||
String? layoutString = await getLayoutColor();
|
||||
String? secondString = await getSecondaryColor();
|
||||
String? thridString = await getTernaryColor();
|
||||
|
||||
// String? bodyStringColor = await getBodyColor();
|
||||
|
||||
setState(() {
|
||||
layoutColor =
|
||||
layoutString != null
|
||||
? 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))
|
||||
// : Colors.white;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -32,7 +78,8 @@ class ForexListWidget extends StatelessWidget {
|
||||
final ApiService apiService = ApiService();
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
padding:
|
||||
isDesktop ? const EdgeInsets.all(16.0) : const EdgeInsets.all(5.0),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 16.0),
|
||||
child: Column(
|
||||
@ -135,26 +182,23 @@ class ForexListWidget extends StatelessWidget {
|
||||
// ],
|
||||
// ),
|
||||
const SizedBox(height: 16),
|
||||
// Scroll behavior based on device
|
||||
|
||||
_buildData(context, isDesktop)
|
||||
// Scroll behavior based on device
|
||||
_buildData(context, isDesktop),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildData(
|
||||
BuildContext context,
|
||||
bool isDesktop,
|
||||
) {
|
||||
Widget _buildData(BuildContext context, bool isDesktop) {
|
||||
final ApiService apiService = ApiService();
|
||||
List<Map<String, dynamic>> filteredList =
|
||||
forexList.where((item) => item["is_active"] == "1").toList();
|
||||
widget.forexList.where((item) => item["is_active"] == "1").toList();
|
||||
print("filteredList- $filteredList");
|
||||
|
||||
List<dynamic> visatypeList = apiData?['visa_type_of_visa'] ?? [];
|
||||
List<dynamic> countryList = apiCountryData ?? [];
|
||||
List<dynamic> visatypeList = widget.apiData?['visa_type_of_visa'] ?? [];
|
||||
List<dynamic> countryList = widget.apiCountryData ?? [];
|
||||
|
||||
String getRequestForVisa(String? specialRequestKey) {
|
||||
if (specialRequestKey == null) return "N/A";
|
||||
@ -209,8 +253,11 @@ class ForexListWidget extends StatelessWidget {
|
||||
|
||||
if (hour == 24 && minute == 0) {
|
||||
// 24:00 is treated as 00:00 on the next day
|
||||
dateTime = DateTime(now.year, now.month, now.day)
|
||||
.add(const Duration(days: 1));
|
||||
dateTime = DateTime(
|
||||
now.year,
|
||||
now.month,
|
||||
now.day,
|
||||
).add(const Duration(days: 1));
|
||||
} else {
|
||||
if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
|
||||
throw FormatException("Invalid hour or minute");
|
||||
@ -231,27 +278,34 @@ class ForexListWidget extends StatelessWidget {
|
||||
itemBuilder: (context, index) {
|
||||
final item = filteredList[index];
|
||||
final double transport = double.tryParse(item["transport"] ?? "0") ?? 0;
|
||||
final double accommodation = double.tryParse(item["accommodation"] ?? "0") ?? 0;
|
||||
final double accommodation =
|
||||
double.tryParse(item["accommodation"] ?? "0") ?? 0;
|
||||
final double telephone = double.tryParse(item["telephone"] ?? "0") ?? 0;
|
||||
final double perdiemAmount = double.tryParse(item["perdiem_amount"] ?? "0") ?? 0;
|
||||
final double perdiemAmount =
|
||||
double.tryParse(item["perdiem_amount"] ?? "0") ?? 0;
|
||||
final double calculatedValue = transport + accommodation + telephone;
|
||||
final String calculatedOtherExpenses = calculatedValue.toStringAsFixed(0);
|
||||
final String calculatedOtherExpenses = calculatedValue.toStringAsFixed(
|
||||
0,
|
||||
);
|
||||
final double finalTotal = calculatedValue + perdiemAmount;
|
||||
|
||||
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(horizontal: 8, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
// color: Colors.orange.shade50,
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
blurRadius: 3,
|
||||
offset: Offset(0, 1),
|
||||
),
|
||||
],
|
||||
// color: Colors.white,
|
||||
color: isDesktop ? Colors.white : thridColor,
|
||||
boxShadow:
|
||||
isDesktop
|
||||
? [
|
||||
BoxShadow(
|
||||
color: Colors.black12,
|
||||
blurRadius: 3,
|
||||
offset: Offset(0, 1),
|
||||
),
|
||||
]
|
||||
: [],
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Colors.white70, // Change color to match your theme
|
||||
@ -260,7 +314,7 @@ class ForexListWidget extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(12),
|
||||
padding: isDesktop ? EdgeInsets.all(12) : EdgeInsets.all(8),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -271,12 +325,12 @@ class ForexListWidget extends StatelessWidget {
|
||||
getRequestForCountry(item["country_code"]!.toString()),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () => onOpen(true, item, "Forex"),
|
||||
onTap: () => widget.onOpen(true, item, "Forex"),
|
||||
child: Tooltip(
|
||||
message: 'Edit Forex Details',
|
||||
child: Image.asset(
|
||||
@ -284,7 +338,7 @@ class ForexListWidget extends StatelessWidget {
|
||||
width: 20,
|
||||
height: 15,
|
||||
// color: Color(0xFF114D8B),
|
||||
color: !isDesktop ? Color(0xFF114D8B) : Color(0xFF575A74)
|
||||
color: !isDesktop ? Colors.black : Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -303,287 +357,307 @@ class ForexListWidget extends StatelessWidget {
|
||||
// ),
|
||||
item['forex_id'] != null
|
||||
? IconButton(
|
||||
icon: Icon(Icons.download,
|
||||
color: Color(0xFF114D8B), size: 18),
|
||||
onPressed: () {
|
||||
print("PDF- ${item['forex_id']}");
|
||||
final forexIdString = item['forex_id'];
|
||||
final id = int.tryParse(forexIdString ?? '');
|
||||
icon: Icon(
|
||||
Icons.download,
|
||||
color: Color(0xFF114D8B),
|
||||
size: 18,
|
||||
),
|
||||
onPressed: () {
|
||||
print("PDF- ${item['forex_id']}");
|
||||
final forexIdString = item['forex_id'];
|
||||
final id = int.tryParse(forexIdString ?? '');
|
||||
|
||||
if (id != null) {
|
||||
apiService.getForexPdfDownload(id);
|
||||
} else {
|
||||
print("Invalid forex_id: $forexIdString");
|
||||
}
|
||||
},
|
||||
)
|
||||
if (id != null) {
|
||||
apiService.getForexPdfDownload(id);
|
||||
} else {
|
||||
print("Invalid forex_id: $forexIdString");
|
||||
}
|
||||
},
|
||||
)
|
||||
: SizedBox.shrink(), // or Container()
|
||||
],
|
||||
),
|
||||
Divider(
|
||||
color: Colors.blueGrey.shade50,
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Divider(color: Colors.blueGrey.shade50),
|
||||
// SizedBox(height: 4),
|
||||
isDesktop
|
||||
? Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Currency",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Duration",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Time Period ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Text(
|
||||
// " Total ",
|
||||
// style: TextStyle(
|
||||
// fontSize: 11, fontFamily: "Archivo"),
|
||||
// )),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Perdiem ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Others ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Total ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Cash ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Card ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Currency",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Duration",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Time Period ",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Text(
|
||||
// " Total ",
|
||||
// style: TextStyle(
|
||||
// fontSize: 11, fontFamily: "Archivo"),
|
||||
// )),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Perdiem ",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Others ",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Total ",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Cash ",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Card ",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
isDesktop
|
||||
? Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["currency"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["duration"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["start_date"]!)} - ${formatDate(item["end_date"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"$perdiemAmount",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"$calculatedOtherExpenses",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"$finalTotal",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["deposit_on_cash"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["deposit_on_card"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _buildComments(
|
||||
"Comments:", item["comments"] ?? "N/A"),
|
||||
),
|
||||
],
|
||||
): Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Top Row (Country, Currency, Total)
|
||||
Wrap(
|
||||
spacing: 20, // horizontal space between items
|
||||
runSpacing: 10, // vertical space between rows
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_infoBlock("Country code", item["country_code"] ?? "N/A"),
|
||||
_infoBlock("Currency", item["currency"] ?? "N/A"),
|
||||
_infoBlock("Total Amount", item["total_amount"]?.toString() ?? "0"),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["currency"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["duration"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["start_date"]!)} - ${formatDate(item["end_date"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"$perdiemAmount",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"$calculatedOtherExpenses",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"$finalTotal",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["deposit_on_cash"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["deposit_on_card"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: _buildComments(
|
||||
"Comments:",
|
||||
item["comments"] ?? "N/A",
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Second Row (Start Date, End Date, Duration)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_infoBlock("Start Date", item["start_date"] ?? "N/A"),
|
||||
_infoBlock("End Date", item["end_date"] ?? "N/A"),
|
||||
_infoBlock("Duration", item["duration"]?.toString() ?? "N/A"),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Comment label
|
||||
Text(
|
||||
"Comment",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
if (item["comments"] != null && item["comments"].toString().trim().isNotEmpty)
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: const Color(0xFF7098DD), width: 1),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
item["comments"] ?? "N/A",
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black87),
|
||||
),
|
||||
)
|
||||
else
|
||||
const Text( "N/A", style: TextStyle(fontSize: 12), ),
|
||||
],
|
||||
),
|
||||
// old code
|
||||
// : Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// _buildRow(
|
||||
// "Currency:",
|
||||
// item["currency"],
|
||||
// ),
|
||||
// // SizedBox(height: 6),
|
||||
// _buildRow(
|
||||
// "Duration:",
|
||||
// item["duration"],
|
||||
// ),
|
||||
// // SizedBox(height: 6),
|
||||
// _buildRow("StartDate:", item["start_date"]!),
|
||||
// _buildRow("EndDate:", item["end_date"]!),
|
||||
// _buildRow("Perdiem:", "$perdiemAmount",),
|
||||
// _buildRow("Others:", "$calculatedOtherExpenses"),
|
||||
// _buildRow("Total:", "$finalTotal"),
|
||||
// _buildRow("Cash:", item["deposit_on_cash"]!),
|
||||
// _buildRow("Card:", item["deposit_on_card"]!),
|
||||
// _buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// ],
|
||||
// ),
|
||||
: Container(
|
||||
color: Colors.white,
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildRow("Currency", item["currency"]),
|
||||
SizedBox(height: 2),
|
||||
_buildRow("Duration", item["duration"]),
|
||||
SizedBox(height: 2),
|
||||
_buildRow(
|
||||
"Time Period",
|
||||
"${formatDate(item["start_date"]!)} - ${formatDate(item["end_date"]!)}",
|
||||
// "${item["start_date"]!} - ${item["end_date"]!}",
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
_buildRow("Perdiem", "$perdiemAmount"),
|
||||
SizedBox(height: 2),
|
||||
_buildRow("Others", "$calculatedOtherExpenses"),
|
||||
SizedBox(height: 2),
|
||||
_buildRow("Total", "$finalTotal"),
|
||||
SizedBox(height: 2),
|
||||
_buildRow("Cash", item["deposit_on_cash"]!),
|
||||
SizedBox(height: 2),
|
||||
_buildRow("Card", item["deposit_on_card"]!),
|
||||
SizedBox(height: 2),
|
||||
_buildRow("Comments", item["comments"] ?? "N/A"),
|
||||
],
|
||||
),
|
||||
),
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// // Top Row (Country, Currency, Total)
|
||||
// Wrap(
|
||||
// spacing: 20, // horizontal space between items
|
||||
// runSpacing: 10, // vertical space between rows
|
||||
// // Row(
|
||||
// // mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// _infoBlock(
|
||||
// "Country code",
|
||||
// item["country_code"] ?? "N/A",
|
||||
// ),
|
||||
// _infoBlock("Currency", item["currency"] ?? "N/A"),
|
||||
// _infoBlock(
|
||||
// "Total Amount",
|
||||
// item["total_amount"]?.toString() ?? "0",
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// const SizedBox(height: 12),
|
||||
//
|
||||
// // Second Row (Start Date, End Date, Duration)
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// _infoBlock(
|
||||
// "Start Date",
|
||||
// item["start_date"] ?? "N/A",
|
||||
// ),
|
||||
// _infoBlock("End Date", item["end_date"] ?? "N/A"),
|
||||
// _infoBlock(
|
||||
// "Duration",
|
||||
// item["duration"]?.toString() ?? "N/A",
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// const SizedBox(height: 16),
|
||||
//
|
||||
// // Comment label
|
||||
// Text(
|
||||
// "Comment",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 14,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// ),
|
||||
// ),
|
||||
// const SizedBox(height: 8),
|
||||
// if (item["comments"] != null &&
|
||||
// item["comments"].toString().trim().isNotEmpty)
|
||||
// Container(
|
||||
// width: double.infinity,
|
||||
// padding: const EdgeInsets.all(12),
|
||||
// decoration: BoxDecoration(
|
||||
// border: Border.all(
|
||||
// color: const Color(0xFF7098DD),
|
||||
// width: 1,
|
||||
// ),
|
||||
// borderRadius: BorderRadius.circular(6),
|
||||
// ),
|
||||
// child: Text(
|
||||
// item["comments"] ?? "N/A",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// color: Colors.black87,
|
||||
// ),
|
||||
// ),
|
||||
// )
|
||||
// else
|
||||
// const Text("N/A", style: TextStyle(fontSize: 12)),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -612,31 +686,35 @@ class ForexListWidget extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(
|
||||
child: exceedsLimit
|
||||
? Tooltip(
|
||||
message: wrapText(value, 50),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade200, // Black background
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
textStyle:
|
||||
TextStyle(color: Colors.black), // Tooltip text color
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(value.substring(0, limit) + "...",
|
||||
child:
|
||||
exceedsLimit
|
||||
? Tooltip(
|
||||
message: wrapText(value, 50),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade200, // Black background
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
color: Colors.black,
|
||||
), // Tooltip text color
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(
|
||||
value.substring(0, limit) + "...",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -660,10 +738,7 @@ class ForexListWidget extends StatelessWidget {
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
),
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black87),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -671,60 +746,59 @@ class ForexListWidget extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
// Widget _buildRow(String title, String value) {
|
||||
// // Define character limits based on title
|
||||
// Map<String, int> limits = {
|
||||
// // "Special Request:": 30,
|
||||
// "Comments:": 10,
|
||||
// // Add more keys and limits if needed
|
||||
// };
|
||||
//
|
||||
// int limit = limits[title] ?? 50; // Default limit if title not found
|
||||
// bool exceedsLimit = value.length > limit;
|
||||
//
|
||||
// String wrapText(String text, int maxLineLength) {
|
||||
// final pattern = RegExp('.{1,$maxLineLength}(\\s+|\$)');
|
||||
// return pattern.allMatches(text).map((m) => m.group(0)!).join('\n');
|
||||
// }
|
||||
//
|
||||
// return Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Text(
|
||||
// title,
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(width: 8),
|
||||
// Expanded(
|
||||
// child: exceedsLimit
|
||||
// ? Tooltip(
|
||||
// message: wrapText(value, 50),
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.grey.shade200, // Black background
|
||||
// borderRadius: BorderRadius.circular(6),
|
||||
// ),
|
||||
// textStyle:
|
||||
// TextStyle(color: Colors.black), // Tooltip text color
|
||||
// padding: EdgeInsets.all(8),
|
||||
// preferBelow: false,
|
||||
// child: Text(value.substring(0, limit) + "...",
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// ),
|
||||
// overflow: TextOverflow.ellipsis),
|
||||
// )
|
||||
// : Text(
|
||||
// value,
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
Widget _buildRow(String title, String value) {
|
||||
// Define character limits based on title
|
||||
Map<String, int> limits = {
|
||||
// "Special Request:": 30,
|
||||
"Comments:": 10,
|
||||
// Add more keys and limits if needed
|
||||
};
|
||||
|
||||
int limit = limits[title] ?? 50; // Default limit if title not found
|
||||
bool exceedsLimit = value.length > limit;
|
||||
|
||||
String wrapText(String text, int maxLineLength) {
|
||||
final pattern = RegExp('.{1,$maxLineLength}(\\s+|\$)');
|
||||
return pattern.allMatches(text).map((m) => m.group(0)!).join('\n');
|
||||
}
|
||||
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: Text(
|
||||
title,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child:
|
||||
exceedsLimit
|
||||
? Tooltip(
|
||||
message: wrapText(value, 50),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade200, // Black background
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
color: Colors.black,
|
||||
), // Tooltip text color
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(
|
||||
value.substring(0, limit) + "...",
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
)
|
||||
: Text(value, style: GoogleFonts.poppins(fontSize: 12)),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -856,7 +856,7 @@ class DynamicItineraryState extends State<DynamicItinerary> {
|
||||
margin: EdgeInsets.only(
|
||||
top: 40,
|
||||
), // Push it down to make room for the tab bar
|
||||
padding: EdgeInsets.all(12),
|
||||
padding: EdgeInsets.only(top: 12, bottom: 12, left: 3, right: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white, // Card background
|
||||
// color: Colors.yellow.shade50, // Card background
|
||||
|
||||
@ -181,7 +181,8 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
"first_approver": selectedFirstApprover,
|
||||
"second_approver": selectedSecondApprover,
|
||||
"third_approver": selectedThirdApprover,
|
||||
"exceptional_approver": selectedExceptionalApprover,
|
||||
"fourth_approver": selectedExceptionalApprover,
|
||||
// "exceptional_approver": selectedExceptionalApprover,
|
||||
"delegated_to_user_id": selectedSubstituteApprover,
|
||||
// "passport_number": controllers["passportNumber"]?.text,
|
||||
// "place_of_issue": controllers["placeOfIssue"]?.text,
|
||||
@ -300,9 +301,14 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
apiselectedUser?["third_approver"]?.toString() ?? "";
|
||||
}
|
||||
|
||||
if (apiselectedUser?["exceptional_approver"] != null) {
|
||||
// if (apiselectedUser?["exceptional_approver"] != null) {
|
||||
// selectedExceptionalApprover =
|
||||
// apiselectedUser?["exceptional_approver"]?.toString() ?? "";
|
||||
// }
|
||||
|
||||
if (apiselectedUser?["fourth_approver"] != null) {
|
||||
selectedExceptionalApprover =
|
||||
apiselectedUser?["exceptional_approver"]?.toString() ?? "";
|
||||
apiselectedUser?["fourth_approver"]?.toString() ?? "";
|
||||
}
|
||||
|
||||
if (apiselectedUser?["delegated_to_user_id"] != null) {
|
||||
@ -1329,9 +1335,11 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
|
||||
print("📨 Response: ${response.body}");
|
||||
|
||||
if(roleId == "4"){ context.go('/listPlan'); }
|
||||
else{ context.go('/listUser'); }
|
||||
|
||||
if (roleId == "4") {
|
||||
context.go('/listPlan');
|
||||
} else {
|
||||
context.go('/listUser');
|
||||
}
|
||||
} else {
|
||||
print("❌ Submission failed. Status: ${response.statusCode}");
|
||||
print("📨 Body: ${response.body}");
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
//api url
|
||||
// const String apiUrl = 'http://localhost/tstat_be';
|
||||
const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be';
|
||||
// const String apiUrl = 'https://apitest.tripapprovaltool.com/tstat_be';
|
||||
// const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be';
|
||||
const String apiUrl = 'https://apitest.tripapprovaltool.com/tstat_be';
|
||||
|
||||
/** Note : Adfactor UAT BE URL
|
||||
* File : web/index.html - change below
|
||||
|
||||
Loading…
Reference in New Issue
Block a user