plan iternary ui changes

This commit is contained in:
venbaittech 2025-04-25 13:04:25 +05:30
parent 36d3b365be
commit 5e4a093456
9 changed files with 177 additions and 55 deletions

View File

@ -157,6 +157,42 @@ class _ApprovalListState extends State<ApprovalList> {
} }
} }
Future<void> postPlanData(planData, planId) async {
final String apiUrldata = '$apiUrl/api/plans/createOrEditPlan';
final token = await getToken(); // Fetch token
if (token == null) {
throw Exception('Token not found. Please log in.');
}
planData['is_active'] = "0";
print("POSTPlanTesting------- $planData"); // Add plan_id for update
try {
final response = await http.post(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
body: jsonEncode(planData), // Convert map to JSON
);
if (response.statusCode == 200) {
print("Plan Deleted successfully!");
print("Response: ${response.body}");
initializeData();
} else {
print("Failed to submit plan. Status: ${response.statusCode}");
print("Error: ${response.body}");
}
} catch (e) {
print(" Error submitting plan: $e");
}
}
// Future<Map<String, dynamic>> getViewPlan(String planId) async { // Future<Map<String, dynamic>> getViewPlan(String planId) async {
// final String apiUrldata = '$apiUrl/api/plans/find/$planId'; // final String apiUrldata = '$apiUrl/api/plans/find/$planId';
// print("API URL: $apiUrldata"); // print("API URL: $apiUrldata");
@ -200,6 +236,17 @@ class _ApprovalListState extends State<ApprovalList> {
// } // }
// } // }
void deletePlan(String planId) async {
try {
Map<String, dynamic> planData = await getViewPlan(planId);
print("ViewAAA - $planData");
postPlanData(planData, planId);
} catch (e) {
print("Error fetching plan: $e");
}
}
Future<Map<String, dynamic>> getViewPlan(String planId) async { Future<Map<String, dynamic>> getViewPlan(String planId) async {
final String apiUrldata = '$apiUrl/api/plans/find/$planId'; final String apiUrldata = '$apiUrl/api/plans/find/$planId';
print("API URL: $apiUrldata"); print("API URL: $apiUrldata");
@ -583,7 +630,7 @@ class _ApprovalListState extends State<ApprovalList> {
width: 5, width: 5,
), ),
GestureDetector( GestureDetector(
onTap: () => (), onTap: () => deletePlan(plan.planId),
child: Image.asset( child: Image.asset(
'assets/images/IconsImg/delete.png', 'assets/images/IconsImg/delete.png',
width: 20, width: 20,

View File

@ -148,11 +148,18 @@ class FlightListWidget extends StatelessWidget {
borderRadius: BorderRadius.circular(12), borderRadius: BorderRadius.circular(12),
// color: Colors.orange.shade50, // color: Colors.orange.shade50,
color: Colors.white, color: Colors.white,
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: Colors.black12, color: Colors.black12,
blurRadius: 3, blurRadius: 2,
offset: Offset(0, 1), offset: Offset(0, 2), // down
),
// Top shadow
BoxShadow(
color: Colors.black12,
blurRadius: 0.5,
offset: Offset(0, -1), // up
), ),
], ],
border: Border( border: Border(

View File

@ -33,7 +33,7 @@ class MiscellaneousListWidget extends StatelessWidget {
children: [ children: [
Text( Text(
"Miscellaneous List", "Miscellaneous List",
style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
), ),
MouseRegion( MouseRegion(
cursor: isViewMode cursor: isViewMode

View File

@ -36,8 +36,8 @@ class VisaListWidget extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
"Visa Booking List", "Visa List",
style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
), ),
MouseRegion( MouseRegion(
cursor: isViewMode cursor: isViewMode

View File

@ -498,12 +498,12 @@ class _OrgSetUpState extends State<OrgSetUp> {
), ),
) )
: selectedOrg?['logo'] != null : selectedOrg?['logo'] != null
? ClipOval( ? ClipRect(
child: Image.network( child: Image.network(
selectedOrg!['logo'], selectedOrg!['logo'],
width: 50, width: 100,
height: 50, height: 30,
fit: BoxFit.cover, fit: BoxFit.contain,
errorBuilder: errorBuilder:
(context, error, stackTrace) { (context, error, stackTrace) {
return const CircleAvatar( return const CircleAvatar(

View File

@ -924,6 +924,15 @@ class CreateNewPlansState extends State<CreateNewPlan> {
} }
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool hasApprovals = planStatusList.any(
(item) => item.entries.any(
(entry) =>
entry.key.contains('status') &&
entry.value != null &&
entry.value.toString().isNotEmpty,
),
);
return ResponsiveBuilder(builder: (context, sizingInfo) { return ResponsiveBuilder(builder: (context, sizingInfo) {
bool isMobile = sizingInfo.isMobile; bool isMobile = sizingInfo.isMobile;
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop; bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
@ -983,6 +992,17 @@ class CreateNewPlansState extends State<CreateNewPlan> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (!hasApprovals)
Center(
child: Text(
"--- No Approvals ---",
style: TextStyle(
fontFamily: "Archivo",
fontSize: 11,
fontWeight: FontWeight.w500,
color: Colors.black87,
),
)),
for (int i = 0; i < planStatusList.length; i++) ...[ for (int i = 0; i < planStatusList.length; i++) ...[
if (planStatusList[i].entries.any((entry) => if (planStatusList[i].entries.any((entry) =>
entry.key.contains('status') && entry.key.contains('status') &&
@ -1563,6 +1583,18 @@ class CreateNewPlansState extends State<CreateNewPlan> {
borderRadius: BorderRadius.circular(25), borderRadius: BorderRadius.circular(25),
isFocused: _selectedOption == option["value"], isFocused: _selectedOption == option["value"],
isDesktop: isDesktop, isDesktop: isDesktop,
child: GestureDetector(
onTap: widget.isViewMode
? null
: () {
setState(() {
_selectedOption = option["value"]!;
if (option["value"] == 'Option 2' ||
option["value"] == 'Option 3') {
_showInputDialog(option["title"]!);
}
});
},
child: Row( child: Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -1579,19 +1611,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
: null, : null,
), ),
), ),
GestureDetector( Container(
onTap: widget.isViewMode
? null
: () {
setState(() {
_selectedOption = option["value"]!;
if (option["value"] == 'Option 2' ||
option["value"] == 'Option 3') {
_showInputDialog(option["title"]!);
}
});
},
child: Container(
width: 15, width: 15,
height: 15, height: 15,
decoration: BoxDecoration( decoration: BoxDecoration(
@ -1611,10 +1631,10 @@ class CreateNewPlansState extends State<CreateNewPlan> {
? Icon(Icons.rectangle, size: 8, color: Colors.white) ? Icon(Icons.rectangle, size: 8, color: Colors.white)
: null, // Add checkmark if selected : null, // Add checkmark if selected
), ),
)
], ],
), ),
), ),
),
); );
}).toList(); }).toList();
} }
@ -2238,7 +2258,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
}); });
}, },
child: Icon( child: Icon(
Icons.approval, Icons.approval_outlined,
size: 18, size: 18,
color: isStatusExpanded ? Colors.green : Colors.grey, color: isStatusExpanded ? Colors.green : Colors.grey,
), ),

View File

@ -812,16 +812,17 @@ class _DynamicItineraryState extends State<DynamicItinerary> {
SizedBox(width: 2), SizedBox(width: 2),
// if (selectedListOption == title && widget.isViewMode == false) // if (selectedListOption == title && widget.isViewMode == false)
if (hasData) if (hasData)
Container( Icon(Icons.circle, size: 8, color: Colors.green
height: 10,
width: 10,
// decoration: BoxDecoration(
// shape: BoxShape.circle,
// border: Border.all(color: Colors.green, width: 1.5),
// ),
child: Icon(Icons.circle, size: 8, color: Colors.green
// color: Colors.grey, // color: Colors.grey,
)), )
// Container(
// height: 10,
// width: 10,
// // decoration: BoxDecoration(
// // shape: BoxShape.circle,
// // border: Border.all(color: Colors.green, width: 1.5),
// // ),
// child:),
]), ]),
); );
} }
@ -833,7 +834,7 @@ class _DynamicItineraryState extends State<DynamicItinerary> {
case 'train': case 'train':
return Icons.train_outlined; return Icons.train_outlined;
case 'bus': case 'bus':
return Icons.directions_bus_filled_outlined; return Icons.directions_bus_rounded;
case 'taxi': case 'taxi':
return Icons.local_taxi_outlined; return Icons.local_taxi_outlined;
case 'accomodation': case 'accomodation':

View File

@ -139,6 +139,42 @@ class _ListPlansState extends State<ListPlans> {
} }
} }
Future<void> postPlanData(planData, planId) async {
final String apiUrldata = '$apiUrl/api/plans/createOrEditPlan';
final token = await getToken(); // Fetch token
if (token == null) {
throw Exception('Token not found. Please log in.');
}
planData['is_active'] = "0";
print("POSTPlanTesting------- $planData"); // Add plan_id for update
try {
final response = await http.post(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
body: jsonEncode(planData), // Convert map to JSON
);
if (response.statusCode == 200) {
print("Plan Deleted successfully!");
print("Response: ${response.body}");
initializeData();
} else {
print("Failed to submit plan. Status: ${response.statusCode}");
print("Error: ${response.body}");
}
} catch (e) {
print(" Error submitting plan: $e");
}
}
Future<Map<String, dynamic>> getViewPlan(String planId) async { Future<Map<String, dynamic>> getViewPlan(String planId) async {
final String apiUrldata = '$apiUrl/api/plans/find/$planId'; final String apiUrldata = '$apiUrl/api/plans/find/$planId';
print("API URL: $apiUrldata"); print("API URL: $apiUrldata");
@ -177,6 +213,17 @@ class _ListPlansState extends State<ListPlans> {
} }
} }
void deletePlan(String planId) async {
try {
Map<String, dynamic> planData = await getViewPlan(planId);
print("ViewAAA - $planData");
postPlanData(planData, planId);
} catch (e) {
print("Error fetching plan: $e");
}
}
Widget build(BuildContext context) { Widget build(BuildContext context) {
return ResponsiveBuilder(builder: (context, sizingInfo) { return ResponsiveBuilder(builder: (context, sizingInfo) {
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop; bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
@ -582,7 +629,7 @@ class _ListPlansState extends State<ListPlans> {
width: 5, width: 5,
), ),
GestureDetector( GestureDetector(
onTap: () => (), onTap: () => deletePlan(plan.planId),
child: Image.asset( child: Image.asset(
'assets/images/IconsImg/delete.png', 'assets/images/IconsImg/delete.png',
width: 20, width: 20,

View File

@ -142,9 +142,9 @@ class _CustomDrawerState extends State<CustomDrawer> {
? ClipRect( ? ClipRect(
child: Image.network( child: Image.network(
selectedOrg!['logo'], selectedOrg!['logo'],
width: 150, width: 100,
height: 50, height: 50,
fit: BoxFit.fitWidth, fit: BoxFit.contain,
errorBuilder: (context, error, stackTrace) { errorBuilder: (context, error, stackTrace) {
return const CircleAvatar( return const CircleAvatar(
radius: 20, radius: 20,