lastest code with cf23f4f9
This commit is contained in:
parent
cf23f4f936
commit
d2b3b792d9
@ -798,7 +798,12 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
builder: (context, constraints) {
|
||||
double minWidth = isDesktop ? constraints.maxWidth : 1300;
|
||||
|
||||
return ConstrainedBox(
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child:
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(minWidth: minWidth),
|
||||
child: DataTable(
|
||||
dividerThickness: 0.5,
|
||||
@ -811,8 +816,7 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
),
|
||||
columns: [
|
||||
DataColumn(
|
||||
label: Expanded(
|
||||
child: Text(
|
||||
label: Text(
|
||||
'S.NO',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
@ -820,7 +824,6 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
DataColumn(
|
||||
label: Text(
|
||||
@ -930,11 +933,8 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
softWrap: true, // Allows wrapping
|
||||
overflow:
|
||||
TextOverflow
|
||||
.visible, // Ensures full display
|
||||
maxLines: null,
|
||||
softWrap: true,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
DataCell(
|
||||
@ -1164,7 +1164,8 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
),
|
||||
));
|
||||
},
|
||||
);
|
||||
|
||||
@ -1256,12 +1257,6 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
fontWeight:
|
||||
FontWeight.w500,
|
||||
),
|
||||
softWrap:
|
||||
true, // Allows wrapping
|
||||
overflow:
|
||||
TextOverflow
|
||||
.visible, // Ensures full display
|
||||
maxLines: null,
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -1438,7 +1433,7 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
CrossAxisAlignment.end,
|
||||
|
||||
children: [
|
||||
Column(
|
||||
Flexible( child:Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -1451,6 +1446,8 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
fontSize: 10,
|
||||
color: Colors.black87,
|
||||
),
|
||||
// overflow: TextOverflow.ellipsis,
|
||||
// maxLines: 2,
|
||||
),
|
||||
// Text(
|
||||
// // plan.userName.isNotEmpty
|
||||
@ -1472,7 +1469,7 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),),
|
||||
Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
|
||||
1925
lib/Screens/allTrips/list_all_plans_24july2025.dart
Normal file
1925
lib/Screens/allTrips/list_all_plans_24july2025.dart
Normal file
File diff suppressed because it is too large
Load Diff
@ -931,7 +931,12 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
builder: (context, constraints) {
|
||||
double minWidth = isDesktop ? constraints.maxWidth : 1300;
|
||||
|
||||
return ConstrainedBox(
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child:
|
||||
ConstrainedBox(
|
||||
constraints: BoxConstraints(minWidth: minWidth),
|
||||
child: DataTable(
|
||||
dividerThickness: 0.5,
|
||||
@ -1416,7 +1421,7 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
)));
|
||||
},
|
||||
);
|
||||
|
||||
@ -1647,7 +1652,7 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
CrossAxisAlignment.end,
|
||||
|
||||
children: [
|
||||
Column(
|
||||
Flexible( child:Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -1666,7 +1671,7 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),),
|
||||
Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
|
||||
1816
lib/Screens/approvals/approval_list_backup24july2025.dart
Normal file
1816
lib/Screens/approvals/approval_list_backup24july2025.dart
Normal file
File diff suppressed because it is too large
Load Diff
@ -491,14 +491,17 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
}
|
||||
|
||||
Widget statusCard(String label, int count, bool isDesktop) {
|
||||
return Container(
|
||||
return SizedBox(
|
||||
width: isDesktop ? 120 : double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
|
||||
height: isDesktop ? 100 : 100, // fixed height for all cards
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEAF3FB),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center, // vertically center everything
|
||||
children: [
|
||||
Text(
|
||||
count.toString(),
|
||||
@ -508,9 +511,12 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
label,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 12 : 11,
|
||||
@ -519,6 +525,7 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -613,13 +613,13 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: _destinationFocused,
|
||||
isDesktop: isDesktop,
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
: null,//MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
@ -1164,7 +1164,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
_checkInTimeFocusNode.requestFocus();
|
||||
_checkInTimeController.text = "";
|
||||
// _checkInTimeController.text = ""; // pavithra told me. here client reported the issues here thats why.
|
||||
_selectCheckInTime(context);
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
@ -1326,13 +1326,14 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
// CustomTextFieldWrapper
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: _commentsFocus, // Dropdown doesn't use focus
|
||||
isDesktop: isDesktop,
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
: null, // MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
|
||||
@ -647,7 +647,7 @@ class _BusScreenState extends State<BusScreen> {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: _commentsFocus, // Dropdown doesn't use focus
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.34 : null,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -2198,7 +2198,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused:
|
||||
focusStates["_comments"] ?? false, // Dropdown doesn't use focus
|
||||
isDesktop: isDesktop,
|
||||
@ -2301,7 +2301,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused:
|
||||
focusStates["_deliveryLocation"] ??
|
||||
false, // Dropdown doesn't use focus
|
||||
@ -2344,7 +2344,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisAlignment: isDesktop ? MainAxisAlignment.center : MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
alignment: Alignment.bottomLeft,
|
||||
|
||||
@ -1333,7 +1333,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.31
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
: null, // MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
|
||||
@ -309,7 +309,7 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
: null,//MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
@ -432,13 +432,14 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
// CustomTextFieldWrapper
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: _commentsFocus, // Dropdown doesn't use focus
|
||||
isDesktop: isDesktop,
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
: null,//MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
|
||||
@ -603,7 +603,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
: null,//MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
@ -1019,13 +1019,13 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: _commentsFocus, // Dropdown doesn't use focus
|
||||
isDesktop: isDesktop,
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
: null,//MediaQuery.of(context).size.width * 0.66,
|
||||
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
|
||||
@ -456,7 +456,7 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
|
||||
|
||||
return [
|
||||
CustomTextFieldWrapper(
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: _trainNoFocused,
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.32 : null,
|
||||
@ -653,7 +653,8 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
CustomTextFieldWrapper(
|
||||
// CustomTextFieldWrapper
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: _typeOfClassFocus,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 0),
|
||||
isDesktop: isDesktop,
|
||||
@ -1332,7 +1333,7 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: _commentsFocus, // Dropdown doesn't use focus
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.32 : null,
|
||||
|
||||
@ -542,14 +542,14 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: _isHotelNameFocused,
|
||||
isDesktop: isDesktop,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 0),
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
: null,//MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: Focus(
|
||||
@ -586,7 +586,7 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
vertical: 6,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 4.0),
|
||||
padding: const EdgeInsets.only(right: 1.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
@ -927,7 +927,7 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
: null, //MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
|
||||
@ -34,10 +34,15 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// Text(
|
||||
// "Accomodation Booking List",
|
||||
// style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||
// ),
|
||||
if ((!isDesktop) && accommodationList.isNotEmpty)
|
||||
Text(
|
||||
" ",
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
|
||||
MouseRegion(
|
||||
cursor: isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
@ -64,6 +69,24 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
size: 30,
|
||||
color: Color(0xFF114D8B),
|
||||
)
|
||||
// Container(
|
||||
// decoration: BoxDecoration(
|
||||
// shape: BoxShape.circle,
|
||||
// border: Border.all(
|
||||
// color: Color(0xFF114D8B), // Outline color
|
||||
// width: 2, // Outline thickness
|
||||
// ),
|
||||
// ),
|
||||
// height: 30,
|
||||
// width: 30,
|
||||
// child: Center(
|
||||
// child: Icon(
|
||||
// Icons.add,
|
||||
// size: 20,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -240,7 +263,7 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Color(0xFF575A74)),
|
||||
color: !isDesktop ? Color(0xFF114D8B) : Color(0xFF575A74),)
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
@ -251,6 +274,7 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Color(0xFF114D8B),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -263,6 +287,7 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -356,21 +381,82 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
: 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"]!,
|
||||
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"]!)}",
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
_buildRow(
|
||||
"Date(out):", formatDate(item["checkout_date"]!)),
|
||||
SizedBox(width: 10),
|
||||
_buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
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), ),
|
||||
],
|
||||
)
|
||||
// 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"),
|
||||
// ],
|
||||
// )
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -429,78 +515,103 @@ class AccomodationListWidget 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(
|
||||
// Helper widget
|
||||
Widget _buildInfoColumn(String label, String value) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
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(
|
||||
SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
// 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 _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,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
||||
@ -40,6 +40,15 @@ class BusListWidget extends StatelessWidget {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if ((!isDesktop) && busList.isNotEmpty)
|
||||
Text(
|
||||
" ",
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
|
||||
MouseRegion(
|
||||
cursor: isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
@ -65,6 +74,24 @@ class BusListWidget extends StatelessWidget {
|
||||
size: 30,
|
||||
color: Color(0xFF114D8B),
|
||||
)
|
||||
// Container(
|
||||
// decoration: BoxDecoration(
|
||||
// shape: BoxShape.circle,
|
||||
// border: Border.all(
|
||||
// color: Color(0xFF114D8B), // Outline color
|
||||
// width: 2, // Outline thickness
|
||||
// ),
|
||||
// ),
|
||||
// height: 30,
|
||||
// width: 30,
|
||||
// child: Center(
|
||||
// child: Icon(
|
||||
// Icons.add,
|
||||
// size: 20,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -230,6 +257,8 @@ class BusListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
// color: Color(0xFF114D8B),
|
||||
color: !isDesktop ? Color(0xFF114D8B) : Color(0xFF575A74)
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -242,6 +271,7 @@ class BusListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -314,21 +344,70 @@ class BusListWidget extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildRow("From:", item["from"]),
|
||||
SizedBox(width: 10),
|
||||
_buildRow("To:", item["to"]!),
|
||||
SizedBox(width: 10),
|
||||
_buildDateTimeRow(
|
||||
"Date:",
|
||||
formatDate(item["date"]!),
|
||||
formatTime(item["time"]!),
|
||||
// Top Row (Country, Currency, Total)
|
||||
Wrap(
|
||||
spacing: 20, // horizontal space between items
|
||||
runSpacing: 10, // vertical space between rows
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_infoBlock("From", item["from"] ?? "N/A"),
|
||||
_infoBlock("To", item["to"]! ?? "N/A"),
|
||||
_infoBlock("Date",
|
||||
(item["date"] != null && item["time"] != null)
|
||||
? "${formatDate(item["date"]!)} ${formatTime(item["time"]!)}"
|
||||
: "N/A",
|
||||
),
|
||||
_buildRow("Comments:", item["comments"] ?? "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), ),
|
||||
],
|
||||
),
|
||||
// Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// _buildRow("From:", item["from"]),
|
||||
// SizedBox(width: 10),
|
||||
// _buildRow("To:", item["to"]!),
|
||||
// SizedBox(width: 10),
|
||||
// _buildDateTimeRow(
|
||||
// "Date:",
|
||||
// formatDate(item["date"]!),
|
||||
// formatTime(item["time"]!),
|
||||
// ),
|
||||
// _buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// ],
|
||||
// )
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -337,6 +416,34 @@ class BusListWidget extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _infoBlock(String label, String value) {
|
||||
return Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
Widget _buildComments(String title, String value) {
|
||||
// Define character limits based on title
|
||||
Map<String, int> limits = {
|
||||
|
||||
@ -108,6 +108,66 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
}
|
||||
}
|
||||
|
||||
// return Padding(
|
||||
// padding: const EdgeInsets.all(16.0),
|
||||
// child: Container(
|
||||
// margin: const EdgeInsets.only(top: 16.0),
|
||||
// child: Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
// children: [
|
||||
// // Header with title and button
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// Text(
|
||||
// "Flight",
|
||||
// style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||
// ),
|
||||
// widget.flightList.isNotEmpty
|
||||
// ? MouseRegion(
|
||||
// cursor:
|
||||
// widget.isViewMode
|
||||
// ? SystemMouseCursors.forbidden
|
||||
// : SystemMouseCursors.click,
|
||||
// child: GestureDetector(
|
||||
// onTap:
|
||||
// widget.isViewMode
|
||||
// ? null
|
||||
// : () {
|
||||
// widget.onAddNew("Flight", true);
|
||||
// // checkClass();
|
||||
// print("New data");
|
||||
// },
|
||||
// child: Row(
|
||||
// mainAxisSize:
|
||||
// MainAxisSize.min, // Ensures content fits nicely
|
||||
// children: [
|
||||
// // Text(
|
||||
// // "Add New",
|
||||
// // style: TextStyle(fontSize: 13),
|
||||
// // ),
|
||||
// // SizedBox(width: 8), // spacing between icon and text
|
||||
// Icon(
|
||||
// Icons.add_circle_sharp,
|
||||
// size: 30,
|
||||
// color: Color(0xFF114D8B),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// )
|
||||
// : SizedBox.shrink(),
|
||||
// ],
|
||||
// ),
|
||||
// const SizedBox(height: 16),
|
||||
//
|
||||
// // Scroll behavior based on device
|
||||
// _buildData(context, isDesktop),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Container(
|
||||
@ -115,58 +175,67 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Header with title and button
|
||||
// Row: Title (mobile only) + Add Button (conditional)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// Text(
|
||||
// "Flight Booking List",
|
||||
// style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
|
||||
// ),
|
||||
widget.flightList.isNotEmpty
|
||||
? MouseRegion(
|
||||
cursor:
|
||||
widget.isViewMode
|
||||
// Title (optional on desktop or mobile)
|
||||
if ((!isDesktop) && widget.flightList.isNotEmpty)
|
||||
Text(
|
||||
" ",
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
|
||||
// Right side: either "Add" icon or nothing
|
||||
if (widget.flightList.isNotEmpty)
|
||||
MouseRegion(
|
||||
cursor: widget.isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap:
|
||||
widget.isViewMode
|
||||
onTap: widget.isViewMode
|
||||
? null
|
||||
: () {
|
||||
widget.onAddNew("Flight", true);
|
||||
// checkClass();
|
||||
print("New data");
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
// Text(
|
||||
// "Add New",
|
||||
// style: TextStyle(fontSize: 13),
|
||||
// ),
|
||||
// SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(
|
||||
child: Icon(
|
||||
Icons.add_circle_sharp,
|
||||
size: 30,
|
||||
color: Color(0xFF114D8B),
|
||||
),
|
||||
],
|
||||
color: const Color(0xFF114D8B),
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
else if (!isDesktop)
|
||||
// Centered "No Data Found" message for mobile and empty list
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Text(
|
||||
"No Data Found",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Scroll behavior based on device
|
||||
// Actual flight data UI
|
||||
_buildData(context, isDesktop),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Widget _buildData(BuildContext context, bool isDesktop) {
|
||||
@ -313,6 +382,7 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: !isDesktop ? Color(0xFF114D8B) : Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
@ -324,6 +394,7 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Color(0xFF114D8B),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -336,6 +407,7 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -559,40 +631,175 @@ 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(12),
|
||||
// child: Row(
|
||||
// children: [
|
||||
// /// LEFT SIDE: Class and Airport Info
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Row(
|
||||
// children: [
|
||||
// Text(
|
||||
// '${getRequestForClass(trip["class"].toString()) ?? "N/A"} (',
|
||||
// style: const TextStyle(
|
||||
// fontWeight: FontWeight.bold,
|
||||
// fontSize: 14,
|
||||
// color: Colors.black87,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// // fromairport,
|
||||
// fromcode,
|
||||
// style: const TextStyle(
|
||||
// fontWeight: FontWeight.bold,
|
||||
// fontSize: 14,
|
||||
// color: Colors.black87,
|
||||
// ),
|
||||
// ),
|
||||
// const Padding(
|
||||
// padding: EdgeInsets.symmetric(horizontal: 6),
|
||||
// child: Image(
|
||||
// image: AssetImage('assets/images/IconsImg/Frame.png'),
|
||||
// width: 18,
|
||||
// height: 18,
|
||||
// ),
|
||||
// ),
|
||||
// Text(
|
||||
// '$tocode)',
|
||||
// // '$toairport)',
|
||||
// style: const TextStyle(
|
||||
// fontWeight: FontWeight.bold,
|
||||
// fontSize: 14,
|
||||
// color: Colors.black87,
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
//
|
||||
// /// RIGHT SIDE: Date and Time
|
||||
// Expanded(
|
||||
// flex: 1,
|
||||
// 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(
|
||||
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",
|
||||
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,
|
||||
),
|
||||
_buildKeyValueRow(
|
||||
"Sector",
|
||||
"$fromcity ($fromcode), $fromairport → $tocity ($tocode), $toairport",
|
||||
),
|
||||
|
||||
_buildKeyValueRow(
|
||||
"Date",
|
||||
formatDate(trip["date"] ?? ""),
|
||||
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,
|
||||
),
|
||||
),
|
||||
_buildKeyValueRow(
|
||||
"Time",
|
||||
formatTime(trip["time"] ?? ""),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
}).toList(),
|
||||
],
|
||||
),
|
||||
|
||||
@ -39,73 +39,24 @@ class ForexListWidget extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Header with title and button
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
MouseRegion(
|
||||
cursor: isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
|
||||
child: GestureDetector(
|
||||
onTap: isViewMode
|
||||
? null
|
||||
: () {
|
||||
print("New data");
|
||||
onAddNew("Forex", true);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
// Text(
|
||||
// "Add New",
|
||||
// style: TextStyle(fontSize: 13),
|
||||
// ),
|
||||
// SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(
|
||||
Icons.add_circle_sharp,
|
||||
size: 30,
|
||||
color: Color(0xFF114D8B),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
// onPressed: isViewMode
|
||||
// ? null
|
||||
// : () {
|
||||
// print("New data");
|
||||
//
|
||||
// },
|
||||
// child: Row(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// Icon(
|
||||
// Icons.add_circle_sharp,
|
||||
// size: 30,
|
||||
// color: Color(0xFF114D8B),
|
||||
// )
|
||||
// ],
|
||||
// if ((!isDesktop) && forexList.isNotEmpty)
|
||||
// Text(
|
||||
// " ",
|
||||
// style: const TextStyle(
|
||||
// fontSize: 18,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
// MouseRegion(
|
||||
// cursor: isViewMode
|
||||
// ? SystemMouseCursors.forbidden
|
||||
// : SystemMouseCursors.click,
|
||||
// child: ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// foregroundColor: Colors.white,
|
||||
// disabledBackgroundColor: Color(0xFF114D8B),
|
||||
// disabledForegroundColor: Colors.white,
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding:
|
||||
// EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: isViewMode
|
||||
//
|
||||
// child: GestureDetector(
|
||||
// onTap: isViewMode
|
||||
// ? null
|
||||
// : () {
|
||||
// print("New data");
|
||||
@ -115,6 +66,11 @@ class ForexListWidget extends StatelessWidget {
|
||||
// mainAxisSize:
|
||||
// MainAxisSize.min, // Ensures content fits nicely
|
||||
// children: [
|
||||
// // Text(
|
||||
// // "Add New",
|
||||
// // style: TextStyle(fontSize: 13),
|
||||
// // ),
|
||||
// // SizedBox(width: 8), // spacing between icon and text
|
||||
// Icon(
|
||||
// Icons.add_circle_sharp,
|
||||
// size: 30,
|
||||
@ -123,9 +79,61 @@ class ForexListWidget extends StatelessWidget {
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// // onPressed: isViewMode
|
||||
// // ? null
|
||||
// // : () {
|
||||
// // print("New data");
|
||||
// //
|
||||
// // },
|
||||
// // child: Row(
|
||||
// // mainAxisSize: MainAxisSize.min,
|
||||
// // children: [
|
||||
// // Icon(
|
||||
// // Icons.add_circle_sharp,
|
||||
// // size: 30,
|
||||
// // color: Color(0xFF114D8B),
|
||||
// // )
|
||||
// // ],
|
||||
// // ),
|
||||
// ),
|
||||
// // MouseRegion(
|
||||
// // cursor: isViewMode
|
||||
// // ? SystemMouseCursors.forbidden
|
||||
// // : SystemMouseCursors.click,
|
||||
// // child: ElevatedButton(
|
||||
// // style: ElevatedButton.styleFrom(
|
||||
// // backgroundColor: Color(0xFF114D8B),
|
||||
// // foregroundColor: Colors.white,
|
||||
// // disabledBackgroundColor: Color(0xFF114D8B),
|
||||
// // disabledForegroundColor: Colors.white,
|
||||
// // shape: RoundedRectangleBorder(
|
||||
// // borderRadius: BorderRadius.circular(8),
|
||||
// // side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// // ),
|
||||
// // padding:
|
||||
// // EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// // ),
|
||||
// // onPressed: isViewMode
|
||||
// // ? null
|
||||
// // : () {
|
||||
// // print("New data");
|
||||
// // onAddNew("Forex", true);
|
||||
// // },
|
||||
// // child: Row(
|
||||
// // mainAxisSize:
|
||||
// // MainAxisSize.min, // Ensures content fits nicely
|
||||
// // children: [
|
||||
// // Icon(
|
||||
// // Icons.add_circle_sharp,
|
||||
// // size: 30,
|
||||
// // color: Color(0xFF114D8B),
|
||||
// // )
|
||||
// // ],
|
||||
// // ),
|
||||
// // ),
|
||||
// // ),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
// Scroll behavior based on device
|
||||
|
||||
@ -275,21 +283,24 @@ class ForexListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
// color: Color(0xFF114D8B),
|
||||
color: !isDesktop ? Color(0xFF114D8B) : Color(0xFF575A74)
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
GestureDetector(
|
||||
onTap: () => onDeleteForex(item),
|
||||
child: Tooltip(
|
||||
message: 'Delete Forex Details',
|
||||
child: Image.asset(
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
),
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// GestureDetector(
|
||||
// onTap: () => onDeleteForex(item),
|
||||
// child: Tooltip(
|
||||
// message: 'Delete Forex Details',
|
||||
// child: Image.asset(
|
||||
// 'assets/images/IconsImg/delete.png',
|
||||
// width: 20,
|
||||
// height: 15,
|
||||
// color: Colors.red,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
item['forex_id'] != null
|
||||
? IconButton(
|
||||
icon: Icon(Icons.download,
|
||||
@ -495,30 +506,84 @@ class ForexListWidget extends StatelessWidget {
|
||||
"Comments:", item["comments"] ?? "N/A"),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
): 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"),
|
||||
// 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), ),
|
||||
],
|
||||
),
|
||||
// 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"),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -577,59 +642,89 @@ 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(
|
||||
Widget _infoBlock(String label, String value) {
|
||||
return Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
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(
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
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,
|
||||
// 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,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@ -34,51 +34,23 @@ class InsuranceListWidget extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Header with title and button
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
MouseRegion(
|
||||
cursor: isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: isViewMode
|
||||
? null
|
||||
: () {
|
||||
print("New data");
|
||||
onAddNew("Insurance", true);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// if ((!isDesktop) && insuranceList.isNotEmpty)
|
||||
// Text(
|
||||
// "Add New",
|
||||
// style: TextStyle(fontSize: 13),
|
||||
// " ",
|
||||
// style: const TextStyle(
|
||||
// fontSize: 18,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// ),
|
||||
// SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(
|
||||
Icons.add_circle_sharp,
|
||||
size: 30,
|
||||
color: Color(0xFF114D8B),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
// child: ElevatedButton(
|
||||
// style: ElevatedButton.styleFrom(
|
||||
// backgroundColor: Color(0xFF114D8B),
|
||||
// foregroundColor: Colors.white,
|
||||
// disabledBackgroundColor: Color(0xFF114D8B),
|
||||
// disabledForegroundColor: Colors.white,
|
||||
// shape: RoundedRectangleBorder(
|
||||
// borderRadius: BorderRadius.circular(8),
|
||||
// side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// ),
|
||||
// padding:
|
||||
// EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// ),
|
||||
// onPressed: isViewMode
|
||||
// MouseRegion(
|
||||
// cursor: isViewMode
|
||||
// ? SystemMouseCursors.forbidden
|
||||
// : SystemMouseCursors.click,
|
||||
// child: GestureDetector(
|
||||
// onTap: isViewMode
|
||||
// ? null
|
||||
// : () {
|
||||
// print("New data");
|
||||
@ -88,17 +60,53 @@ class InsuranceListWidget extends StatelessWidget {
|
||||
// mainAxisSize:
|
||||
// MainAxisSize.min, // Ensures content fits nicely
|
||||
// children: [
|
||||
// Icon(
|
||||
// Icons.add_circle_sharp,
|
||||
// size: 30,
|
||||
// color: Color(0xFF114D8B),
|
||||
// )
|
||||
// // Text(
|
||||
// // "Add New",
|
||||
// // style: TextStyle(fontSize: 13),
|
||||
// // ),
|
||||
// // SizedBox(width: 8), // spacing between icon and text
|
||||
// // Icon(
|
||||
// // Icons.add_circle_sharp,
|
||||
// // size: 30,
|
||||
// // color: Color(0xFF114D8B),
|
||||
// // )
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
],
|
||||
),
|
||||
// // child: ElevatedButton(
|
||||
// // style: ElevatedButton.styleFrom(
|
||||
// // backgroundColor: Color(0xFF114D8B),
|
||||
// // foregroundColor: Colors.white,
|
||||
// // disabledBackgroundColor: Color(0xFF114D8B),
|
||||
// // disabledForegroundColor: Colors.white,
|
||||
// // shape: RoundedRectangleBorder(
|
||||
// // borderRadius: BorderRadius.circular(8),
|
||||
// // side: BorderSide(color: Color(0xFF114D8B), width: 2),
|
||||
// // ),
|
||||
// // padding:
|
||||
// // EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
// // ),
|
||||
// // onPressed: isViewMode
|
||||
// // ? null
|
||||
// // : () {
|
||||
// // print("New data");
|
||||
// // onAddNew("Insurance", true);
|
||||
// // },
|
||||
// // child: Row(
|
||||
// // mainAxisSize:
|
||||
// // MainAxisSize.min, // Ensures content fits nicely
|
||||
// // children: [
|
||||
// // Icon(
|
||||
// // Icons.add_circle_sharp,
|
||||
// // size: 30,
|
||||
// // color: Color(0xFF114D8B),
|
||||
// // )
|
||||
// // ],
|
||||
// // ),
|
||||
// // ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
const SizedBox(height: 16),
|
||||
// Scroll behavior based on device
|
||||
|
||||
@ -197,6 +205,7 @@ class InsuranceListWidget extends StatelessWidget {
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: !isDesktop ? Color(0xFF114D8B) : Color(0xFF575A74)
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
@ -208,21 +217,23 @@ class InsuranceListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Color(0xFF114D8B),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
GestureDetector(
|
||||
onTap: () => onDeleteInsurance(item),
|
||||
child: Tooltip(
|
||||
message: 'Delete Insurance Details',
|
||||
child: Image.asset(
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
),
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 10),
|
||||
// GestureDetector(
|
||||
// onTap: () => onDeleteInsurance(item),
|
||||
// child: Tooltip(
|
||||
// message: 'Delete Insurance Details',
|
||||
// child: Image.asset(
|
||||
// 'assets/images/IconsImg/delete.png',
|
||||
// width: 20,
|
||||
// height: 15,
|
||||
// color: Colors.red,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
@ -293,21 +304,65 @@ class InsuranceListWidget extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildRow(
|
||||
"InsuranceType:",
|
||||
getRequestForInsuranceType(
|
||||
item["type_of_insurance"]!.toString())),
|
||||
SizedBox(width: 10),
|
||||
_buildRow(
|
||||
"StartDate:", formatDate(item["start_date"]!)),
|
||||
SizedBox(width: 10),
|
||||
_buildRow("EndDate:", formatDate(item["end_date"])),
|
||||
SizedBox(width: 10),
|
||||
_buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// Top Row (Country, Currency, Total)
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
Wrap(
|
||||
spacing: 20, // horizontal space between items
|
||||
runSpacing: 10, // vertical space between rows
|
||||
children: [
|
||||
_infoBlock("Insurance Type", getRequestForInsuranceType(item["type_of_insurance"]!.toString()) ?? "N/A"),
|
||||
_infoBlock("Start Date", formatDate(item["start_date"]!) ?? "N/A"),
|
||||
_infoBlock("End Date", formatDate(item["end_date"]) ?? "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), ),
|
||||
],
|
||||
),
|
||||
// Column(
|
||||
// children: [
|
||||
// _buildRow(
|
||||
// "InsuranceType:",
|
||||
// getRequestForInsuranceType(
|
||||
// item["type_of_insurance"]!.toString())),
|
||||
// SizedBox(width: 10),
|
||||
// _buildRow(
|
||||
// "StartDate:", formatDate(item["start_date"]!)),
|
||||
// SizedBox(width: 10),
|
||||
// _buildRow("EndDate:", formatDate(item["end_date"])),
|
||||
// SizedBox(width: 10),
|
||||
// _buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -366,6 +421,34 @@ class InsuranceListWidget extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _infoBlock(String label, String value) {
|
||||
return Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
Widget _buildRow(String title, String value) {
|
||||
// Define character limits based on title
|
||||
Map<String, int> limits = {
|
||||
|
||||
@ -26,16 +26,22 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Container(
|
||||
// color: Color(0xFFE8F0FC),
|
||||
margin: const EdgeInsets.only(top: 28.0),
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
margin: const EdgeInsets.only(top: 16.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// Header with title and button
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if ((!isDesktop) && miscellaneousList.isNotEmpty)
|
||||
Text(
|
||||
" ",
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
MouseRegion(
|
||||
cursor:
|
||||
isViewMode
|
||||
@ -58,24 +64,29 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
// style: TextStyle(fontSize: 13),
|
||||
// ),
|
||||
// SizedBox(width: 8), // spacing between icon and text
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
border: Border.all(
|
||||
color: Color(0xFF114D8B), // Outline color
|
||||
width: 2, // Outline thickness
|
||||
),
|
||||
),
|
||||
height: 30,
|
||||
width: 30,
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.add,
|
||||
size: 20,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
Icons.add_circle_sharp,
|
||||
size: 30,
|
||||
color: Color(0xFF114D8B),
|
||||
),
|
||||
// Container(
|
||||
// decoration: BoxDecoration(
|
||||
// shape: BoxShape.circle,
|
||||
// border: Border.all(
|
||||
// color: Color(0xFF114D8B), // Outline color
|
||||
// width: 2, // Outline thickness
|
||||
// ),
|
||||
// ),
|
||||
// height: 30,
|
||||
// width: 30,
|
||||
// child: Center(
|
||||
// child: Icon(
|
||||
// Icons.add,
|
||||
// size: 20,
|
||||
// color: Colors.black,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -174,8 +185,7 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
getRequestValue(item["special_request"]?.toString()),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
color: Color(0xFF114D8B),
|
||||
fontWeight: FontWeight.w500,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
@ -187,6 +197,7 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Color(0xFF114D8B),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -200,45 +211,37 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// Divider(color: Colors.blueGrey.shade50),
|
||||
SizedBox(height: 10),
|
||||
Divider(color: Colors.blueGrey.shade50),
|
||||
SizedBox(height: 4),
|
||||
isDesktop
|
||||
? Row(
|
||||
children: [
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Text(
|
||||
// "Special Request",
|
||||
// style: GoogleFonts.poppins(fontSize: 11),
|
||||
// ),
|
||||
// ),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Special Request",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
SizedBox(height: 4),
|
||||
isDesktop
|
||||
? Container(
|
||||
// color: Color(0xFFE8F0FC),
|
||||
color: Colors.white,
|
||||
child: Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
// : SizedBox.shrink(),
|
||||
// isDesktop
|
||||
// ? Row(
|
||||
// children: [
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Text(
|
||||
@ -251,32 +254,58 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// Expanded(
|
||||
// flex: 3,
|
||||
// child: Text(
|
||||
// item["comments"],
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// )
|
||||
:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 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: MediaQuery.of(context).size.width * 0.6,
|
||||
// padding: EdgeInsets.all(16),
|
||||
// color: Color(0xFFE8F0FC),
|
||||
child: Expanded(
|
||||
// flex: 1,
|
||||
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"],
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
item["comments"] ?? "N/A",
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black87),
|
||||
),
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
_buildRow(
|
||||
"Special Request:",
|
||||
getRequestValue(item["special_request"]?.toString()),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
_buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
else
|
||||
const Text( "N/A", style: TextStyle(fontSize: 12), ),
|
||||
],
|
||||
),
|
||||
// Column(
|
||||
// children: [
|
||||
// _buildRow(
|
||||
// "Special Request:",
|
||||
// getRequestValue(item["special_request"]?.toString()),
|
||||
// ),
|
||||
// SizedBox(width: 10),
|
||||
// _buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -36,6 +36,14 @@ class TaxiListWidget extends StatelessWidget {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if ((!isDesktop) && taxiList.isNotEmpty)
|
||||
Text(
|
||||
" ",
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
MouseRegion(
|
||||
cursor:
|
||||
isViewMode
|
||||
@ -248,6 +256,7 @@ class TaxiListWidget extends StatelessWidget {
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: !isDesktop ? Color(0xFF114D8B) : Color(0xFF575A74)
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
@ -259,6 +268,7 @@ class TaxiListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Color(0xFF114D8B),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -271,6 +281,7 @@ class TaxiListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -358,22 +369,72 @@ class TaxiListWidget extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildRow("City:", item["destination_city"]),
|
||||
SizedBox(width: 10),
|
||||
_buildRow("Pickup:", item["location_of_pickup"]!),
|
||||
SizedBox(width: 10),
|
||||
_buildDateTimeRow(
|
||||
"Date:",
|
||||
formatDate(item["date"]!),
|
||||
formatTime(item["time"]!),
|
||||
),
|
||||
_buildRow("TaxiFor:", item["car_required_for"]!),
|
||||
_buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// First row: City & Location
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_infoColumn("City", item["destination_city"] ?? "N/A"),
|
||||
_infoColumn("Location", item["location_of_pickup"] ?? "N/A",alignEnd: true),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Second row: Date & Time
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_infoColumn("Date", "${formatDate(item["date"]!)}" ?? "N/A"),
|
||||
_infoColumn("Time", "${formatTime(item["time"]!)}" ?? "N/A",alignEnd: true),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Comment label
|
||||
Text(
|
||||
"Comment",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
// Comment box
|
||||
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), ),
|
||||
|
||||
] )
|
||||
// Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// _buildRow("City:", item["destination_city"]),
|
||||
// SizedBox(width: 10),
|
||||
// _buildRow("Pickup:", item["location_of_pickup"]!),
|
||||
// SizedBox(width: 10),
|
||||
// _buildDateTimeRow(
|
||||
// "Date:",
|
||||
// formatDate(item["date"]!),
|
||||
// formatTime(item["time"]!),
|
||||
// ),
|
||||
// _buildRow("TaxiFor:", item["car_required_for"]!),
|
||||
// _buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -501,4 +562,30 @@ class TaxiListWidget extends StatelessWidget {
|
||||
],
|
||||
);
|
||||
}
|
||||
Widget _infoColumn(String label, String value, {bool alignEnd = false}) {
|
||||
return Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
alignEnd ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -109,6 +109,14 @@ class _TrainListWidgetState extends State<TrainListWidget> {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if ((!isDesktop))
|
||||
Text(
|
||||
" ",
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
MouseRegion(
|
||||
cursor:
|
||||
widget.isViewMode
|
||||
@ -335,6 +343,7 @@ class _TrainListWidgetState extends State<TrainListWidget> {
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: !isDesktop ? Color(0xFF114D8B) : Color(0xFF575A74)
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
@ -346,6 +355,7 @@ class _TrainListWidgetState extends State<TrainListWidget> {
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Color(0xFF114D8B),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -358,6 +368,7 @@ class _TrainListWidgetState extends State<TrainListWidget> {
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -528,23 +539,74 @@ class _TrainListWidgetState extends State<TrainListWidget> {
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildRow(
|
||||
"Class:",
|
||||
getRequestForTrainClass(item["class"]!.toString()),
|
||||
),
|
||||
_buildRow("From:", item["from_station"]!),
|
||||
_buildRow("To:", item["to_station"]!),
|
||||
_buildDateTimeRow(
|
||||
"Date:",
|
||||
formatDate(item["date"]!),
|
||||
formatTime(item["time"]!),
|
||||
),
|
||||
_buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// First row: City & Location
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_infoColumn("Class", getRequestForTrainClass(item["class"]!.toString()) ?? "N/A"),
|
||||
_infoColumn("From", item["from_station"]! ?? "N/A"),
|
||||
_infoColumn("To", item["to_station"]! ?? "N/A",alignEnd: true),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Second row: Date & Time
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_infoColumn("Date", "${formatDate(item["date"]!)}" ?? "N/A"),
|
||||
_infoColumn("Time", "${formatTime(item["time"]!)}" ?? "N/A",alignEnd: true),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Comment label
|
||||
Text(
|
||||
"Comment",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
// Comment box
|
||||
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), ),
|
||||
|
||||
] )
|
||||
// Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// _buildRow(
|
||||
// "Class:",
|
||||
// getRequestForTrainClass(item["class"]!.toString()),
|
||||
// ),
|
||||
// _buildRow("From:", item["from_station"]!),
|
||||
// _buildRow("To:", item["to_station"]!),
|
||||
// _buildDateTimeRow(
|
||||
// "Date:",
|
||||
// formatDate(item["date"]!),
|
||||
// formatTime(item["time"]!),
|
||||
// ),
|
||||
// _buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -659,6 +721,31 @@ class _TrainListWidgetState extends State<TrainListWidget> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _infoColumn(String label, String value, {bool alignEnd = false}) {
|
||||
return Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment:
|
||||
alignEnd ? CrossAxisAlignment.end : CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
Widget _buildDateTimeRow(String title, String date, String time) {
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
||||
@ -37,6 +37,14 @@ class VisaListWidget extends StatelessWidget {
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
if ((!isDesktop) && visaList.isNotEmpty)
|
||||
Text(
|
||||
" ",
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
MouseRegion(
|
||||
cursor: isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
@ -58,11 +66,11 @@ class VisaListWidget extends StatelessWidget {
|
||||
// style: TextStyle(fontSize: 13),
|
||||
// ),
|
||||
// SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(
|
||||
Icons.add_circle_sharp,
|
||||
size: 30,
|
||||
color: Color(0xFF114D8B),
|
||||
)
|
||||
// Icon(
|
||||
// Icons.add_circle_sharp,
|
||||
// size: 30,
|
||||
// color: Color(0xFF114D8B),
|
||||
// )
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -296,6 +304,7 @@ class VisaListWidget extends StatelessWidget {
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: !isDesktop ? Color(0xFF114D8B) : Color(0xFF575A74)
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
@ -307,6 +316,7 @@ class VisaListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Color(0xFF114D8B),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -319,6 +329,7 @@ class VisaListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -411,24 +422,68 @@ class VisaListWidget extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildRow(
|
||||
"VisaType:",
|
||||
getRequestForVisa(
|
||||
item["type_of_visa"]!.toString())),
|
||||
SizedBox(height: 6),
|
||||
_buildRow(
|
||||
"Country:",
|
||||
getRequestForCountry(
|
||||
item["country_code"]!.toString())),
|
||||
SizedBox(height: 6),
|
||||
_buildRow("StartDate:", item["start_date"]!),
|
||||
SizedBox(height: 6),
|
||||
_buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// Top Row (Country, Currency, Total)
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
Wrap(
|
||||
spacing: 20, // horizontal space between items
|
||||
runSpacing: 10, // vertical space between rows
|
||||
children: [
|
||||
_infoBlock("Visa Type", getRequestForCountry(item["country_code"]!.toString()) ?? "N/A"),
|
||||
_infoBlock("Country", getRequestForCountry(item["country_code"]!.toString()) ?? "N/A"),
|
||||
_infoBlock("Start Date", formatDate(item["start_date"]!) ?? "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), ),
|
||||
],
|
||||
),
|
||||
// Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// _buildRow(
|
||||
// "VisaType:",
|
||||
// getRequestForVisa(
|
||||
// item["type_of_visa"]!.toString())),
|
||||
// SizedBox(height: 6),
|
||||
// _buildRow(
|
||||
// "Country:",
|
||||
// getRequestForCountry(
|
||||
// item["country_code"]!.toString())),
|
||||
// SizedBox(height: 6),
|
||||
// _buildRow("StartDate:", item["start_date"]!),
|
||||
// SizedBox(height: 6),
|
||||
// _buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -487,6 +542,34 @@ class VisaListWidget extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _infoBlock(String label, String value) {
|
||||
return Expanded(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 12),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 4),
|
||||
Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
Widget _buildRow(String title, String value) {
|
||||
// Define character limits based on title
|
||||
Map<String, int> limits = {
|
||||
|
||||
@ -72,9 +72,13 @@ class _ListPlansState extends State<ListPlans> {
|
||||
print(roleUser);
|
||||
if (roleUser == "User") {
|
||||
print("user");
|
||||
// Push a dummy state so back button triggers popstate instead of navigating
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final String? msUserStr = prefs.getString('is_microsoft_user');
|
||||
final bool msUser = msUserStr?.toLowerCase() == 'true';
|
||||
print("msUser - $msUser");
|
||||
html.window.history.pushState(null, '', html.window.location.href);
|
||||
|
||||
if(!msUser){
|
||||
_popStateListener = html.window.onPopState.listen((event) {
|
||||
if (!_dialogShown && mounted) {
|
||||
_showBackConfirmationDialog();
|
||||
@ -85,6 +89,7 @@ class _ListPlansState extends State<ListPlans> {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
@ -955,7 +960,11 @@ class _ListPlansState extends State<ListPlans> {
|
||||
builder: (context, constraints) {
|
||||
double minWidth = isDesktop ? constraints.maxWidth : 1300;
|
||||
|
||||
return ConstrainedBox(
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child:ConstrainedBox(
|
||||
constraints: BoxConstraints(minWidth: minWidth),
|
||||
child: DataTable(
|
||||
dividerThickness: 0.5,
|
||||
@ -1361,7 +1370,7 @@ class _ListPlansState extends State<ListPlans> {
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
)));
|
||||
},
|
||||
);
|
||||
|
||||
@ -1859,7 +1868,7 @@ class _ListPlansState extends State<ListPlans> {
|
||||
CrossAxisAlignment.end,
|
||||
|
||||
children: [
|
||||
Column(
|
||||
Flexible( child:Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -1881,7 +1890,7 @@ class _ListPlansState extends State<ListPlans> {
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),),
|
||||
Column(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.end,
|
||||
|
||||
2031
lib/Screens/plans/list_plans_backup24july2025.dart
Normal file
2031
lib/Screens/plans/list_plans_backup24july2025.dart
Normal file
File diff suppressed because it is too large
Load Diff
@ -50,10 +50,12 @@ class _PolicyState extends State<Policy> {
|
||||
Color? layoutColor;
|
||||
Color? bodyColor;
|
||||
late String policyType = "domestic";
|
||||
String selectedServiceDBValue = '1';
|
||||
// String selectedServiceDBValue = '1';
|
||||
List<int> serviceDBValueList = [];
|
||||
ValueNotifier<String> selectedServiceIndex = ValueNotifier("1");
|
||||
ValueNotifier<String> selectedServicePriorityIndex = ValueNotifier("1");
|
||||
String selectedService = "train";
|
||||
ValueNotifier<String> selectedServiceDBValue = ValueNotifier("0");
|
||||
String? selectedService;
|
||||
// ValueNotifier<String> selectedService = ValueNotifier("Train");
|
||||
bool isViewMode = false;
|
||||
bool isDisable = false;
|
||||
@ -101,6 +103,7 @@ class _PolicyState extends State<Policy> {
|
||||
});
|
||||
}).toList();
|
||||
|
||||
|
||||
Map<String, dynamic> data = {
|
||||
"name": _policyController.text,
|
||||
"domestic": SelectedDomestic,
|
||||
@ -152,7 +155,6 @@ class _PolicyState extends State<Policy> {
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
void _addFocusListener(FocusNode node, Function(bool) updateState) {
|
||||
node.addListener(() {
|
||||
setState(() {
|
||||
@ -160,7 +162,6 @@ class _PolicyState extends State<Policy> {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void _checkAuthAndLoadData() async {
|
||||
final String? token = await getToken(); // Your async function to get token
|
||||
|
||||
@ -175,19 +176,33 @@ class _PolicyState extends State<Policy> {
|
||||
try {
|
||||
loadinitializeData();
|
||||
|
||||
updateSelectedServices();
|
||||
await updateSelectedServices();
|
||||
updateData();
|
||||
|
||||
loadInitialData();
|
||||
|
||||
|
||||
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (widget.policy != null) {
|
||||
final details = List<Map<String, dynamic>>.from(
|
||||
widget.policy!['policy_details'],
|
||||
);
|
||||
policyCriteriaKey.currentState?.loadPolicyDetails(details);
|
||||
|
||||
policyCriteriaKey.currentState?.fetchTrainFlightClass();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// if (widget.policy != null) {
|
||||
// print("185");
|
||||
// final details = List<Map<String, dynamic>>.from(
|
||||
// widget.policy!['policy_details'],
|
||||
// );
|
||||
// policyCriteriaKey.currentState?.loadPolicyDetails(details);
|
||||
//
|
||||
// policyCriteriaKey.currentState?.fetchTrainFlightClass();
|
||||
// }
|
||||
} catch (e) {
|
||||
print("group : $e");
|
||||
}
|
||||
@ -261,24 +276,32 @@ class _PolicyState extends State<Policy> {
|
||||
}
|
||||
|
||||
Future<void> updateSelectedServices() async {
|
||||
print("started");
|
||||
await loadAllServices();
|
||||
await loadOrgSelectedAlServices();
|
||||
|
||||
print("III-end");
|
||||
final selectedIds =
|
||||
selectedOrgServiceIds.map((e) => e['service_id']).toSet();
|
||||
|
||||
if (widget.policy != null) {
|
||||
print("inside if");
|
||||
print(widget.policy);
|
||||
final details = List<Map<String, dynamic>>.from(
|
||||
widget.policy!['policy_details'],
|
||||
);
|
||||
print("****details-$details");
|
||||
|
||||
print(
|
||||
"UUFiltered Selected Services - ${widget.policy!['services_ids']} ",
|
||||
);
|
||||
// pr int("UUFiltered Selected Services - $details");
|
||||
|
||||
final exisitingService = List<Map<String, dynamic>>.from(
|
||||
jsonDecode(widget.policy!['services_ids']),
|
||||
);
|
||||
print("exisitingService ${exisitingService}");
|
||||
|
||||
final filtered =
|
||||
selectedAllServices!
|
||||
exisitingService!
|
||||
.where(
|
||||
(service) =>
|
||||
selectedIds.contains(service['service_id'].toString()),
|
||||
@ -288,18 +311,35 @@ class _PolicyState extends State<Policy> {
|
||||
setState(() {
|
||||
ServicesChoosed = filtered;
|
||||
});
|
||||
print("298 ServicesChoosed ${ServicesChoosed}");
|
||||
|
||||
|
||||
print("Filtered Selected Services ChooesedIpfa1: $ServicesChoosed");
|
||||
|
||||
if (ServicesChoosed!.isNotEmpty) {
|
||||
String firstServiceName = ServicesChoosed?.first['name'];
|
||||
print("✅ First service name selected for filter: $firstServiceName");
|
||||
selectedService = firstServiceName;
|
||||
// services = ServicesChoosed!
|
||||
// .map((service) => service['name'].toString())
|
||||
// .toList();
|
||||
}
|
||||
print("Filtered Selected Services ChooesedIpfa1: $ServicesChoosed");
|
||||
|
||||
|
||||
ServicesChoosed!.sort(
|
||||
(a, b) => (a['order'] ?? 0).compareTo(b['order'] ?? 0),
|
||||
);
|
||||
String firstServiceName = ServicesChoosed?.first['name'];
|
||||
String firstServiceId = ServicesChoosed?.first['service_id'];
|
||||
|
||||
print("✅ 306 First service name selected for filter: $firstServiceName - $firstServiceId");
|
||||
selectedService = firstServiceName;
|
||||
if (selectedServiceDBValue.value == "0") {
|
||||
setState(() {
|
||||
selectedServiceDBValue.value = firstServiceId.toString();
|
||||
});
|
||||
}
|
||||
List<int> serviceDBvalue = ServicesChoosed!
|
||||
.map((item) => int.parse(item['service_id'].toString()))
|
||||
.toList();
|
||||
serviceDBValueList = serviceDBvalue;
|
||||
|
||||
}
|
||||
print(widget.policy);
|
||||
// updateData();
|
||||
if (widget.policy != null && widget.policy!['services_ids'] != null) {
|
||||
final decoded = jsonDecode(widget.policy!['services_ids']);
|
||||
|
||||
@ -317,10 +357,14 @@ class _PolicyState extends State<Policy> {
|
||||
});
|
||||
|
||||
print("✅ Loaded services from policy (decoded): $services");
|
||||
|
||||
|
||||
}
|
||||
|
||||
print("Filtered Selected Services Added to Policy: $ServicesChoosed");
|
||||
} else {
|
||||
|
||||
}
|
||||
else {
|
||||
final filtered =
|
||||
selectedAllServices!
|
||||
.where(
|
||||
@ -354,15 +398,33 @@ class _PolicyState extends State<Policy> {
|
||||
print("Filtered Selected Services Chooesed1: $ServicesChoosed");
|
||||
|
||||
if (ServicesChoosed!.isNotEmpty) {
|
||||
String firstServiceName = ServicesChoosed?.first['name'];
|
||||
print("✅ First service name selected for filter: $firstServiceName");
|
||||
selectedService = firstServiceName;
|
||||
policyCriteriaKey.currentState?.fetchTrainFlightClass();
|
||||
ServicesChoosed!.sort(
|
||||
(a, b) => (a['order'] ?? 0).compareTo(b['order'] ?? 0),
|
||||
);
|
||||
String firstServiceName = ServicesChoosed?.first['name'];
|
||||
String firstServiceId = ServicesChoosed?.first['service_id'];
|
||||
print("✅ 363 First service name selected for filter: $firstServiceName - $firstServiceId");
|
||||
selectedService = firstServiceName;
|
||||
if (selectedServiceDBValue.value == "0") {
|
||||
setState(() {
|
||||
selectedServiceDBValue.value = firstServiceId.toString();
|
||||
});
|
||||
}
|
||||
|
||||
List<int> serviceDBvalue = ServicesChoosed!
|
||||
.map((item) => int.parse(item['service_id'].toString()))
|
||||
.toList();
|
||||
serviceDBValueList = serviceDBvalue;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void updateData() {
|
||||
print("updateData");
|
||||
// if (widget.policy != null && selectedService != null && selectedServiceDBValue.value != "0") {
|
||||
if (widget.policy != null) {
|
||||
setState(() {
|
||||
selectedPolicyId = widget.policy?["policy_id"] ?? "";
|
||||
@ -380,6 +442,7 @@ class _PolicyState extends State<Policy> {
|
||||
policy_details = List<Map<String, dynamic>>.from(
|
||||
widget.policy?["policy_details"] ?? [],
|
||||
);
|
||||
// print("policy_details ${policy_details}");
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -462,6 +525,7 @@ class _PolicyState extends State<Policy> {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
bool isValidData(Map<String, dynamic> data) {
|
||||
errorMessages.clear(); // Reset previous errors
|
||||
|
||||
@ -1149,11 +1213,13 @@ class _PolicyState extends State<Policy> {
|
||||
List<String> services =
|
||||
ServicesChoosed!.map((service) => service['name'].toString()).toList();
|
||||
|
||||
List<String> serviceDBvalue =
|
||||
ServicesChoosed!
|
||||
.map((service) => service['service_id'].toString())
|
||||
// List<int> serviceDBvalue =
|
||||
// ServicesChoosed!.map((service) => int.parse(service['service_id'].toString())).toList();
|
||||
List<int> serviceDBvalue = ServicesChoosed!
|
||||
.map((item) => int.parse(item['service_id'].toString()))
|
||||
.toList();
|
||||
|
||||
|
||||
print("1093");
|
||||
print(services);
|
||||
print(serviceDBvalue);
|
||||
@ -1165,9 +1231,12 @@ class _PolicyState extends State<Policy> {
|
||||
direction: Axis.horizontal,
|
||||
children:
|
||||
services.asMap().entries.map((entry) {
|
||||
int index = entry.key + 1;
|
||||
print("1182 ${entry}");
|
||||
int i = entry.key;
|
||||
int index = i + 1;
|
||||
String service = entry.value;
|
||||
String serviceId = index.toString();
|
||||
int serviceId = serviceDBvalue[i];
|
||||
|
||||
bool isSelected =
|
||||
selectedServiceIndex.value == index.toString();
|
||||
|
||||
@ -1184,30 +1253,26 @@ class _PolicyState extends State<Policy> {
|
||||
// max((MediaQuery.of(context).size.height * 0.09), 10)
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
print("Selected Services - $service - $index");
|
||||
print("1201 Selected Services - $service - Tab Index - $index Service Id- $serviceId");
|
||||
setState(() {
|
||||
selectedServiceIndex.value = index.toString();
|
||||
selectedServiceDBValue = serviceDBvalue[entry.key];
|
||||
selectedServiceDBValue.value = serviceId.toString();
|
||||
selectedService = service;
|
||||
|
||||
print(
|
||||
" selectedServiceIndex.value - ${selectedServiceIndex.value}",
|
||||
);
|
||||
|
||||
print(
|
||||
" selectedServiceDBValue.value - ${selectedServiceDBValue}",
|
||||
);
|
||||
|
||||
// policyCriteriaKey.currentState?.fieldForPolicy();
|
||||
// policyCriteriaKey.currentState
|
||||
// ?.addOrUpdatePolicy(selectedServiceIndex.value);
|
||||
print("policyselectedService - $selectedService");
|
||||
if (selectedService == "Flight" ||
|
||||
selectedService == "Train" ||
|
||||
selectedService == "Accomodation") {
|
||||
selectedService == "Train" || selectedService == "Accomodation") {
|
||||
showClass = true;
|
||||
showCost = false;
|
||||
int serviceCode = selectedService == "Flight" ? 1 : 2;
|
||||
// int serviceCode = selectedService == "Flight" ? 1 : 2;
|
||||
print("policyselectedService1 - $selectedService");
|
||||
policyCriteriaKey.currentState
|
||||
?.fetchTrainFlightClass();
|
||||
@ -1387,19 +1452,24 @@ class _PolicyState extends State<Policy> {
|
||||
}
|
||||
|
||||
Widget _buildPolicyCategory(bool isDesktop) {
|
||||
print("1408 $selectedServiceIndex");
|
||||
print("1409 $selectedService");
|
||||
print("1410 ${selectedServiceDBValue.value}");
|
||||
return Container(
|
||||
margin: isDesktop ? EdgeInsets.all(5) : null,
|
||||
// color: Colors.brown.shade100,
|
||||
// child: Text("data"),
|
||||
// color: Colors.white60,
|
||||
child: PolicyCriteria(
|
||||
child: (selectedService != null && selectedServiceDBValue.value != "0")
|
||||
? PolicyCriteria(
|
||||
key: policyCriteriaKey,
|
||||
isDesktop: isDesktop,
|
||||
isClass: showClass,
|
||||
isCost: showCost,
|
||||
selectedTabNotifier: selectedServiceIndex,
|
||||
selectedService: selectedService,
|
||||
selectedServiceDBValue: selectedServiceDBValue,
|
||||
selectedIdNotifier: selectedServiceDBValue,
|
||||
selectedService: selectedService!,
|
||||
serviceDBValueList: serviceDBValueList, // 👈 Pass the array here
|
||||
userId: userId,
|
||||
onPolicyDataChanged: (List<Map<String, dynamic>>? policyData) {
|
||||
print("🟢 policyData received from child: $policyData");
|
||||
@ -1411,7 +1481,7 @@ class _PolicyState extends State<Policy> {
|
||||
});
|
||||
});
|
||||
},
|
||||
),
|
||||
) : const Center(child: CircularProgressIndicator()),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -14,11 +14,12 @@ import '../../widgets/custom_user_form.dart';
|
||||
class PolicyCriteria extends StatefulWidget {
|
||||
bool isDesktop;
|
||||
String selectedService;
|
||||
String selectedServiceDBValue;
|
||||
final ValueNotifier<String> selectedTabNotifier;
|
||||
final ValueNotifier<String> selectedIdNotifier;
|
||||
String? userId;
|
||||
bool isClass = true;
|
||||
bool isCost = true;
|
||||
final List<int> serviceDBValueList;
|
||||
|
||||
final Function(List<Map<String, dynamic>>?) onPolicyDataChanged;
|
||||
|
||||
@ -27,18 +28,19 @@ class PolicyCriteria extends StatefulWidget {
|
||||
required this.isDesktop,
|
||||
required this.selectedService,
|
||||
required this.selectedTabNotifier,
|
||||
required this.selectedServiceDBValue,
|
||||
required this.selectedIdNotifier,
|
||||
required this.userId,
|
||||
required this.isClass,
|
||||
required this.isCost,
|
||||
required this.onPolicyDataChanged,
|
||||
required this.serviceDBValueList,
|
||||
});
|
||||
@override
|
||||
PolicyCriteriaState createState() => PolicyCriteriaState();
|
||||
}
|
||||
|
||||
class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
String? ServiceId = "1";
|
||||
String? ServiceId;// = "1";
|
||||
String? ServiceIndxId = "1";
|
||||
|
||||
String? orgId;
|
||||
@ -101,19 +103,32 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
|
||||
super.initState();
|
||||
fetchTrainFlightClass();
|
||||
|
||||
print("whole value here - ${widget.serviceDBValueList}");
|
||||
print(widget.serviceDBValueList);
|
||||
|
||||
fieldForPolicy();
|
||||
|
||||
widget.selectedIdNotifier.addListener(() {
|
||||
setState(() {
|
||||
ServiceId = widget.selectedIdNotifier.value ?? "1";
|
||||
print("new :) ${widget.selectedIdNotifier.value}");
|
||||
print("ServiceIndxId changed: $ServiceId");
|
||||
});
|
||||
});
|
||||
widget.selectedTabNotifier.addListener(() {
|
||||
print("selectedTab changed: ${widget.selectedTabNotifier.value}");
|
||||
setState(() {
|
||||
ServiceIndxId = widget.selectedTabNotifier.value ?? "1";
|
||||
|
||||
// ServiceId = widget.selectedIdNotifier.value ?? "1";
|
||||
print("ServiceIndxId changed: $ServiceIndxId");
|
||||
});
|
||||
|
||||
fieldForPolicy();
|
||||
fetchTrainFlightClass();
|
||||
// fetchTrainFlightClass(); // old here
|
||||
});
|
||||
}
|
||||
|
||||
@ -146,6 +161,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
// Step 3: Loop through all service definitions
|
||||
for (var service in services) {
|
||||
String id = service['service_id'].toString();
|
||||
print("164 service == $id");
|
||||
|
||||
// Skip if already present
|
||||
if (existingServiceIds!.contains(id)) continue;
|
||||
@ -200,6 +216,8 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
|
||||
// To set the data (update)
|
||||
void loadPolicyDetails(List<Map<String, dynamic>> details) {
|
||||
|
||||
print("loadPolicyDetails");
|
||||
for (var item in details) {
|
||||
final serviceId = item['service_id'].toString();
|
||||
|
||||
@ -321,14 +339,12 @@ 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 && ae4 == null;
|
||||
bool allExceptionalActionsNull = ae1 == null && ae2 == null && ae3 == null && ae4 == null;
|
||||
bool someExceptionalActionsMissing =
|
||||
[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 && aa4 == null;
|
||||
bool allAmendActionsNull = aa1 == null && aa2 == null && aa3 == null && aa4 == null;
|
||||
bool someAmendActionsMissing =
|
||||
[aa1, aa2, aa3, aa4].where((a) => a != null).length > 0 &&
|
||||
[aa1, aa2, aa3, aa4].where((a) => a == null).length > 0;
|
||||
@ -439,6 +455,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
// }
|
||||
|
||||
Future<void> fetchTrainFlightClass() async {
|
||||
print("ftech api");
|
||||
try {
|
||||
final data = await apiService.fetchMasterDropdown();
|
||||
|
||||
@ -460,7 +477,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
void fieldForPolicy() {
|
||||
print("fieldForPolicy - ${widget.selectedTabNotifier.value}");
|
||||
|
||||
print("POlicyCheck - $policyData");
|
||||
|
||||
// Save current input to policyData before switching
|
||||
if (ServiceId != null) {
|
||||
print("Calling addOrUpdatePolicy");
|
||||
@ -470,12 +487,25 @@ 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 (Controller Creation)
|
||||
final String tabIndexStr = widget.selectedTabNotifier.value;
|
||||
print(" fns - $ServiceId");
|
||||
// Safely convert tab index to int
|
||||
final int? tabIndex = int.tryParse(tabIndexStr);
|
||||
print(" tb inx - $tabIndex");
|
||||
print(" db - ${widget.serviceDBValueList.length}");
|
||||
print(" db list - ${widget.serviceDBValueList}");
|
||||
|
||||
if (tabIndex != null && tabIndex >= 0 && tabIndex <= widget.serviceDBValueList.length) {
|
||||
ServiceId = widget.serviceDBValueList[tabIndex-1].toString();
|
||||
print('✅ 484 Selected ServiceId: $ServiceId');
|
||||
}
|
||||
else {
|
||||
print('❌ Invalid tab index or out of range');
|
||||
}
|
||||
print("502 ServiceId $ServiceId");
|
||||
// Initialize controllers and variables if not present
|
||||
costController.putIfAbsent(ServiceId!, () => TextEditingController());
|
||||
classAction.putIfAbsent((widget.selectedServiceDBValue), () => "1");
|
||||
classAction.putIfAbsent((ServiceId!), () => "1");
|
||||
// classController.putIfAbsent(ServiceId!, () => TextEditingController());
|
||||
|
||||
FirstApproverAction.putIfAbsent(ServiceId!, () => "None");
|
||||
@ -1238,10 +1268,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
children: [
|
||||
Container(
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -1387,10 +1414,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
),
|
||||
Container(
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -1540,10 +1564,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
),
|
||||
Container(
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -1694,10 +1715,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
),
|
||||
Container(
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -1942,10 +1960,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
children: [
|
||||
Container(
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -2091,10 +2106,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
),
|
||||
Container(
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -2244,10 +2256,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
),
|
||||
Container(
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -2398,10 +2407,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
),
|
||||
Container(
|
||||
// padding: const EdgeInsets.all(10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 4.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0, vertical: 4.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
@ -2580,19 +2586,21 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
// : (apiDataForClass?['train_class'] ?? []);
|
||||
// }
|
||||
|
||||
if (ServiceIndxId != null) {
|
||||
switch (ServiceIndxId) {
|
||||
if (ServiceId != null) {
|
||||
// ServiceId = '1';
|
||||
print("sid $ServiceId");
|
||||
switch (ServiceId) {
|
||||
case "1":
|
||||
textLabel = "Class";
|
||||
purposeList = apiDataForClass?['flight_class'] ?? [];
|
||||
break;
|
||||
|
||||
case "2":
|
||||
case "5":
|
||||
textLabel = "Category";
|
||||
purposeList = apiDataForClass?['hotel_class'] ?? [];
|
||||
break;
|
||||
|
||||
case "9":
|
||||
case "2":
|
||||
textLabel = "Class";
|
||||
purposeList = apiDataForClass?['train_class'] ?? [];
|
||||
break;
|
||||
@ -2606,8 +2614,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
print("CLASS-ServiceId- $ServiceId");
|
||||
print("CLASS-ServiceIndxId- $ServiceIndxId");
|
||||
print("CLASS-purposeList - $purposeList");
|
||||
print("CLASS-DB Service Id - ${widget.selectedServiceDBValue}");
|
||||
print("CLASS-Action - ${classAction[widget.selectedServiceDBValue]}");
|
||||
print("CLASS-Action - ${classAction[ServiceId]}");
|
||||
|
||||
// ✅ Sort by dropdown_key
|
||||
purposeList.sort((a, b) {
|
||||
@ -2626,6 +2633,7 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
)
|
||||
.toList();
|
||||
|
||||
|
||||
if (dropdownItems.isEmpty) {
|
||||
dropdownItems.add(
|
||||
DropdownMenuItem<String>(
|
||||
@ -2651,14 +2659,13 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
// }
|
||||
|
||||
// 1. First, when dropdownItems are ready, assign default value:
|
||||
if ((widget.selectedServiceDBValue) != null &&
|
||||
classAction[(widget.selectedServiceDBValue)] == null &&
|
||||
if ((ServiceId) != null &&
|
||||
classAction[ServiceId] == null &&
|
||||
dropdownItems.isNotEmpty) {
|
||||
// Important to wrap inside setState if async
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
setState(() {
|
||||
classAction[(widget.selectedServiceDBValue)] =
|
||||
dropdownItems.first.value!;
|
||||
classAction[ServiceId!] = dropdownItems.first.value!;
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -2718,18 +2725,13 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
child:
|
||||
(widget.selectedServiceDBValue) != null &&
|
||||
(isLoading || dropdownItems.isEmpty)
|
||||
(ServiceId!) != null && (isLoading || dropdownItems.isEmpty)
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: DropdownSearch<Map<String, dynamic>>(
|
||||
key:
|
||||
classAction[(widget.selectedServiceDBValue)] ==
|
||||
null
|
||||
classAction[(ServiceId!)] == null
|
||||
? UniqueKey()
|
||||
: ValueKey(
|
||||
classAction[(widget
|
||||
.selectedServiceDBValue)],
|
||||
),
|
||||
: ValueKey(classAction[(ServiceId!)]),
|
||||
items: purposeList.cast<Map<String, dynamic>>(),
|
||||
|
||||
// selectedItem: purposeList.firstWhere(
|
||||
@ -2737,13 +2739,11 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
// orElse: () => {},
|
||||
// ),
|
||||
selectedItem:
|
||||
classAction[(widget.selectedServiceDBValue)] !=
|
||||
null
|
||||
classAction[(ServiceId!)] != null
|
||||
? purposeList.firstWhere(
|
||||
(item) =>
|
||||
item['dropdown_key'] ==
|
||||
classAction[(widget
|
||||
.selectedServiceDBValue)],
|
||||
classAction[(ServiceId!)],
|
||||
orElse: () => {},
|
||||
)
|
||||
: null,
|
||||
@ -2806,11 +2806,10 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
purposeList.isNotEmpty
|
||||
? (Map<String, dynamic>? newValue) async {
|
||||
setState(() {
|
||||
classAction[(widget
|
||||
.selectedServiceDBValue)] =
|
||||
classAction[(ServiceId!)] =
|
||||
newValue?['dropdown_key'];
|
||||
print(
|
||||
"Selected Purpose: ${classAction[(widget.selectedServiceDBValue)]}",
|
||||
"Selected Purpose: ${classAction[(ServiceId!)]}",
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
2872
lib/Screens/policy/policyCriteria_backup24july2025.dart
Normal file
2872
lib/Screens/policy/policyCriteria_backup24july2025.dart
Normal file
File diff suppressed because it is too large
Load Diff
1663
lib/Screens/policy/policy_backup24july2025.dart
Normal file
1663
lib/Screens/policy/policy_backup24july2025.dart
Normal file
File diff suppressed because it is too large
Load Diff
@ -57,6 +57,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
|
||||
String? userId;
|
||||
String? orgId;
|
||||
String? roleId;
|
||||
String? userIdApi;
|
||||
|
||||
bool isCheckingToken = false;
|
||||
@ -677,6 +678,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
Future<void> initializeData() async {
|
||||
token = await getToken();
|
||||
userId = await getUserId();
|
||||
roleId = await getRoleId();
|
||||
|
||||
if (token == null || userId == null) {
|
||||
print("Token or USerId missing");
|
||||
@ -706,6 +708,19 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<String?> getRoleId() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final userData = prefs.getString('user_data');
|
||||
|
||||
if (userData != null) {
|
||||
final decodedData = jsonDecode(userData);
|
||||
|
||||
// Return the user_id from the decoded data
|
||||
return decodedData['role_id']?.toString();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// Dispose all controllers to prevent memory leaks
|
||||
@ -1313,7 +1328,10 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
print("✅ User submitted successfully!");
|
||||
|
||||
print("📨 Response: ${response.body}");
|
||||
context.go('/listUser');
|
||||
|
||||
if(roleId == "4"){ context.go('/listPlan'); }
|
||||
else{ context.go('/listUser'); }
|
||||
|
||||
} else {
|
||||
print("❌ Submission failed. Status: ${response.statusCode}");
|
||||
print("📨 Body: ${response.body}");
|
||||
|
||||
144
lib/app.dart
144
lib/app.dart
@ -2,7 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
// import 'package:flutter/rendering.dart';
|
||||
import 'dart:html' as html;
|
||||
import 'package:frontend/config/apiUrl.dart'; // 1 newly added
|
||||
import 'package:frontend/services/apiService.dart';
|
||||
@ -15,6 +15,7 @@ import 'package:flutter_quill/flutter_quill.dart';
|
||||
import 'package:frontend/routes/custom_router.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'Screens/myTemplates/templateTest.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
const MyApp({super.key});
|
||||
@ -27,12 +28,14 @@ class _MyAppState extends State<MyApp> {
|
||||
final ApiService apiService = ApiService();
|
||||
String? _authCode;
|
||||
String? userRole;
|
||||
bool _isAuthRedirect = false;
|
||||
bool _isAuthRedirect = false; // Only true for Microsoft redirect
|
||||
bool _isloading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
SemanticsBinding.instance
|
||||
.ensureSemantics(); // Safe here -only for testing uncomment, Otherwise Email Template wont allow to type
|
||||
// SemanticsBinding.instance
|
||||
// .ensureSemantics(); // Safe here -only for testing uncomment, Otherwise Email Template wont allow to type
|
||||
if (kIsWeb) {
|
||||
final uri = Uri.parse(html.window.location.href);
|
||||
print("URI - $uri");
|
||||
@ -51,38 +54,41 @@ class _MyAppState extends State<MyApp> {
|
||||
print("query: $query");
|
||||
|
||||
final queryParams = Uri.splitQueryString(query);
|
||||
print("query: $query");
|
||||
print("queryParams: $queryParams");
|
||||
|
||||
final authCode = queryParams['code'];
|
||||
|
||||
if (fragmentPath == '/authredirection' && authCode != null) {
|
||||
// _authCode = uri.queryParameters['code'];
|
||||
|
||||
_authCode = queryParams['code'];
|
||||
// _isAuthRedirect = true;
|
||||
html.window.console.log("Auth code detected: $_authCode");
|
||||
// print(">>> _isAuthRedirect: $_isAuthRedirect");
|
||||
print(">>> Auth code found at startup: $_authCode");
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
handleTokenUsingMS(_authCode);
|
||||
setState(() {
|
||||
_isAuthRedirect = true; // Show loading screen ONLY for MS login
|
||||
});
|
||||
print("🔍 Auth code detected at startup: $authCode");
|
||||
// ✅ Immediately begin token handling
|
||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// handleTokenUsingMS(authCode);
|
||||
// });
|
||||
|
||||
handleTokenUsingMS(authCode).then((_) {
|
||||
// 🔥 No URL cleanup — leave it as is
|
||||
setState(() {
|
||||
_isAuthRedirect = false;
|
||||
});
|
||||
});
|
||||
|
||||
html.window.console.log("Auth code detected: $authCode");
|
||||
}else {
|
||||
html.window.console.log("No auth code found or wrong path.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> handleTokenUsingMS(String? authCode) async {
|
||||
// Note : Doing any change means just refer on login_widget.dart file - _login function. 24july2025
|
||||
Future<void> handleTokenUsingMS(String authCode) async {
|
||||
print("handleTokenUsingMS- $authCode");
|
||||
if (authCode == null) return;
|
||||
|
||||
// final url =
|
||||
// 'http://localhost:40617/tstat/auth/verifyMSAuthUser?code=$authCode';
|
||||
final url = '$apiUrl/auth/verifyMSAuthUser?code=$authCode';
|
||||
|
||||
print("url- $url");
|
||||
try {
|
||||
// final url = 'http://localhost:43627/tstat/auth/verifyMSAuthUser?code=$authCode';
|
||||
final url = '$apiUrl/auth/verifyMSAuthUser?code=$authCode';
|
||||
print("Microsoft BE URL - $url");
|
||||
final response = await http.get(
|
||||
Uri.parse(url),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
@ -90,44 +96,69 @@ class _MyAppState extends State<MyApp> {
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final responseBody = json.decode(response.body);
|
||||
final MS_Token = responseBody['token'];
|
||||
print("MS_Token - $MS_Token");
|
||||
final token = responseBody['token'];
|
||||
print("Microsoft_Token - $token");
|
||||
setState(() {
|
||||
_isloading = true;
|
||||
});
|
||||
|
||||
if (MS_Token != null && MS_Token != '') {
|
||||
if (token != null && token.isNotEmpty) {
|
||||
print('Microsoft - Token Available');
|
||||
await storeUserDetails(MS_Token);
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString('is_microsoft_user', 'true');
|
||||
await storeUserDetails(token);
|
||||
setState(() {
|
||||
_isloading = false;
|
||||
});
|
||||
if(_isloading){ const CircularProgressIndicator(); }
|
||||
final userData = prefs.getString('user_data');
|
||||
print("MS Userdata - $userData");
|
||||
final orgDataString = prefs.getString('org_data');
|
||||
print("MS orgdata - $orgDataString");
|
||||
|
||||
print("userRole - $userRole");
|
||||
if (orgDataString != null && userData != null){
|
||||
Fluttertoast.showToast(
|
||||
msg: "You're in!",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
backgroundColor: Colors.green,
|
||||
textColor: Colors.white,
|
||||
fontSize: 16,
|
||||
webBgColor: "linear-gradient(to right, #28a745, #28a745)",
|
||||
);
|
||||
|
||||
print("Microsoft User Logged In Refer the Role - $userRole");
|
||||
// Navigate based on role
|
||||
if (userRole == "Travel Agent") {
|
||||
router.go('/listTravelAgentPlan');
|
||||
} else if (userRole == "Org Admin" || userRole == "Travel Admin") {
|
||||
router.go('/listAllPlan');
|
||||
router.go('/StatusDashboard');
|
||||
} else {
|
||||
router.go('/listPlan');
|
||||
}
|
||||
} else {
|
||||
throw Exception('Token not found in response.');
|
||||
}
|
||||
} else {
|
||||
// Handle 400/401/500 etc.
|
||||
String errorMsg;
|
||||
try {
|
||||
final decoded = json.decode(response.body);
|
||||
errorMsg = decoded['message'] ?? 'Unknown error';
|
||||
} catch (_) {
|
||||
errorMsg = response.body; // fallback to plain text
|
||||
throw Exception('Token missing in response.');
|
||||
}
|
||||
|
||||
print("Error response: $errorMsg");
|
||||
throw Exception("Authentication failed: $errorMsg");
|
||||
} else {
|
||||
final error = json.decode(response.body)['message'] ?? 'Auth failed';
|
||||
throw Exception(error);
|
||||
}
|
||||
} catch (e, stack) {
|
||||
print("Caught error: $e");
|
||||
} catch (e) {
|
||||
Fluttertoast.showToast(
|
||||
msg: "Login Failed: $e",
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white,
|
||||
fontSize: 16,
|
||||
webBgColor: "linear-gradient(to right, #dc1c13, #dc1c13)",
|
||||
);
|
||||
router.go('/');
|
||||
}
|
||||
}
|
||||
|
||||
// Note : Doing any change means just refer on login_widget.dart file - storeUserDetails function. 24july2025
|
||||
Future<void> storeUserDetails(String token) async {
|
||||
try {
|
||||
final parts = token.split('.');
|
||||
@ -141,10 +172,7 @@ class _MyAppState extends State<MyApp> {
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString('auth_token', token);
|
||||
await prefs.setString(
|
||||
'user_data',
|
||||
jsonEncode(userData),
|
||||
); // Store full user data
|
||||
await prefs.setString('user_data', jsonEncode(userData)); // Store full user data
|
||||
|
||||
if (userData != null) {
|
||||
final pref = await SharedPreferences.getInstance();
|
||||
@ -153,19 +181,31 @@ class _MyAppState extends State<MyApp> {
|
||||
|
||||
userRole = userData['role'];
|
||||
|
||||
print("userData - $userData");
|
||||
print("userData11 - ${userData['role']}");
|
||||
print("userData12 - $userRole");
|
||||
print("MicroSoft UserData RAW - $userData");
|
||||
print("MicroSoft UserData ROLE RAW - ${userData['role']}");
|
||||
print("MicroSoft UserData ROLE FECTHED - $userRole");
|
||||
}
|
||||
apiService.getOrganizationData();
|
||||
print("MicroSoft Started");
|
||||
await apiService.getOrganizationData();
|
||||
print("MicroSoft end");
|
||||
|
||||
} catch (e) {
|
||||
print('Error decoding token: $e');
|
||||
print('Error decoding token MS: $e');
|
||||
router.go('/');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
if (_isAuthRedirect) {
|
||||
return const MaterialApp(
|
||||
home: Scaffold(
|
||||
body: Center(child: CircularProgressIndicator()),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return MaterialApp.router(
|
||||
title: 'Trip Approval Tool',
|
||||
debugShowCheckedModeBanner: false,
|
||||
|
||||
@ -1,5 +1,19 @@
|
||||
//api url
|
||||
// const String apiUrl = 'http://localhost/tstat_be';
|
||||
// const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be';
|
||||
const String apiUrl =
|
||||
'http://apitest.tripapprovaltool.com/tstat_be'; // look at this
|
||||
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
|
||||
* <base href="/tstat/"> replaced to <base href="/adfactor/"> **/
|
||||
// const String apiUrl = 'https://uat.tripapprovaltool.com/adfactor_be';
|
||||
|
||||
/** Note : Aujas UAT BE URL
|
||||
* File : web/index.html - change below
|
||||
* <base href="/tstat/"> replaced to <base href="/aujas/"> **/
|
||||
// const String apiUrl = 'https://uat.tripapprovaltool.com/aujas_be';
|
||||
|
||||
/** Note : Aujas Live BE URL
|
||||
* File : web/index.html - change below
|
||||
* <base href="/tstat/"> replaced to <base href="/aujas/"> **/
|
||||
// const String apiUrl = 'https://tripapprovaltool.com/aujas_be' ;
|
||||
|
||||
@ -15,7 +15,7 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
class ApiService {
|
||||
Future<void> getOrganizationData() async {
|
||||
try {
|
||||
print("getUpdatedServices");
|
||||
print("ORG getUpdatedServices");
|
||||
final result = await fetchOrganization();
|
||||
print("UUPdatedServices - $result");
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user