lastest code with cf23f4f9
This commit is contained in:
parent
cf23f4f936
commit
d2b3b792d9
File diff suppressed because it is too large
Load Diff
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,33 +491,40 @@ 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),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEAF3FB),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
count.toString(),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 18 : 16,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
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(),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 18 : 16,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
label,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 12 : 11,
|
||||
color: Colors.black87,
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
label,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
softWrap: true,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 12 : 11,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -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(
|
||||
value,
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
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,
|
||||
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(
|
||||
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"),
|
||||
],
|
||||
:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Top Row (Country, Currency, Total)
|
||||
Wrap(
|
||||
spacing: 20, // horizontal space between items
|
||||
runSpacing: 10, // vertical space between rows
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_infoBlock("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",
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
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
|
||||
? 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),
|
||||
),
|
||||
],
|
||||
// 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
|
||||
? null
|
||||
: () {
|
||||
widget.onAddNew("Flight", true);
|
||||
print("New data");
|
||||
},
|
||||
child: Icon(
|
||||
Icons.add_circle_sharp,
|
||||
size: 30,
|
||||
color: const Color(0xFF114D8B),
|
||||
),
|
||||
),
|
||||
)
|
||||
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,
|
||||
),
|
||||
),
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
),
|
||||
)
|
||||
|
||||
],
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
_buildKeyValueRow(
|
||||
"Sector",
|
||||
"$fromcity ($fromcode), $fromairport → $tocity ($tocode), $toairport",
|
||||
),
|
||||
|
||||
_buildKeyValueRow(
|
||||
"Date",
|
||||
formatDate(trip["date"] ?? ""),
|
||||
),
|
||||
_buildKeyValueRow(
|
||||
"Time",
|
||||
formatTime(trip["time"] ?? ""),
|
||||
const SizedBox(height: 6),
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: Text(
|
||||
'${formatDate(trip["date"] ?? "")} ${formatTime(trip["time"] ?? "")}',
|
||||
textAlign: TextAlign.right,
|
||||
style: const TextStyle(
|
||||
fontSize: 13,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
}).toList(),
|
||||
],
|
||||
),
|
||||
|
||||
@ -39,93 +39,101 @@ 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,
|
||||
// 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),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// if ((!isDesktop) && forexList.isNotEmpty)
|
||||
// Text(
|
||||
// " ",
|
||||
// style: const TextStyle(
|
||||
// fontSize: 18,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// ),
|
||||
// ),
|
||||
// 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,
|
||||
// // 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(
|
||||
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"),
|
||||
],
|
||||
): Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Top Row (Country, Currency, Total)
|
||||
Wrap(
|
||||
spacing: 20, // horizontal space between items
|
||||
runSpacing: 10, // vertical space between rows
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_infoBlock("Country code", item["country_code"] ?? "N/A"),
|
||||
_infoBlock("Currency", item["currency"] ?? "N/A"),
|
||||
_infoBlock("Total Amount", item["total_amount"]?.toString() ?? "0"),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
|
||||
// Second Row (Start Date, End Date, Duration)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
_infoBlock("Start Date", item["start_date"] ?? "N/A"),
|
||||
_infoBlock("End Date", item["end_date"] ?? "N/A"),
|
||||
_infoBlock("Duration", item["duration"]?.toString() ?? "N/A"),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
||||
// Comment label
|
||||
Text(
|
||||
"Comment",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
if (item["comments"] != null && item["comments"].toString().trim().isNotEmpty)
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.all(12),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: const Color(0xFF7098DD), width: 1),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
item["comments"] ?? "N/A",
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black87),
|
||||
),
|
||||
)
|
||||
else
|
||||
const Text( "N/A", style: TextStyle(fontSize: 12), ),
|
||||
],
|
||||
),
|
||||
// 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(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: exceedsLimit
|
||||
? Tooltip(
|
||||
message: wrapText(value, 50),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade200, // Black background
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
textStyle:
|
||||
TextStyle(color: Colors.black), // Tooltip text color
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(value.substring(0, limit) + "...",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Widget _buildRow(String title, String value) {
|
||||
// // Define character limits based on title
|
||||
// Map<String, int> limits = {
|
||||
// // "Special Request:": 30,
|
||||
// "Comments:": 10,
|
||||
// // Add more keys and limits if needed
|
||||
// };
|
||||
//
|
||||
// int limit = limits[title] ?? 50; // Default limit if title not found
|
||||
// bool exceedsLimit = value.length > limit;
|
||||
//
|
||||
// String wrapText(String text, int maxLineLength) {
|
||||
// final pattern = RegExp('.{1,$maxLineLength}(\\s+|\$)');
|
||||
// return pattern.allMatches(text).map((m) => m.group(0)!).join('\n');
|
||||
// }
|
||||
//
|
||||
// return Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// 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,71 +34,79 @@ 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: [
|
||||
// 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),
|
||||
// )
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
],
|
||||
),
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// if ((!isDesktop) && insuranceList.isNotEmpty)
|
||||
// Text(
|
||||
// " ",
|
||||
// style: const TextStyle(
|
||||
// fontSize: 18,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// ),
|
||||
// ),
|
||||
// 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: [
|
||||
// // 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(
|
||||
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"),
|
||||
],
|
||||
:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 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,56 +26,67 @@ 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
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap:
|
||||
isViewMode
|
||||
? null
|
||||
: () {
|
||||
print("New data");
|
||||
onAddNew("Miscellaneous", true);
|
||||
},
|
||||
isViewMode
|
||||
? null
|
||||
: () {
|
||||
print("New data");
|
||||
onAddNew("Miscellaneous", true);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
// Text(
|
||||
// "Add New",
|
||||
// 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,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -122,7 +133,7 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
|
||||
Widget _buildData(BuildContext context, bool isDesktop) {
|
||||
List<Map<String, dynamic>> filteredList =
|
||||
miscellaneousList.where((item) => item["is_active"] == "1").toList();
|
||||
miscellaneousList.where((item) => item["is_active"] == "1").toList();
|
||||
|
||||
return ListView.builder(
|
||||
shrinkWrap: true,
|
||||
@ -136,9 +147,9 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
return (apiData?['miscellaneous_special_request'] ?? [])
|
||||
.firstWhere(
|
||||
(element) =>
|
||||
element["dropdown_key"].toString() == specialRequestKey,
|
||||
orElse: () => {"dropdown_value": "N/A"},
|
||||
)["dropdown_value"]
|
||||
element["dropdown_key"].toString() == specialRequestKey,
|
||||
orElse: () => {"dropdown_value": "N/A"},
|
||||
)["dropdown_value"]
|
||||
.toString();
|
||||
}
|
||||
|
||||
@ -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,83 +211,101 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
'assets/images/IconsImg/delete.png',
|
||||
width: 20,
|
||||
height: 15,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
// Divider(color: Colors.blueGrey.shade50),
|
||||
SizedBox(height: 10),
|
||||
isDesktop
|
||||
? Row(
|
||||
children: [
|
||||
// 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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: SizedBox.shrink(),
|
||||
Divider(color: Colors.blueGrey.shade50),
|
||||
SizedBox(height: 4),
|
||||
isDesktop
|
||||
? Container(
|
||||
// color: Color(0xFFE8F0FC),
|
||||
color: Colors.white,
|
||||
child: Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Text(
|
||||
// getRequestValue(
|
||||
// item["special_request"]?.toString(),
|
||||
// ),
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
Container(
|
||||
// width: MediaQuery.of(context).size.width * 0.6,
|
||||
// padding: EdgeInsets.all(16),
|
||||
// color: Color(0xFFE8F0FC),
|
||||
child: Expanded(
|
||||
// flex: 1,
|
||||
child: Text(
|
||||
item["comments"],
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
? Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Special Request",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
)
|
||||
: Column(
|
||||
children: [
|
||||
_buildRow(
|
||||
"Special Request:",
|
||||
getRequestValue(item["special_request"]?.toString()),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
_buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: GoogleFonts.poppins(fontSize: 11),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
// : SizedBox.shrink(),
|
||||
// isDesktop
|
||||
// ? Row(
|
||||
// children: [
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Text(
|
||||
// getRequestValue(
|
||||
// item["special_request"]?.toString(),
|
||||
// ),
|
||||
// style: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// 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: 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(
|
||||
// "Special Request:",
|
||||
// getRequestValue(item["special_request"]?.toString()),
|
||||
// ),
|
||||
// SizedBox(width: 10),
|
||||
// _buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -306,34 +335,34 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Expanded(
|
||||
child:
|
||||
exceedsLimit
|
||||
? Tooltip(
|
||||
message: wrapText(value, 50),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade200, // Black background
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
color: Colors.black,
|
||||
), // Tooltip text color
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(
|
||||
value.substring(0, limit) + "...",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
exceedsLimit
|
||||
? Tooltip(
|
||||
message: wrapText(value, 50),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade200, // Black background
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
color: Colors.black,
|
||||
), // Tooltip text color
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(
|
||||
value.substring(0, limit) + "...",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
@ -365,95 +394,95 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
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,
|
||||
fontSize: 12,
|
||||
), // Tooltip text color
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(
|
||||
value.substring(0, limit) + "...",
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
)
|
||||
: Text(value),
|
||||
exceedsLimit
|
||||
? Tooltip(
|
||||
message: wrapText(value, 50),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.shade200, // Black background
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 12,
|
||||
), // Tooltip text color
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(
|
||||
value.substring(0, limit) + "...",
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
)
|
||||
: Text(value),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
//
|
||||
// Widget _buildData(BuildContext context) {
|
||||
// return Container(
|
||||
// width: MediaQuery.of(context).size.width,
|
||||
// child: DataTable(
|
||||
// border: TableBorder(
|
||||
// bottom: BorderSide(color: Colors.black12),
|
||||
// horizontalInside: BorderSide(color: Colors.black12),
|
||||
// ),
|
||||
// columns: const [
|
||||
// DataColumn(label: Text('Special Request')),
|
||||
// DataColumn(label: Text('Comments')),
|
||||
// DataColumn(label: Text('Actions')),
|
||||
// ],
|
||||
// rows: _buildDataRows(),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// List<DataRow> _buildDataRows() {
|
||||
// List<dynamic> purposeList = apiData?['miscellaneous_special_request'] ?? [];
|
||||
//
|
||||
// String getRequestValue(String? specialRequestKey) {
|
||||
// if (specialRequestKey == null) return "N/A";
|
||||
// return purposeList
|
||||
// .firstWhere(
|
||||
// (element) =>
|
||||
// element["dropdown_key"].toString() == specialRequestKey,
|
||||
// orElse: () => {"dropdown_value": "N/A"},
|
||||
// )["dropdown_value"]
|
||||
// .toString();
|
||||
// }
|
||||
//
|
||||
// List<Map<String, dynamic>> filteredList =
|
||||
// miscellaneousList.where((item) => item["is_active"] == "1").toList();
|
||||
//
|
||||
// return filteredList.asMap().entries.map((entry) {
|
||||
// Map<String, dynamic> item = entry.value;
|
||||
//
|
||||
// return DataRow(cells: [
|
||||
// DataCell(Text(getRequestValue(item["special_request"]?.toString()))),
|
||||
// DataCell(Text(item["comments"] ?? "N/A")),
|
||||
// DataCell(Row(
|
||||
// children: [
|
||||
// GestureDetector(
|
||||
// onTap: () => onOpen(true, item, "Miscellaneous"),
|
||||
// child: Image.asset('assets/images/IconsImg/edit.png',
|
||||
// width: 20, height: 15),
|
||||
// ),
|
||||
// SizedBox(width: 10),
|
||||
// GestureDetector(
|
||||
// onTap: () => onOpen(true, item, "Miscellaneous"),
|
||||
// child: Image.asset('assets/images/IconsImg/delete.png',
|
||||
// width: 20, height: 15),
|
||||
// ),
|
||||
// IconButton(
|
||||
// icon: Icon(Icons.keyboard_arrow_down_outlined,
|
||||
// size: 28, color: Color(0xFF475569)),
|
||||
// onPressed: () {
|
||||
// // Expand logic (optional)
|
||||
// },
|
||||
// ),
|
||||
// ],
|
||||
// )),
|
||||
// ]);
|
||||
// }).toList();
|
||||
// }
|
||||
}
|
||||
//
|
||||
// Widget _buildData(BuildContext context) {
|
||||
// return Container(
|
||||
// width: MediaQuery.of(context).size.width,
|
||||
// child: DataTable(
|
||||
// border: TableBorder(
|
||||
// bottom: BorderSide(color: Colors.black12),
|
||||
// horizontalInside: BorderSide(color: Colors.black12),
|
||||
// ),
|
||||
// columns: const [
|
||||
// DataColumn(label: Text('Special Request')),
|
||||
// DataColumn(label: Text('Comments')),
|
||||
// DataColumn(label: Text('Actions')),
|
||||
// ],
|
||||
// rows: _buildDataRows(),
|
||||
// ),
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// List<DataRow> _buildDataRows() {
|
||||
// List<dynamic> purposeList = apiData?['miscellaneous_special_request'] ?? [];
|
||||
//
|
||||
// String getRequestValue(String? specialRequestKey) {
|
||||
// if (specialRequestKey == null) return "N/A";
|
||||
// return purposeList
|
||||
// .firstWhere(
|
||||
// (element) =>
|
||||
// element["dropdown_key"].toString() == specialRequestKey,
|
||||
// orElse: () => {"dropdown_value": "N/A"},
|
||||
// )["dropdown_value"]
|
||||
// .toString();
|
||||
// }
|
||||
//
|
||||
// List<Map<String, dynamic>> filteredList =
|
||||
// miscellaneousList.where((item) => item["is_active"] == "1").toList();
|
||||
//
|
||||
// return filteredList.asMap().entries.map((entry) {
|
||||
// Map<String, dynamic> item = entry.value;
|
||||
//
|
||||
// return DataRow(cells: [
|
||||
// DataCell(Text(getRequestValue(item["special_request"]?.toString()))),
|
||||
// DataCell(Text(item["comments"] ?? "N/A")),
|
||||
// DataCell(Row(
|
||||
// children: [
|
||||
// GestureDetector(
|
||||
// onTap: () => onOpen(true, item, "Miscellaneous"),
|
||||
// child: Image.asset('assets/images/IconsImg/edit.png',
|
||||
// width: 20, height: 15),
|
||||
// ),
|
||||
// SizedBox(width: 10),
|
||||
// GestureDetector(
|
||||
// onTap: () => onOpen(true, item, "Miscellaneous"),
|
||||
// child: Image.asset('assets/images/IconsImg/delete.png',
|
||||
// width: 20, height: 15),
|
||||
// ),
|
||||
// IconButton(
|
||||
// icon: Icon(Icons.keyboard_arrow_down_outlined,
|
||||
// size: 28, color: Color(0xFF475569)),
|
||||
// onPressed: () {
|
||||
// // Expand logic (optional)
|
||||
// },
|
||||
// ),
|
||||
// ],
|
||||
// )),
|
||||
// ]);
|
||||
// }).toList();
|
||||
// }
|
||||
}
|
||||
@ -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(
|
||||
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"),
|
||||
],
|
||||
),
|
||||
:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 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(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
_buildRow(
|
||||
"Class:",
|
||||
getRequestForTrainClass(item["class"]!.toString()),
|
||||
:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 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,
|
||||
),
|
||||
_buildRow("From:", item["from_station"]!),
|
||||
_buildRow("To:", item["to_station"]!),
|
||||
_buildDateTimeRow(
|
||||
"Date:",
|
||||
formatDate(item["date"]!),
|
||||
formatTime(item["time"]!),
|
||||
),
|
||||
_buildRow("Comments:", item["comments"] ?? "N/A"),
|
||||
],
|
||||
),
|
||||
),
|
||||
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(
|
||||
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"),
|
||||
],
|
||||
:
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// 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,17 +72,22 @@ 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);
|
||||
|
||||
_popStateListener = html.window.onPopState.listen((event) {
|
||||
if (!_dialogShown && mounted) {
|
||||
_showBackConfirmationDialog();
|
||||
}
|
||||
if(!msUser){
|
||||
_popStateListener = html.window.onPopState.listen((event) {
|
||||
if (!_dialogShown && mounted) {
|
||||
_showBackConfirmationDialog();
|
||||
}
|
||||
|
||||
// Re-push to prevent leaving
|
||||
html.window.history.pushState(null, '', html.window.location.href);
|
||||
});
|
||||
// Re-push to prevent leaving
|
||||
html.window.history.pushState(null, '', html.window.location.href);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
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}");
|
||||
|
||||
156
lib/app.dart
156
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
|
||||
});
|
||||
} else {
|
||||
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)",
|
||||
);
|
||||
|
||||
if (userRole == "Travel Agent") {
|
||||
router.go('/listTravelAgentPlan');
|
||||
} else if (userRole == "Org Admin" || userRole == "Travel Admin") {
|
||||
router.go('/listAllPlan');
|
||||
} else {
|
||||
router.go('/listPlan');
|
||||
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('/StatusDashboard');
|
||||
} else {
|
||||
router.go('/listPlan');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw Exception('Token not found in response.');
|
||||
throw Exception('Token missing 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
|
||||
}
|
||||
|
||||
print("Error response: $errorMsg");
|
||||
throw Exception("Authentication failed: $errorMsg");
|
||||
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