org settings
This commit is contained in:
parent
aa284d9563
commit
7c9ec2310b
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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}");
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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";
|
||||
}
|
||||
|
||||
@ -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";
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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";
|
||||
}
|
||||
|
||||
@ -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";
|
||||
}
|
||||
|
||||
@ -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";
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
|
||||
@ -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');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -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"),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -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");
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -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(),
|
||||
|
||||
184
lib/routes/organizationSetting.dart
Normal file
184
lib/routes/organizationSetting.dart
Normal 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
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user