org settings

This commit is contained in:
venbaittech 2025-05-23 14:52:28 +05:30
parent aa284d9563
commit 7c9ec2310b
33 changed files with 1119 additions and 339 deletions

View File

@ -125,6 +125,21 @@ class _ListAllPlansState extends State<ListAllPlans> {
}
}
void refresh() {
print("Refresj");
setState(() {
futurePlans = fetchPlans();
});
// Wait for futurePlans to be fetched and update allPlans
futurePlans.then((plans) {
setState(() {
allPlans = plans; // Set allPlans after the fetch is complete
filteredPlans = allPlans; // You can update filteredPlans too if needed
});
});
}
Future<String?> getUserId() async {
final prefs = await SharedPreferences.getInstance();
final String? userDataString = prefs.getString('user_data');
@ -231,13 +246,20 @@ class _ListAllPlansState extends State<ListAllPlans> {
}
void deletePlan(String planId) async {
try {
Map<String, dynamic> planData = await ApiService.getViewPlan(planId);
print("ViewAAA - $planData");
bool confirmed =
await apiService.showCancelConfirmationDialog(context, layoutColor);
postPlanData(planData, planId);
} catch (e) {
print("Error fetching plan: $e");
if (confirmed) {
try {
Map<String, dynamic> planData = await ApiService.getViewPlan(planId);
print("ViewAAA - $planData");
refresh();
// postPlanData(planData, planId);
} catch (e) {
print("Error fetching plan: $e");
}
} else {
print("User cancelled");
}
}
@ -289,10 +311,20 @@ class _ListAllPlansState extends State<ListAllPlans> {
}
Widget buildTableLayout(isDesktop) {
// String _formatDate(String rawDate) {
// try {
// final dateTime = DateTime.parse(rawDate);
// return DateFormat('dd, MMM yyyy hh:m a').format(dateTime);
// } catch (e) {
// return rawDate; // fallback if parsing fails
// }
// }
String _formatDate(String rawDate) {
try {
final dateTime = DateTime.parse(rawDate);
return DateFormat('dd, MMM yyyy hh:m a').format(dateTime);
return DateFormat('dd, MMM yyyy HH:mm')
.format(dateTime); // 24-hour format
} catch (e) {
return rawDate; // fallback if parsing fails
}
@ -753,10 +785,9 @@ class _ListAllPlansState extends State<ListAllPlans> {
},
),
IconButton(
icon: Image.asset(
'assets/images/IconsImg/delete.png',
width: 20,
height: 15),
icon: Icon(
Icons.cancel_rounded,
size: 18),
onPressed: () {
Navigator.pop(context);
deletePlan(plan.planId);

View File

@ -124,6 +124,21 @@ class _TravelAgentListPlansState extends State<TravelAgentListPlans> {
}
}
void refresh() {
print("Refresj");
setState(() {
futurePlans = fetchPlans();
});
// Wait for futurePlans to be fetched and update allPlans
futurePlans.then((plans) {
setState(() {
allPlans = plans; // Set allPlans after the fetch is complete
filteredPlans = allPlans; // You can update filteredPlans too if needed
});
});
}
Future<String?> getUserId() async {
final prefs = await SharedPreferences.getInstance();
final String? userDataString = prefs.getString('user_data');
@ -224,13 +239,20 @@ class _TravelAgentListPlansState extends State<TravelAgentListPlans> {
}
void deletePlan(String planId) async {
try {
Map<String, dynamic> planData = await ApiService.getViewPlan(planId);
print("ViewAAA - $planData");
bool confirmed =
await apiService.showCancelConfirmationDialog(context, layoutColor);
postPlanData(planData, planId);
} catch (e) {
print("Error fetching plan: $e");
if (confirmed) {
try {
Map<String, dynamic> planData = await ApiService.getViewPlan(planId);
print("ViewAAA - $planData");
refresh();
// postPlanData(planData, planId);
} catch (e) {
print("Error fetching plan: $e");
}
} else {
print("User cancelled");
}
}
@ -279,10 +301,20 @@ class _TravelAgentListPlansState extends State<TravelAgentListPlans> {
}
Widget buildTableLayout(isDesktop) {
// String _formatDate(String rawDate) {
// try {
// final dateTime = DateTime.parse(rawDate);
// return DateFormat('dd,MMM yyyy hh:m a').format(dateTime);
// } catch (e) {
// return rawDate; // fallback if parsing fails
// }
// }
String _formatDate(String rawDate) {
try {
final dateTime = DateTime.parse(rawDate);
return DateFormat('dd,MMM yyyy hh:m a').format(dateTime);
return DateFormat('dd, MMM yyyy HH:mm')
.format(dateTime); // 24-hour format
} catch (e) {
return rawDate; // fallback if parsing fails
}
@ -687,10 +719,9 @@ class _TravelAgentListPlansState extends State<TravelAgentListPlans> {
},
),
IconButton(
icon: Image.asset(
'assets/images/IconsImg/delete.png',
width: 20,
height: 15),
icon: Icon(
Icons.cancel_rounded,
size: 18),
onPressed: () {
Navigator.pop(context);
deletePlan(plan.planId);

View File

@ -109,6 +109,21 @@ class _ApprovalListState extends State<ApprovalList> {
}
}
void refresh() {
print("Refresj");
setState(() {
futurePlans = fetchPlans();
});
// Wait for futurePlans to be fetched and update allPlans
futurePlans.then((plans) {
setState(() {
allPlans = plans; // Set allPlans after the fetch is complete
filteredPlans = allPlans; // You can update filteredPlans too if needed
});
});
}
Future<String?> getUserId() async {
final prefs = await SharedPreferences.getInstance();
final String? userDataString = prefs.getString('user_data');
@ -215,13 +230,29 @@ class _ApprovalListState extends State<ApprovalList> {
}
void deletePlan(String planId) async {
try {
Map<String, dynamic> planData = await getViewPlan(planId);
print("ViewAAA - $planData");
// try {
// Map<String, dynamic> planData = await getViewPlan(planId);
// print("ViewAAA - $planData");
//
// postPlanData(planData, planId);
// } catch (e) {
// print("Error fetching plan: $e");
// }
postPlanData(planData, planId);
} catch (e) {
print("Error fetching plan: $e");
bool confirmed =
await apiService.showCancelConfirmationDialog(context, layoutColor);
if (confirmed) {
try {
Map<String, dynamic> planData = await ApiService.getViewPlan(planId);
print("ViewAAA - $planData");
refresh();
// postPlanData(planData, planId);
} catch (e) {
print("Error fetching plan: $e");
}
} else {
print("User cancelled");
}
}
@ -342,10 +373,20 @@ class _ApprovalListState extends State<ApprovalList> {
}
Widget buildTableLayout(isDesktop) {
// String _formatDate(String rawDate) {
// try {
// final dateTime = DateTime.parse(rawDate);
// return DateFormat('dd, MMM yyyy hh:m a').format(dateTime);
// } catch (e) {
// return rawDate; // fallback if parsing fails
// }
// }
String _formatDate(String rawDate) {
try {
final dateTime = DateTime.parse(rawDate);
return DateFormat('dd, MMM yyyy hh:m a').format(dateTime);
return DateFormat('dd, MMM yyyy HH:mm')
.format(dateTime); // 24-hour format
} catch (e) {
return rawDate; // fallback if parsing fails
}
@ -730,10 +771,9 @@ class _ApprovalListState extends State<ApprovalList> {
},
),
IconButton(
icon: Image.asset(
'assets/images/IconsImg/delete.png',
width: 20,
height: 15),
icon: Icon(
Icons.cancel_rounded,
size: 18),
onPressed: () {
Navigator.pop(context);
deletePlan(plan.planId);
@ -924,10 +964,9 @@ class _ApprovalListState extends State<ApprovalList> {
},
),
IconButton(
icon: Image.asset(
'assets/images/IconsImg/delete.png',
width: 20,
height: 15),
icon: Icon(
Icons.cancel_rounded,
size: 18),
onPressed: () {
Navigator.pop(context);
deletePlan(plan.planId);

View File

@ -245,6 +245,17 @@ class ForexDataState extends State<ForexData> {
// dispose();
Navigator.of(context).pop();
} else if (response.statusCode == 404) {
Navigator.of(context).pop();
final message = jsonDecode(response.body)['message'] ?? 'Unknown error';
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.redAccent,
behavior: SnackBarBehavior.floating,
),
);
} else {
print("Failed to submit plan. Status: ${response.statusCode}");
print("Error: ${response.body}");

View File

@ -314,7 +314,6 @@ class _GroupListState extends State<GroupList> {
child: Text(
"Policy: ${group['domestic_policy_name'] ?? group['international_policy_name']}")),
Expanded(child: Text("${group['description'] ?? 'N/A'}")),
Expanded(child: Text(" ${group['created_by']}")),
],
),
Row(

View File

@ -152,17 +152,22 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
"flightfirstToDestinationNotifier: $flightFirstToDestinationNotifier.value ");
// Only set controller after value is updated
final parsedDate =
DateTime.tryParse(flightFirstTripDateNotifier.value ?? '');
// final parsedDate = DateTime.tryParse(flightFirstTripDateNotifier.value ?? '');
final parsedDate = DateFormat("dd-MM-yyyy")
.parse(flightFirstTripDateNotifier.value ?? '');
if (parsedDate != null) {
_checkInController.text = DateFormat('yyyy-MM-dd').format(parsedDate);
_checkInController.text = DateFormat('dd-MM-yyyy').format(parsedDate);
}
final parsedEndDate =
DateTime.tryParse(flightLastTripDateNotifier.value ?? '');
// final parsedEndDate = DateTime.tryParse(flightLastTripDateNotifier.value ?? '');
final parsedEndDate = DateFormat("dd-MM-yyyy")
.parse(flightLastTripDateNotifier.value ?? '');
if (parsedEndDate != null) {
// _checkOutController.text = DateFormat('dd-MM-yyyy').format(parsedEndDate);
_checkOutController.text =
DateFormat('yyyy-MM-dd').format(parsedEndDate);
DateFormat('dd-MM-yyyy').format(parsedEndDate);
}
// Check and set default times if empty
@ -260,8 +265,13 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
checkIn.toString().isNotEmpty &&
checkOut.toString().isNotEmpty) {
try {
final checkInDate = DateTime.parse(checkIn);
final checkOutDate = DateTime.parse(checkOut);
final format = DateFormat("dd-MM-yyyy");
final formatTime = DateFormat("dd-MM-yyyy HH:mm");
// final checkInDate = format.parse(checkIn);
// final checkOutDate = format.parse(checkOut);
final checkInDate = format.parse("$checkIn");
final checkOutDate = format.parse("$checkOut");
if (checkOutDate.isBefore(checkInDate)) {
errorMessages["checkout_date"] =
@ -273,10 +283,9 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
checkInTime.toString().isNotEmpty &&
checkOutTime.toString().isNotEmpty) {
try {
final checkInDateTime =
DateTime.parse("${checkIn}T${checkInTime}");
final checkInDateTime = formatTime.parse("$checkIn $checkInTime");
final checkOutDateTime =
DateTime.parse("${checkOut}T${checkOutTime}");
formatTime.parse("$checkOut $checkOutTime");
if (!checkOutDateTime.isAfter(checkInDateTime)) {
errorMessages["checkout_time"] =
@ -563,7 +572,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
if (pickedDate != null && pickedDate != _selectedCheckInDate) {
setState(() {
_selectedCheckInDate = pickedDate;
_checkInController.text = DateFormat('yyyy-MM-dd').format(pickedDate);
_checkInController.text = DateFormat('dd-MM-yyyy').format(pickedDate);
});
}
}
@ -618,10 +627,14 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
Future<void> _selectCheckOutDate(BuildContext context) async {
DateTime now = DateTime.now();
DateTime today = DateTime(now.year, now.month, now.day);
final format = DateFormat("dd-MM-yyyy HH:mm");
// final prevDateTime = DateTime.parse("$prevDateStr $prevTimeStr");
// final currDateTime = DateTime.parse("$currDateStr $currTimeStr");
DateTime? checkInDate;
try {
checkInDate = DateTime.parse(_checkInController.text);
checkInDate = format.parse(_checkInController.text);
} catch (e) {
checkInDate = today;
}
@ -650,7 +663,8 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
setState(() {
_selectedCheckOutDate = pickedDate;
_checkOutController.text =
DateFormat('yyyy-MM-dd').format(pickedDate);
DateFormat('dd-MM-yyyy').format(pickedDate);
errorMessages.remove("checkout_date");
});
}
}
@ -671,6 +685,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
pickedTime.minute),
);
_checkOutTimeController.text = formattedTime;
errorMessages.remove("checkout_time");
});
}
}

View File

@ -371,7 +371,7 @@ class _BusScreenState extends State<BusScreen> {
if (pickedDate != null && pickedDate != _selectedCheckOutDate) {
setState(() {
_selectedCheckOutDate = pickedDate;
_dateController.text = DateFormat('yyyy-MM-dd').format(pickedDate);
_dateController.text = DateFormat('dd-MM-yyyy').format(pickedDate);
});
}
}

View File

@ -521,6 +521,8 @@ class FlightScreenState extends State<FlightScreen> {
String? currDateStr = textControllers["_date${index}Controller"]?.text;
String? currTimeStr = textControllers["_time${index}Controller"]?.text;
print("prevDateTime - $prevTimeStr");
print("currDateTime - $currTimeStr");
if (prevDateStr != null &&
prevDateStr.isNotEmpty &&
prevTimeStr != null &&
@ -530,8 +532,13 @@ class FlightScreenState extends State<FlightScreen> {
currTimeStr != null &&
currTimeStr.isNotEmpty) {
try {
final prevDateTime = DateTime.parse("$prevDateStr $prevTimeStr");
final currDateTime = DateTime.parse("$currDateStr $currTimeStr");
final format = DateFormat("dd-MM-yyyy HH:mm");
// final prevDateTime = DateTime.parse("$prevDateStr $prevTimeStr");
// final currDateTime = DateTime.parse("$currDateStr $currTimeStr");
final prevDateTime = format.parse("$prevDateStr $prevTimeStr");
final currDateTime = format.parse("$currDateStr $currTimeStr");
if (!currDateTime.isAfter(prevDateTime)) {
errorMessages["time_$index"] = "Must be after previous time";
@ -542,6 +549,7 @@ class FlightScreenState extends State<FlightScreen> {
errorMessages.remove("time_$index");
}
} catch (e) {
print(" Invalid time format");
errorMessages["time_$index"] = "Invalid time format";
}
}
@ -1112,7 +1120,7 @@ class FlightScreenState extends State<FlightScreen> {
flightLastTripDateNotifier.value != null &&
flightLastTripDateNotifier.value!.isNotEmpty) {
try {
final tripDate = DateFormat('yyyy-MM-dd')
final tripDate = DateFormat('dd-MM-yyyy')
.parseStrict(flightLastTripDateNotifier.value!);
if (tripDate.isAfter(today)) {
firstDate = tripDate;
@ -1126,7 +1134,7 @@ class FlightScreenState extends State<FlightScreen> {
if (previousDateString != null && previousDateString.isNotEmpty) {
try {
final previousDate =
DateFormat('yyyy-MM-dd').parseStrict(previousDateString);
DateFormat('dd-MM-yyyy').parseStrict(previousDateString);
if (previousDate.isAfter(today)) {
firstDate = previousDate;
}
@ -1153,7 +1161,7 @@ class FlightScreenState extends State<FlightScreen> {
_selectedCheckOutDate = pickedDate;
// _dateController.text = DateFormat('yyyy-MM-dd').format(pickedDate);
textControllers["_date${index}Controller"]?.text =
DateFormat('yyyy-MM-dd').format(pickedDate);
DateFormat('dd-MM-yyyy').format(pickedDate);
});
}
}

View File

@ -279,7 +279,7 @@ class _ForexScreenState extends State<ForexScreen> {
DateTime? _parseDate(String date) {
try {
return DateFormat("yyyy-MM-dd").parse(date); // Change format if needed
return DateFormat("dd-MM-yyyy").parse(date); // Change format if needed
} catch (e) {
return null;
}
@ -331,18 +331,20 @@ class _ForexScreenState extends State<ForexScreen> {
flightLastTripDateNotifier.value = result['lastTripDate'];
// Only set controller after value is updated
final parsedDate =
DateTime.tryParse(flightFirstTripDateNotifier.value ?? '');
// final parsedDate =
// DateTime.tryParse(flightFirstTripDateNotifier.value ?? '');
final parsedDate = DateFormat("dd-MM-yyyy")
.parse(flightFirstTripDateNotifier.value ?? '');
if (parsedDate != null) {
textControllers["_forexStartDate"]?.text =
DateFormat('yyyy-MM-dd').format(parsedDate);
DateFormat('dd-MM-yyyy').format(parsedDate);
}
final parsedEndDate =
DateTime.tryParse(flightLastTripDateNotifier.value ?? '');
final parsedEndDate = DateFormat("dd-MM-yyyy")
.parse(flightLastTripDateNotifier.value ?? '');
if (parsedEndDate != null) {
textControllers["_forexEndDate"]?.text =
DateFormat('yyyy-MM-dd').format(parsedEndDate);
DateFormat('dd-MM-yyyy').format(parsedEndDate);
}
});
}
@ -766,7 +768,7 @@ class _ForexScreenState extends State<ForexScreen> {
setState(() {
_selectedCheckOutDate = pickedDate;
textControllers["_forexStartDate"]?.text =
DateFormat('yyyy-MM-dd').format(pickedDate);
DateFormat('dd-MM-yyyy').format(pickedDate);
});
}
}
@ -816,7 +818,7 @@ class _ForexScreenState extends State<ForexScreen> {
setState(() {
_selectedEndDate = pickedDate;
textControllers["_forexEndDate"]?.text =
DateFormat('yyyy-MM-dd').format(pickedDate);
DateFormat('dd-MM-yyyy').format(pickedDate);
// textControllers["_forexEndDate"]?.text =
// DateFormat('dd-MM-yyyy').format(initialDate);
});

View File

@ -121,17 +121,24 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
flightLastTripDateNotifier.value = result['lastTripDate'];
// Only set controller after value is updated
final parsedDate =
DateTime.tryParse(flightFirstTripDateNotifier.value ?? '');
// final parsedDate =
// DateTime.tryParse(flightFirstTripDateNotifier.value ?? '');
final parsedDate = DateFormat("dd-MM-yyyy")
.parse(flightFirstTripDateNotifier.value ?? '');
if (parsedDate != null) {
_startdateController.text = DateFormat('yyyy-MM-dd').format(parsedDate);
_startdateController.text = DateFormat('dd-MM-yyyy').format(parsedDate);
}
final parsedEndDate =
DateTime.tryParse(flightLastTripDateNotifier.value ?? '');
final parsedEndDate = DateFormat("dd-MM-yyyy")
.parse(flightLastTripDateNotifier.value ?? '');
if (parsedEndDate != null) {
_endDateController.text =
DateFormat('yyyy-MM-dd').format(parsedEndDate);
DateFormat('dd-MM-yyyy').format(parsedEndDate);
print("parsedDate");
print(parsedDate);
print("parsedEndDate");
print(parsedEndDate);
}
});
}
@ -189,7 +196,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
errorMessages[field] = "Required";
}
}
final format = DateFormat("dd-MM-yyyy");
// Additional validation: checkout_date >= checkin_date
final checkIn = data["start_date"];
final checkOut = data["end_date"];
@ -199,8 +206,8 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
checkIn.toString().isNotEmpty &&
checkOut.toString().isNotEmpty) {
try {
final checkInDate = DateTime.parse(checkIn);
final checkOutDate = DateTime.parse(checkOut);
final checkInDate = format.parse(checkIn);
final checkOutDate = format.parse(checkOut);
if (checkOutDate.isBefore(checkInDate)) {
errorMessages["end_date"] = "EndDate date cannot be before StartDate";
}
@ -230,7 +237,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
DateTime? _parseDate(String date) {
try {
return DateFormat("yyyy-MM-dd").parse(date); // Change format if needed
return DateFormat("dd-MM-yyyy").parse(date); // Change format if needed
} catch (e) {
return null;
}
@ -463,7 +470,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
setState(() {
_selectedCheckOutDate = pickedDate;
_startdateController.text =
DateFormat('yyyy-MM-dd').format(pickedDate);
DateFormat('dd-MM-yyyy').format(pickedDate);
});
}
}
@ -512,7 +519,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
if (pickedDate != null && pickedDate != _selectedCheckOutDate) {
setState(() {
_selectedCheckOutDate = pickedDate;
_endDateController.text = DateFormat('yyyy-MM-dd').format(pickedDate);
_endDateController.text = DateFormat('dd-MM-yyyy').format(pickedDate);
});
}
}

View File

@ -477,7 +477,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
if (pickedDate != null && pickedDate != _selectedCheckOutDate) {
setState(() {
_selectedCheckOutDate = pickedDate;
_dateController.text = DateFormat('yyyy-MM-dd').format(pickedDate);
_dateController.text = DateFormat('dd-MM-yyyy').format(pickedDate);
});
}
}

View File

@ -466,7 +466,7 @@ class _TrainScreenState extends State<TrainScreen> {
if (pickedDate != null && pickedDate != _selectedCheckOutDate) {
setState(() {
_selectedCheckOutDate = pickedDate;
_dateController.text = DateFormat('yyyy-MM-dd').format(pickedDate);
_dateController.text = DateFormat('dd-MM-yyyy').format(pickedDate);
});
}
}

View File

@ -128,10 +128,12 @@ class _VisaScreenState extends State<VisaScreen> {
flightLastTripDateNotifier.value = result['lastTripDate'];
// Only set controller after value is updated
final parsedDate =
DateTime.tryParse(flightFirstTripDateNotifier.value ?? '');
// final parsedDate =
// DateTime.tryParse(flightFirstTripDateNotifier.value ?? '');
final parsedDate = DateFormat("dd-MM-yyyy")
.parse(flightFirstTripDateNotifier.value ?? '');
if (parsedDate != null) {
_dateController.text = DateFormat('yyyy-MM-dd').format(parsedDate);
_dateController.text = DateFormat('dd-MM-yyyy').format(parsedDate);
}
});
}
@ -406,7 +408,7 @@ class _VisaScreenState extends State<VisaScreen> {
if (pickedDate != null && pickedDate != _selectedCheckOutDate) {
setState(() {
_selectedCheckOutDate = pickedDate;
_dateController.text = DateFormat('yyyy-MM-dd').format(pickedDate);
_dateController.text = DateFormat('dd-MM-yyyy').format(pickedDate);
});
}
}

View File

@ -138,10 +138,19 @@ class AccomodationListWidget extends StatelessWidget {
accommodationList.where((item) => item["is_active"] == "1").toList();
print("filteredList- $filteredList");
// String formatDate(String dateString) {
// try {
// DateTime date = DateTime.parse(dateString);
// return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
// } catch (e) {
// return "Invalid Date";
// }
// }
String formatDate(String dateString) {
try {
DateTime date = DateTime.parse(dateString);
return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
DateTime date = DateFormat("dd-MM-yyyy").parse(dateString);
return DateFormat('dd MMM yy').format(date); // Example: 23 May 25
} catch (e) {
return "Invalid Date";
}
@ -150,20 +159,47 @@ class AccomodationListWidget extends StatelessWidget {
String formatTime(String timeString) {
try {
final parts = timeString.split(':');
int hour = int.parse(parts[0]);
int minute = int.parse(parts[1]);
final now = DateTime.now();
final dateTime = DateTime(
now.year,
now.month,
now.day,
int.parse(parts[0]),
int.parse(parts[1]),
);
return DateFormat.jm().format(dateTime); // e.g., 12:16 PM or 12 AM
DateTime dateTime;
if (hour == 24 && minute == 0) {
// 24:00 is treated as 00:00 on the next day
dateTime = DateTime(now.year, now.month, now.day)
.add(const Duration(days: 1));
} else {
if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
throw FormatException("Invalid hour or minute");
}
dateTime = DateTime(now.year, now.month, now.day, hour, minute);
}
return DateFormat('HH:mm').format(dateTime); // 24-hour format
} catch (e) {
return "Invalid Time";
}
}
// String formatTime(String timeString) {
// try {
// final parts = timeString.split(':');
// final now = DateTime.now();
// final dateTime = DateTime(
// now.year,
// now.month,
// now.day,
// int.parse(parts[0]),
// int.parse(parts[1]),
// );
// return DateFormat.jm().format(dateTime); // e.g., 12:16 PM or 12 AM
// } catch (e) {
// return "Invalid Time";
// }
// }
return ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),

View File

@ -117,10 +117,36 @@ class BusListWidget extends StatelessWidget {
busList.where((item) => item["is_active"] == "1").toList();
print("filteredList- $filteredList");
// String formatDate(String dateString) {
// try {
// DateTime date = DateTime.parse(dateString);
// return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
// } catch (e) {
// return "Invalid Date";
// }
// }
//
// String formatTime(String timeString) {
// try {
// final parts = timeString.split(':');
// final now = DateTime.now();
// final dateTime = DateTime(
// now.year,
// now.month,
// now.day,
// int.parse(parts[0]),
// int.parse(parts[1]),
// );
// return DateFormat.jm().format(dateTime); // e.g., 12:16 PM or 12 AM
// } catch (e) {
// return "Invalid Time";
// }
// }
String formatDate(String dateString) {
try {
DateTime date = DateTime.parse(dateString);
return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
DateTime date = DateFormat("dd-MM-yyyy").parse(dateString);
return DateFormat('dd MMM yy').format(date); // Example: 23 May 25
} catch (e) {
return "Invalid Date";
}
@ -129,15 +155,25 @@ class BusListWidget extends StatelessWidget {
String formatTime(String timeString) {
try {
final parts = timeString.split(':');
int hour = int.parse(parts[0]);
int minute = int.parse(parts[1]);
final now = DateTime.now();
final dateTime = DateTime(
now.year,
now.month,
now.day,
int.parse(parts[0]),
int.parse(parts[1]),
);
return DateFormat.jm().format(dateTime); // e.g., 12:16 PM or 12 AM
DateTime dateTime;
if (hour == 24 && minute == 0) {
// 24:00 is treated as 00:00 on the next day
dateTime = DateTime(now.year, now.month, now.day)
.add(const Duration(days: 1));
} else {
if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
throw FormatException("Invalid hour or minute");
}
dateTime = DateTime(now.year, now.month, now.day, hour, minute);
}
return DateFormat('HH:mm').format(dateTime); // 24-hour format
} catch (e) {
return "Invalid Time";
}

View File

@ -177,10 +177,36 @@ class _FlightListWidgetState extends State<FlightListWidget> {
.toString();
}
// String formatDate(String dateString) {
// try {
// DateTime date = DateTime.parse(dateString);
// return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
// } catch (e) {
// return "Invalid Date";
// }
// }
//
// String formatTime(String timeString) {
// try {
// final parts = timeString.split(':');
// final now = DateTime.now();
// final dateTime = DateTime(
// now.year,
// now.month,
// now.day,
// int.parse(parts[0]),
// int.parse(parts[1]),
// );
// return DateFormat.jm().format(dateTime); // e.g., 12:16 PM or 12 AM
// } catch (e) {
// return "Invalid Time";
// }
// }
String formatDate(String dateString) {
try {
DateTime date = DateTime.parse(dateString);
return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
DateTime date = DateFormat("dd-MM-yyyy").parse(dateString);
return DateFormat('dd MMM yy').format(date); // Example: 23 May 25
} catch (e) {
return "Invalid Date";
}
@ -189,15 +215,25 @@ class _FlightListWidgetState extends State<FlightListWidget> {
String formatTime(String timeString) {
try {
final parts = timeString.split(':');
int hour = int.parse(parts[0]);
int minute = int.parse(parts[1]);
final now = DateTime.now();
final dateTime = DateTime(
now.year,
now.month,
now.day,
int.parse(parts[0]),
int.parse(parts[1]),
);
return DateFormat.jm().format(dateTime); // e.g., 12:16 PM or 12 AM
DateTime dateTime;
if (hour == 24 && minute == 0) {
// 24:00 is treated as 00:00 on the next day
dateTime = DateTime(now.year, now.month, now.day)
.add(const Duration(days: 1));
} else {
if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
throw FormatException("Invalid hour or minute");
}
dateTime = DateTime(now.year, now.month, now.day, hour, minute);
}
return DateFormat('HH:mm').format(dateTime); // 24-hour format
} catch (e) {
return "Invalid Time";
}

View File

@ -171,15 +171,51 @@ class ForexListWidget extends StatelessWidget {
.toString();
}
// String formatDate(String dateString) {
// try {
// DateTime date = DateTime.parse(dateString);
// return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
// } catch (e) {
// return "Invalid Date";
// }
// }
String formatDate(String dateString) {
try {
DateTime date = DateTime.parse(dateString);
return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
DateTime date = DateFormat("dd-MM-yyyy").parse(dateString);
return DateFormat('dd MMM yy').format(date); // Example: 23 May 25
} catch (e) {
return "Invalid Date";
}
}
String formatTime(String timeString) {
try {
final parts = timeString.split(':');
int hour = int.parse(parts[0]);
int minute = int.parse(parts[1]);
final now = DateTime.now();
DateTime dateTime;
if (hour == 24 && minute == 0) {
// 24:00 is treated as 00:00 on the next day
dateTime = DateTime(now.year, now.month, now.day)
.add(const Duration(days: 1));
} else {
if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
throw FormatException("Invalid hour or minute");
}
dateTime = DateTime(now.year, now.month, now.day, hour, minute);
}
return DateFormat('HH:mm').format(dateTime); // 24-hour format
} catch (e) {
return "Invalid Time";
}
}
return ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),

View File

@ -147,10 +147,18 @@ class InsuranceListWidget extends StatelessWidget {
.toString();
}
// String formatDate(String dateString) {
// try {
// DateTime date = DateTime.parse(dateString);
// return DateFormat('dd MMMM yy').format(date); // Example: 4 Apr 25
// } catch (e) {
// return "Invalid Date";
// }
// }
String formatDate(String dateString) {
try {
DateTime date = DateTime.parse(dateString);
return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
DateTime date = DateFormat("dd-MM-yyyy").parse(dateString);
return DateFormat('dd MMM yy').format(date); // Example: 23 May 25
} catch (e) {
return "Invalid Date";
}

View File

@ -140,10 +140,36 @@ class TaxiListWidget extends StatelessWidget {
.toString();
}
// String formatDate(String dateString) {
// try {
// DateTime date = DateTime.parse(dateString);
// return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
// } catch (e) {
// return "Invalid Date";
// }
// }
//
// String formatTime(String timeString) {
// try {
// final parts = timeString.split(':');
// final now = DateTime.now();
// final dateTime = DateTime(
// now.year,
// now.month,
// now.day,
// int.parse(parts[0]),
// int.parse(parts[1]),
// );
// return DateFormat.jm().format(dateTime); // e.g., 12:16 PM or 12 AM
// } catch (e) {
// return "Invalid Time";
// }
// }
String formatDate(String dateString) {
try {
DateTime date = DateTime.parse(dateString);
return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
DateTime date = DateFormat("dd-MM-yyyy").parse(dateString);
return DateFormat('dd MMM yy').format(date); // Example: 23 May 25
} catch (e) {
return "Invalid Date";
}
@ -152,15 +178,25 @@ class TaxiListWidget extends StatelessWidget {
String formatTime(String timeString) {
try {
final parts = timeString.split(':');
int hour = int.parse(parts[0]);
int minute = int.parse(parts[1]);
final now = DateTime.now();
final dateTime = DateTime(
now.year,
now.month,
now.day,
int.parse(parts[0]),
int.parse(parts[1]),
);
return DateFormat.jm().format(dateTime); // e.g., 12:16 PM or 12 AM
DateTime dateTime;
if (hour == 24 && minute == 0) {
// 24:00 is treated as 00:00 on the next day
dateTime = DateTime(now.year, now.month, now.day)
.add(const Duration(days: 1));
} else {
if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
throw FormatException("Invalid hour or minute");
}
dateTime = DateTime(now.year, now.month, now.day, hour, minute);
}
return DateFormat('HH:mm').format(dateTime); // 24-hour format
} catch (e) {
return "Invalid Time";
}

View File

@ -221,10 +221,36 @@ class _TrainListWidgetState extends State<TrainListWidget> {
.toString();
}
// String formatDate(String dateString) {
// try {
// DateTime date = DateTime.parse(dateString);
// return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
// } catch (e) {
// return "Invalid Date";
// }
// }
//
// String formatTime(String timeString) {
// try {
// final parts = timeString.split(':');
// final now = DateTime.now();
// final dateTime = DateTime(
// now.year,
// now.month,
// now.day,
// int.parse(parts[0]),
// int.parse(parts[1]),
// );
// return DateFormat.jm().format(dateTime); // e.g., 12:16 PM or 12 AM
// } catch (e) {
// return "Invalid Time";
// }
// }
String formatDate(String dateString) {
try {
DateTime date = DateTime.parse(dateString);
return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
DateTime date = DateFormat("dd-MM-yyyy").parse(dateString);
return DateFormat('dd MMM yy').format(date); // Example: 23 May 25
} catch (e) {
return "Invalid Date";
}
@ -233,15 +259,25 @@ class _TrainListWidgetState extends State<TrainListWidget> {
String formatTime(String timeString) {
try {
final parts = timeString.split(':');
int hour = int.parse(parts[0]);
int minute = int.parse(parts[1]);
final now = DateTime.now();
final dateTime = DateTime(
now.year,
now.month,
now.day,
int.parse(parts[0]),
int.parse(parts[1]),
);
return DateFormat.jm().format(dateTime); // e.g., 12:16 PM or 12 AM
DateTime dateTime;
if (hour == 24 && minute == 0) {
// 24:00 is treated as 00:00 on the next day
dateTime = DateTime(now.year, now.month, now.day)
.add(const Duration(days: 1));
} else {
if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
throw FormatException("Invalid hour or minute");
}
dateTime = DateTime(now.year, now.month, now.day, hour, minute);
}
return DateFormat('HH:mm').format(dateTime); // 24-hour format
} catch (e) {
return "Invalid Time";
}

View File

@ -212,15 +212,50 @@ class VisaListWidget extends StatelessWidget {
.toString();
}
// String formatDate(String dateString) {
// try {
// DateTime date = DateTime.parse(dateString);
// return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
// } catch (e) {
// return "Invalid Date";
// }
// }
String formatDate(String dateString) {
try {
DateTime date = DateTime.parse(dateString);
return DateFormat('d MMM yy').format(date); // Example: 4 Apr 25
DateTime date = DateFormat("dd-MM-yyyy").parse(dateString);
return DateFormat('dd MMM yy').format(date); // Example: 23 May 25
} catch (e) {
return "Invalid Date";
}
}
String formatTime(String timeString) {
try {
final parts = timeString.split(':');
int hour = int.parse(parts[0]);
int minute = int.parse(parts[1]);
final now = DateTime.now();
DateTime dateTime;
if (hour == 24 && minute == 0) {
// 24:00 is treated as 00:00 on the next day
dateTime = DateTime(now.year, now.month, now.day)
.add(const Duration(days: 1));
} else {
if (hour < 0 || hour > 23 || minute < 0 || minute > 59) {
throw FormatException("Invalid hour or minute");
}
dateTime = DateTime(now.year, now.month, now.day, hour, minute);
}
return DateFormat('HH:mm').format(dateTime); // 24-hour format
} catch (e) {
return "Invalid Time";
}
}
return ListView.builder(
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),

View File

@ -232,7 +232,20 @@ class _CreatePlansState extends State<CreatePlan> {
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
),
onPressed: () {
isApprover ? context.go('/approvallist') : context.go('/listPlan');
final currentUri = GoRouterState.of(context)
.uri
.toString(); // safer than `.location`
print("currentUri - $currentUri");
if (currentUri == "/allTrips/trips") {
context.go('/listAllPlan');
} else if (currentUri == "/createPlan") {
context.go('/listPlan');
} else {
isApprover
? context.go('/approvallist')
: context.go('/listPlan');
}
},
child: Text("Cancel")),
SizedBox(
@ -1091,9 +1104,20 @@ class CreateNewPlansState extends State<CreateNewPlan> {
// " ");
postPlanData(planData);
widget.isApprover
? context.go('/approvallist')
: context.go('/listPlan');
final currentUri = GoRouterState.of(context)
.uri
.toString(); // safer than `.location`
print("currentUri - $currentUri");
if (currentUri == "/allTrips/trips") {
context.go('/listAllPlan');
} else if (currentUri == "/createPlan") {
context.go('/listPlan');
} else {
widget.isApprover
? context.go('/approvallist')
: context.go('/listPlan');
}
}
});
}

View File

@ -49,7 +49,6 @@ class _ListPlansState extends State<ListPlans> {
void initState() {
super.initState();
super.initState();
// futurePlans = fetchPlans();
//
// futurePlans.then((plans) {
@ -78,6 +77,21 @@ class _ListPlansState extends State<ListPlans> {
// futurePlans = fetchPlans();
}
void refresh() {
print("Refresj");
setState(() {
futurePlans = fetchPlans();
});
// Wait for futurePlans to be fetched and update allPlans
futurePlans.then((plans) {
setState(() {
allPlans = plans; // Set allPlans after the fetch is complete
filteredPlans = allPlans; // You can update filteredPlans too if needed
});
});
}
void filterPlans(String query) {
print("allPlans before filtering: $allPlans");
final lowerQuery = query.toLowerCase();
@ -276,13 +290,29 @@ class _ListPlansState extends State<ListPlans> {
// }
void deletePlan(String planId) async {
try {
Map<String, dynamic> planData = await ApiService.getViewPlan(planId);
print("ViewAAA - $planData");
// try {
// Map<String, dynamic> planData = await ApiService.getViewPlan(planId);
// print("ViewAAA - $planData");
//
// postPlanData(planData, planId);
// } catch (e) {
// print("Error fetching plan: $e");
// }
postPlanData(planData, planId);
} catch (e) {
print("Error fetching plan: $e");
bool confirmed =
await apiService.showCancelConfirmationDialog(context, layoutColor);
if (confirmed) {
try {
Map<String, dynamic> planData = await ApiService.getViewPlan(planId);
print("ViewAAA - $planData");
refresh();
// postPlanData(planData, planId);
} catch (e) {
print("Error fetching plan: $e");
}
} else {
print("User cancelled");
}
}
@ -331,10 +361,20 @@ class _ListPlansState extends State<ListPlans> {
}
Widget buildTableLayout(isDesktop) {
// String _formatDate(String rawDate) {
// try {
// final dateTime = DateTime.parse(rawDate);
// return DateFormat('dd, MMM yyyy hh:m a').format(dateTime);
// } catch (e) {
// return rawDate; // fallback if parsing fails
// }
// }
String _formatDate(String rawDate) {
try {
final dateTime = DateTime.parse(rawDate);
return DateFormat('dd, MMM yyyy hh:m a').format(dateTime);
return DateFormat('dd, MMM yyyy HH:mm')
.format(dateTime); // 24-hour format
} catch (e) {
return rawDate; // fallback if parsing fails
}
@ -796,24 +836,27 @@ class _ListPlansState extends State<ListPlans> {
isMyTrips: true);
},
),
if (plan.statusValue ==
"Pending Approval" ||
plan.statusValue ==
"Partially Approved")
IconButton(
icon: Image.asset(
'assets/images/IconsImg/edit.png',
width: 20,
height: 15),
onPressed: () {
Navigator.pop(context);
ApiService.viewPlan(
context, plan.planId,
isViewMode: false,
isMyTrips: true);
},
),
IconButton(
icon: Image.asset(
'assets/images/IconsImg/edit.png',
width: 20,
height: 15),
onPressed: () {
Navigator.pop(context);
ApiService.viewPlan(
context, plan.planId,
isViewMode: false,
isMyTrips: true);
},
),
IconButton(
icon: Image.asset(
'assets/images/IconsImg/delete.png',
width: 20,
height: 15),
icon: Icon(
Icons.cancel_rounded,
size: 18),
onPressed: () {
Navigator.pop(context);
deletePlan(plan.planId);
@ -953,11 +996,103 @@ class _ListPlansState extends State<ListPlans> {
),
),
),
PlanPopupMenu(
plan: plan,
deletePlan: deletePlan,
apiService: apiService,
layoutColor: layoutColor,
// PlanPopupMenu(
// plan: plan,
// deletePlan: deletePlan,
// apiService: apiService,
// layoutColor: layoutColor,
// ),
PopupMenuButton<int>(
color: Colors.white,
padding: EdgeInsets.zero,
offset: Offset(0, 30),
icon: Icon(Icons.more_vert,
size: 14, color: Color(0xFF475569)),
itemBuilder: (context) => [
CustomPopupMenuEntry(
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 8, vertical: 8),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.center,
children: [
IconButton(
icon: Icon(
Icons.remove_red_eye,
color: Color(0xFF475569),
size: 18),
onPressed: () {
Navigator.pop(
context); // Close popup manually
ApiService.viewPlan(
context, plan.planId,
isViewMode: true,
isMyTrips: true);
},
),
if (plan.statusValue ==
"Pending Approval" ||
plan.statusValue ==
"Partially Approved")
IconButton(
icon: Image.asset(
'assets/images/IconsImg/edit.png',
width: 20,
height: 15),
onPressed: () {
Navigator.pop(context);
ApiService.viewPlan(
context, plan.planId,
isViewMode: false,
isMyTrips: true);
},
),
IconButton(
icon: Icon(
Icons.cancel_rounded,
size: 18),
onPressed: () {
Navigator.pop(context);
deletePlan(plan.planId);
},
),
IconButton(
icon: Icon(Icons.download,
color: Color(0xFF114D8B),
size: 18),
onPressed: () {
Navigator.pop(context);
apiService.getPdfDownload(
plan.planId);
},
),
IconButton(
icon: const Icon(
Icons.comment,
color: Color(0xFF475569),
size: 11,
),
onPressed: () {
showDialog(
context: context,
builder: (context) =>
CommentModalList(
// planId: plan.planId,
planId: plan
.planId
.toString(),
layoutColorForUser:
layoutColor!,
role: "User"),
);
}),
],
),
),
),
],
),
],
),

View File

@ -115,9 +115,9 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
"address",
"postalCode",
"country",
"passportNumber",
"placeOfIssue",
"passportDoc",
// "passportNumber",
// "placeOfIssue",
// "passportDoc",
"userType",
"roleId",
"deptId",
@ -128,8 +128,8 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
"employeeCode",
"delegationStartDate",
"delegationEndDate",
"dateOfIssue",
"dateOfExpiry",
// "dateOfIssue",
// "dateOfExpiry",
"changePassword"
];
@ -166,12 +166,12 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
"second_approver": selectedSecondApprover,
"third_approver": selectedThirdApprover,
"delegated_to_user_id": selectedSubstituteApprover,
"passport_number": controllers["passportNumber"]?.text,
"place_of_issue": controllers["placeOfIssue"]?.text,
"passport_document": passportFile,
// "passport_number": controllers["passportNumber"]?.text,
// "place_of_issue": controllers["placeOfIssue"]?.text,
// "passport_document": passportFile,
"date_of_issue": controllers["dateOfIssue"]?.text,
"date_of_expiry": controllers["dateOfExpiry"]?.text,
// "date_of_issue": controllers["dateOfIssue"]?.text,
// "date_of_expiry": controllers["dateOfExpiry"]?.text,
"created_by": userId,
"is_active": "1",
"org_id": orgId,
@ -725,23 +725,38 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
request.fields['user_id'] = apiselectedUser!["user_id"].toString();
}
// Add all non-null and non-empty user data fields
// userData.forEach((key, value) {
// if (value != null && value.toString().trim().isNotEmpty) {
// request.fields[key] = value.toString();
// // if (value == null) {
// // // skip nulls
// // return;
// // }
//
// if (key == 'travel_details' && value is Map<String, dynamic>) {
// // Encode travel_details map as JSON string
// request.fields[key] = jsonEncode(value);
// print("✅ Encoded travel_details: ${request.fields[key]}");
// } else {
// // If the value is empty or only whitespace, add it as empty string
// if (value.toString().trim().isEmpty) {
// request.fields[key] = '';
// } else {
// // Otherwise add the actual string value
// request.fields[key] = value.toString();
// }
// }
// });
userData.forEach((key, value) {
if (value != null && value.toString().trim().isNotEmpty) {
if (key == 'travel_details' && value is Map<String, dynamic>) {
// Encode travel_details as a proper JSON string
request.fields[key] = jsonEncode(value);
print("✅ Encoded travel_details: ${request.fields[key]}");
} else {
request.fields[key] = value.toString();
}
// if (value != null && value.toString().trim().isNotEmpty) {
if (key == 'travel_details' && value is Map<String, dynamic>) {
// Encode travel_details as a proper JSON string
request.fields[key] = jsonEncode(value);
print("✅ Encoded travel_details: ${request.fields[key]}");
} else {
request.fields[key] = value.toString();
}
// }
});
// Attach file if selected
@ -1031,6 +1046,8 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
onFirstSubsApproverChanged: (role) {
setState(() {
selectedSubstituteApprover = role;
print("onFirstSubsApproverChanged - $selectedSubstituteApprover");
});
},
);

View File

@ -96,7 +96,8 @@ class _OfficeDetailsState extends State<OfficeDetails> {
Uint8List? passportDocumentBytes;
String? passportFileUrlFromApi;
String? base64PDF;
DateTime? _selectedCheckOutDate;
DateTime? _selectedEndDate;
html.File? passportFile;
List<String> dataHeader = [
@ -169,7 +170,16 @@ class _OfficeDetailsState extends State<OfficeDetails> {
void handleReset() {
setState(() {
isResetTrue = true;
selectedSubstituteApprover = null;
widget.onFirstSubsApproverChanged?.call(null); // Notify parent if needed
// Clear date selections and fields
_selectedCheckOutDate = null;
_selectedEndDate = null;
widget.controllers["delegationStartDate"]?.text = "";
widget.controllers["delegationEndDate"]?.text = "";
// selectedSubstituteApprover = null;
// widget.onFirstSubsApproverChanged?.call(null);
// widget.controllers["delegationStartDate"]?.clear();
@ -1051,9 +1061,6 @@ class _OfficeDetailsState extends State<OfficeDetails> {
}
Widget buildDelegationStartDateField(bool isDesktop) {
DateTime? _selectedCheckOutDate;
DateTime? _selectedEndDate;
Future<void> _selectCheckOutDate(BuildContext context) async {
DateTime now = DateTime.now();
DateTime today = DateTime(now.year, now.month, now.day);
@ -1150,7 +1157,7 @@ class _OfficeDetailsState extends State<OfficeDetails> {
}
Widget buildDelegationEndDateField(bool isDesktop) {
DateTime? _selectedEndDate;
// DateTime? _selectedEndDate;
Future<void> _selectForexEndDate(BuildContext context) async {
DateTime now = DateTime.now();
DateTime today = DateTime(now.year, now.month, now.day);

View File

@ -237,6 +237,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
border: Border(
top: BorderSide(

View File

@ -662,6 +662,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height,
decoration: BoxDecoration(
border: Border(
top: BorderSide(

View File

@ -46,17 +46,19 @@ class _MyAppState extends State<MyApp> {
SemanticsBinding.instance.ensureSemantics(); // Safe here
if (kIsWeb) {
final uri = Uri.parse(html.window.location.href);
if (uri.path == '/tstat/authredirection' &&
if (uri.path == '/authredirection' &&
uri.queryParameters['code'] != null) {
_authCode = uri.queryParameters['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);
});
} else {
html.window.console.log("No auth code found or wrong path.");
}
}
}

View File

@ -271,10 +271,8 @@ class _CustomAppBarState extends State<CustomAppBar> {
icon: Icons.format_list_bulleted_rounded,
// icon: Icons.insights_outlined,
),
if (userDetails["role"] != "Travel Agent")
const SizedBox(width: 20),
if (userData?["role"] == "Travel Agent")
buildNavItem(
"Trips",
@ -286,7 +284,6 @@ class _CustomAppBarState extends State<CustomAppBar> {
icon: Icons.shopping_bag_outlined,
// icon: Icons.request_page_outlined,
),
if (userData?["role"] != "Travel Agent") // for others
buildNavItem(
"My Trips",
@ -297,18 +294,6 @@ class _CustomAppBarState extends State<CustomAppBar> {
isSelected: selectedTab == TabSelection.myTrips,
icon: Icons.shopping_bag_outlined,
),
// if (userDetails["role"] == "Travel Agent")
// buildNavItem("My Trips", _myTravelRequestColor,
// () => context.go('/listTravelAgentPlan'),
// isSelected: selectedTab == "My Trips"),
// ...[
// const SizedBox(width: 20),
// buildNavItem("My Trips", _myTravelRequestColor,
// () => context.go('/listPlan'),
// isSelected: selectedTab == "My Trips"),
// ],
//
const SizedBox(width: 20),
if (userData?["role"] != "Travel Agent")
buildNavItem(
@ -321,23 +306,6 @@ class _CustomAppBarState extends State<CustomAppBar> {
isSelected: selectedTab == TabSelection.myApprovals,
icon: Icons.verified_outlined,
),
// buildNavItem("My Approvals", _myApprovalsColor, () {
// isSelected:
// selectedTab == "My Approvals",
// context.go('/ApprovalList'),
// icon:Icons.insights_outlined;
// })
// if (userData?["role"] == "Travel Agent") {
// isSelected:
// selectedTab == "My Approvals";
// context.go('/listTravelAgentPlan');
// } else {
// isSelected:
// selectedTab == "My Approvals";
// context.go('/ApprovalList');
// }
],
),
),
@ -359,26 +327,29 @@ class _CustomAppBarState extends State<CustomAppBar> {
offset: const Offset(0, 50), // 👈 shift it 50 pixels down
onSelected: (String value) {
switch (value) {
case '/OrganizationSetup':
context.go('/OrganizationSetup');
case '/OrganizationSettings':
context.go('/OrganizationSettings');
break;
// case '/OrganizationSetup':
// context.go('/OrganizationSetup');
// break;
case '/listUser':
context.go('/listUser');
break;
case '/group':
context.go('/group');
break;
case '/department':
context.go('/department');
break;
case '/PolicyList':
context.go('/PolicyList');
case '/getPerdiem':
context.go('/getPerdiem');
case '/templateList':
context.go('/templateList');
case '/template':
context.go('/template');
// case '/group':
// context.go('/group');
// break;
// case '/department':
// context.go('/department');
// break;
// case '/PolicyList':
// context.go('/PolicyList');
// case '/getPerdiem':
// context.go('/getPerdiem');
// case '/templateList':
// context.go('/templateList');
// case '/template':
// context.go('/template');
case '/CreateUserDetails':
context.go(
"/CreateUserDetails",
@ -441,18 +412,6 @@ class _CustomAppBarState extends State<CustomAppBar> {
];
},
// itemBuilder: (BuildContext context) {
// final isUser = userData?["role"] == "User";
// final filteredItems = isUser
// ? menuItems
// .where((item) =>
// item['value'] == '/CreateUserDetails' ||
// item['value'] == '/logout')
// .toList()
// : menuItems;
//
// return filteredItems.map(buildMenuItem).toList();
// },
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: Row(
@ -503,26 +462,31 @@ class _CustomAppBarState extends State<CustomAppBar> {
}
final List<Map<String, dynamic>> menuItems = [
// {
// 'value': '/OrganizationSetup',
// 'icon': Icons.business,
// 'label': 'Organization'
// },
{
'value': '/OrganizationSetup',
'value': '/OrganizationSettings',
'icon': Icons.business,
'label': 'Organization'
'label': 'Org Management'
},
{
'value': '/listUser',
'icon': Icons.manage_accounts,
'label': 'User Management'
},
{'value': '/group', 'icon': Icons.group, 'label': 'Group'},
{'value': '/department', 'icon': Icons.group, 'label': 'Department'},
{'value': '/PolicyList', 'icon': Icons.policy, 'label': 'Policy'},
{'value': '/getPerdiem', 'icon': Icons.ac_unit_sharp, 'label': 'Forex'},
{
'value': '/templateList',
'icon': Icons.ac_unit_sharp,
'label': 'Template List'
},
{'value': '/template', 'icon': Icons.ac_unit_sharp, 'label': 'Template'},
// {'value': '/group', 'icon': Icons.group, 'label': 'Group'},
// {'value': '/department', 'icon': Icons.group, 'label': 'Department'},
// {'value': '/PolicyList', 'icon': Icons.policy, 'label': 'Policy'},
// {'value': '/getPerdiem', 'icon': Icons.ac_unit_sharp, 'label': 'Forex'},
// {
// 'value': '/templateList',
// 'icon': Icons.ac_unit_sharp,
// 'label': 'Template List'
// },
// {'value': '/template', 'icon': Icons.ac_unit_sharp, 'label': 'Template'},
{
'value': '/CreateUserDetails',
'icon': Icons.account_circle,
@ -607,58 +571,3 @@ Widget buildNavItem(String label, VoidCallback onTap, Color? layoutColor,
),
);
}
Widget buildNavItem1(String label, VoidCallback onTap,
{bool isSelected = true, IconData? icon}) {
return MouseRegion(
cursor: SystemMouseCursors.click,
child: GestureDetector(
onTap: onTap,
child: Container(
padding: EdgeInsets.only(bottom: 2),
decoration: isSelected
? BoxDecoration(
border: Border(
bottom: BorderSide(
width: 2, // underline thickness
color: Colors.red),
),
)
: null, // no underline when not selected
child: Row(
children: [
if (icon != null)
Icon(
icon,
size: 16,
color: isSelected ? Colors.red : Colors.black,
// color: Colors.red,
),
if (icon != null) SizedBox(width: 4),
Text(
label,
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: isSelected ? Colors.red : Colors.black,
// color: Colors.red,
),
),
// Red underline positioned below (e.g. under green line)
if (isSelected)
Positioned(
bottom: -50, // adjust this to push it below green line
left: 0,
right: 0,
child: Container(
height: 2,
color: Colors.red,
),
),
],
),
),
),
);
}

View File

@ -14,6 +14,7 @@ import 'package:frontend/Screens/policy/policy.dart';
import 'package:frontend/Screens/policy/policy_list.dart';
import 'package:frontend/Screens/userManagement/create_user/create_user1.dart';
import 'package:frontend/Screens/userManagement/user_List.dart';
import 'package:frontend/routes/organizationSetting.dart';
import 'package:go_router/go_router.dart';
import '../Screens/allTrips/list_all_plans.dart';
@ -102,6 +103,10 @@ final GoRouter router = GoRouter(
path: '/OrganizationSetup',
builder: (context, state) => OrgSetUp(),
),
GoRoute(
path: '/OrganizationSettings',
builder: (context, state) => OrganizationSetting(),
),
GoRoute(
path: '/group',
builder: (context, state) => GroupList(),

View File

@ -0,0 +1,184 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:responsive_builder/responsive_builder.dart';
import 'custom_appBar.dart';
import 'custom_drawer.dart';
class OrganizationSetting extends StatefulWidget {
const OrganizationSetting({super.key});
@override
OrganizationSettingState createState() => OrganizationSettingState();
}
class OrganizationSettingState extends State<OrganizationSetting> {
@override
Widget build(BuildContext context) {
return ResponsiveBuilder(builder: (context, sizingInfo) {
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
return Scaffold(
backgroundColor: Color(0xFFf5f5f5),
// backgroundColor: Color(0xFFFCFCFC),
// appBar: isDesktop ? null : const CustomAppBar(title: 'Home'),
// drawer: isDesktop ? null : CustomDrawer(isDesktop: false),
appBar: CustomAppBar(isDesktop: isDesktop),
drawer: CustomDrawer(isDesktop: false),
body: Padding(
padding: isDesktop
? EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width *
0.1, // 30% of screen width as horizontal padding
vertical: MediaQuery.of(context).size.height *
0, // 5% of screen height as vertical padding
)
: EdgeInsets.all(0),
child: Row(
children: [
// if (isDesktop) CustomDrawer(isDesktop: true),
Expanded(child: buildGroupListLayout(isDesktop))
],
),
),
);
});
}
Widget buildGroupListLayout(bool isDesktop) {
final int cardsPerRow = 3;
final List<Map<String, dynamic>> menuItems = [
{
'value': '/OrganizationSetup',
'icon': Icons.business,
'label': 'Organization Settings',
'description': 'Edit Logo and Email Configurations'
},
{
'value': '/group',
'icon': Icons.groups,
'label': 'Groups',
'description': 'Create and Edit Groups'
},
{
'value': '/PolicyList',
'icon': Icons.policy,
'label': 'Travel Policies',
'description': 'Create and Edit Travel Policy'
},
{
'value': '/department',
'icon': Icons.group_add_outlined,
'label': 'Departments',
'description': 'Create and Edit Department'
},
{
'value': '/getPerdiem',
'icon': Icons.attach_money,
'label': 'Perdiem Amount',
'description': 'Create and Edit Perdiem Amount'
},
{
'value': '/templateList',
'icon': Icons.email_outlined,
'label': 'Email Templates',
'description': ' Edit Email Template'
},
];
List<Widget> rows = [];
for (int i = 0; i < menuItems.length; i += cardsPerRow) {
List<Widget> cards = [];
for (int j = i; j < i + cardsPerRow && j < menuItems.length; j++) {
final item = menuItems[j];
cards.add(
Expanded(
child: Card(
margin: EdgeInsets.all(8),
color: Colors.white,
child: InkWell(
onTap: () {
// Navigate using go_router
final route = item['value'] as String;
switch (route) {
case '/OrganizationSetup':
case '/group':
case '/department':
case '/PolicyList':
case '/getPerdiem':
case '/templateList':
context.go(route);
break;
default:
// Handle unknown routes or do nothing
print('Unknown route: $route');
}
},
child: Padding(
padding: EdgeInsets.all(12),
child: Row(
children: [
Icon(item['icon'], size: 40, color: Color(0xFF114D8B)),
SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
item['label'],
style: GoogleFonts.poppins(
fontSize: 14, fontWeight: FontWeight.w500),
),
SizedBox(height: 4),
Text(
item['description'],
style: TextStyle(
fontSize: 14, color: Colors.grey[700]),
),
],
),
),
],
),
),
),
),
),
);
}
rows.add(Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: cards,
));
}
return Container(
// color: Colors.white,
padding: EdgeInsets.symmetric(vertical: 16, horizontal: 12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Organization Settings',
style: GoogleFonts.poppins(
fontSize: 15,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
),
SizedBox(height: 8),
Divider(thickness: 0.2, color: Colors.blueGrey.shade100),
SizedBox(height: 12),
...rows, // Spread operator to insert all row widgets
],
),
);
}
}

View File

@ -3,6 +3,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:frontend/utils/auth_utils.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import 'package:universal_html/html.dart' as html;
import 'package:universal_html/js.dart';
@ -423,6 +424,32 @@ class ApiService {
}
static Future<Map<String, dynamic>> getViewPlan(String planId) async {
final String apiUrldata = '$apiUrl/api/plans/cancle_plan?plan_id=$planId';
// final String apiUrldata = '$apiUrl/api/plans/find/$planId';
print("API URL: $apiUrldata");
// final token = await getToken();
final token = await getToken();
final response = await http.get(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token', // Add token here
'Content-Type': 'application/json',
},
);
if (response.statusCode == 200) {
final Map<String, dynamic>? resData = json.decode(response.body);
return resData?["data"];
} else {
throw Exception('Failed to load plans');
}
}
static Future<Map<String, dynamic>> getViewPlanEdit(String planId) async {
final String apiUrldata = '$apiUrl/api/plans/find/$planId';
print("API URL: $apiUrldata");
// final token = await getToken();
@ -449,7 +476,7 @@ class ApiService {
static Future<void> viewPlan(BuildContext context, String planId,
{bool isViewMode = false, bool isMyTrips = false}) async {
try {
Map<String, dynamic> planData = await getViewPlan(planId);
Map<String, dynamic> planData = await getViewPlanEdit(planId);
print("ViewAAA - $planData");
context.go(isMyTrips ? '/createPlan' : '/allTrips/trips',
@ -462,7 +489,7 @@ class ApiService {
static Future<void> viewPlanForApprover(BuildContext context, String planId,
{bool isViewMode = false, bool isApprover = true}) async {
try {
Map<String, dynamic> planData = await getViewPlan(planId);
Map<String, dynamic> planData = await getViewPlanEdit(planId);
print("ViewAAA - $planData");
context.replace('/createPlan', extra: {
@ -840,16 +867,18 @@ class ApiService {
// print(data);
if (!data.containsKey('data') || data['data'] is! List) {
throw Exception("Invalid response format: 'data' field is missing or not a List");
throw Exception(
"Invalid response format: 'data' field is missing or not a List");
}
final List<Map<String, dynamic>> listData = List<Map<String, dynamic>>.from(data['data']);
final List<Map<String, dynamic>> listData =
List<Map<String, dynamic>>.from(data['data']);
if (listData.isEmpty) {
throw Exception("No department found with ID $id");
}
return listData[0];
return listData[0];
} catch (e) {
throw Exception('Error parsing response: $e');
}
@ -858,5 +887,68 @@ class ApiService {
}
}
Future<bool> showCancelConfirmationDialog(
BuildContext context, Color? layoutColor) async {
return await showDialog<bool>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: Colors.white,
title: Text(
'Cancel Confirmation',
style: GoogleFonts.poppins(
fontSize: 18, fontWeight: FontWeight.w500),
),
content: Text(
'Do you want to cancel?',
style: GoogleFonts.poppins(
fontSize: 14.5, fontWeight: FontWeight.w500),
),
actions: [
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: layoutColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: layoutColor ?? Colors.grey, width: 2),
),
padding:
EdgeInsets.symmetric(horizontal: 20, vertical: 12),
),
onPressed: () {
Navigator.of(context).pop(false);
},
child: Text(
"Cancel",
style: GoogleFonts.poppins(fontSize: 12),
)),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: layoutColor, // Keep original color
foregroundColor: Colors.white, // Keep original color
disabledBackgroundColor:
layoutColor, // Ensure color remains when disabled
disabledForegroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
side: BorderSide(
color: layoutColor ?? Colors.grey, width: 1),
),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
),
onPressed: () => Navigator.of(context)
.pop(true), // Disable when in view mode
child: Text(
"OK",
style: GoogleFonts.poppins(fontSize: 12),
),
),
],
);
},
) ??
false; // Default to false if dismissed
}
}

View File

@ -61,8 +61,7 @@ class PlanPopupMenu extends StatelessWidget {
},
),
IconButton(
icon: Image.asset('assets/images/IconsImg/delete.png',
width: 20, height: 15),
icon: Icon(Icons.cancel_rounded, size: 18),
onPressed: () {
Navigator.pop(context);
deletePlan(plan.planId);