import 'package:easy_stepper/easy_stepper.dart'; import 'package:flutter/material.dart'; import 'package:frontend/Screens/itnerary_list/accomodation_list.dart'; import 'package:frontend/Screens/itnerary_list/bus_list.dart'; import 'package:frontend/Screens/itnerary_list/flight_list.dart'; import 'package:frontend/Screens/itnerary_list/taxi_list.dart'; import 'package:frontend/Screens/itnerary_list/train_list.dart'; import 'package:responsive_builder/responsive_builder.dart'; import '../itnerary/accomodations.dart'; import '../itnerary/bus.dart'; import '../itnerary/flights.dart'; import '../itnerary/forex.dart'; import '../itnerary/insurance.dart'; import '../itnerary/miscellaneous.dart'; import '../itnerary/taxi.dart'; import '../itnerary/train.dart'; import '../itnerary/visa.dart'; import '../itnerary_list/forex_list.dart'; import '../itnerary_list/insurance_list.dart'; import '../itnerary_list/miscellaneous_list.dart'; import '../itnerary_list/visa_list.dart'; class DynamicItinerary extends StatefulWidget { final Map? apiData; final List? apiCountryData; final String? loginUser; final Function(String, List>) onItineraryUpdate; // Updated Signature final Map selectedPlanData; final bool isViewMode ; const DynamicItinerary({super.key, required this.apiData, required this.onItineraryUpdate, required this.apiCountryData, required this.loginUser,required this.selectedPlanData, required this.isViewMode}); @override _DynamicItineraryState createState() => _DynamicItineraryState(); } class _DynamicItineraryState extends State { String selectedOption = ""; String selectedListOption = ""; bool isSelected = false; Map? selectedItem; int? selectedIndex; // List> miscellaneousList = []; Map>> itineraryData = { "Train": [], "Bus": [], "Taxi": [], "Miscellaneous": [], "Flight": [], "Accomodation": [], "Insurance": [], "Visa": [], "Forex": [], }; // Store form values for each tab final Map> formData = { "Flight": {}, // Stores data for the Flight tab "Train": {}, // Stores data for the Train tab "Taxi": {}, // Stores data for the Car tab "Bus": {}, // Stores data for the Bus tab "Insurance": {}, // Stores data for the Bus tab "Accomodation": {},// Stores data for the Accomodation tab "Miscellaneous": {}, "Forex": {}, "Visa": {}, }; @override void initState() { super.initState(); handleSelectedPlan(); } void handleSelectedPlan(){ // Check if selectedPlanData has itinerary data if (hasAnyItineraryData()) { print("selectedPlanData HAS DATA"); setState(() { itineraryData = { "Train": List>.from(widget.selectedPlanData['train'] ?? []), "Bus": List>.from(widget.selectedPlanData['bus'] ?? []), "Taxi": List>.from(widget.selectedPlanData['taxi'] ?? []), "Miscellaneous": List>.from(widget.selectedPlanData['miscellaneous'] ?? []), "Flight": List>.from(widget.selectedPlanData['flight'] ?? []), "Accomodation": List>.from(widget.selectedPlanData['accomodation'] ?? []), "Insurance": List>.from(widget.selectedPlanData['insurance'] ?? []), "Visa": List>.from(widget.selectedPlanData['visa'] ?? []), "Forex": List>.from(widget.selectedPlanData['forex'] ?? []), }; }); } else { print("No itinerary data available"); } } bool hasAnyItineraryData() { List keys = [ "train", "bus", "taxi", "miscellaneous", "flight", "accomodation", "insurance", "visa", "forex" ]; for (String key in keys) { if (widget.selectedPlanData.containsKey(key) && widget.selectedPlanData[key] is List && (widget.selectedPlanData[key] as List).isNotEmpty) { return true; // At least one list has data } } return false; // No itinerary data available } void handleClose(bool value) { setState(() { selectedOption = ""; isSelected = value; selectedIndex = null; selectedItem = null; }); } void handleEdit(bool value,selectedItem, title) { setState(() { selectedOption = title; isSelected = value; this.selectedItem = selectedItem; }); print(selectedItem); } Widget build(BuildContext context) { Widget selectedWidget; Widget selectedListWidget; // void updateFormData(String tab, String key, String value) { // setState(() { // formData[tab]![key] = value; // Update the stored data // }); // } void updateFormData(String tab, String key, String value) { setState(() { if (!formData.containsKey(tab)) { formData[tab] = {}; // Initialize if null } formData[tab]![key] = value; // Update the stored data }); } void handleItineraryUpdate(String type, Map newData) { setState(() { if (!itineraryData.containsKey(type)) { itineraryData[type] = []; // Initialize if null } List> itemList = itineraryData[type]!; print("newData - $newData"); // int? existingId = newData["id"]; // String? existingId = newData["id"]; String? idKey = "${type.toLowerCase()}_id"; String? existingId = newData[idKey]; print("Looking for ID using key: $idKey, Found ID: $existingId"); int? existingIndex = newData["indx"]; print("existingIndex - $existingIndex, existingId - $existingId"); // CASE 2: Update using id if available if (existingId != null && existingId != 0) { // int itemId = itemList.indexWhere((item) => item["id"] == existingId); int itemId = itemList.indexWhere((item) => item[idKey]?.toString() == existingId.toString()); if (itemId != -1) { print(" Updating existing item with id: $existingId"); newData["is_active"] = "1"; itemList[itemId] = newData; return; } } // CASE 1: Update if indx exists in list if (existingIndex != null && existingIndex != 0) { int itemIndex = itemList.indexWhere((item) => item["indx"] == existingIndex); if (itemIndex != -1) { print("Updating existing item with indx: $existingIndex"); newData["is_active"] = "1"; itemList[itemIndex] = newData; // Update the item return; } } // CASE 3: New Entry (Assign new indx) print(" Creating new entry"); newData["indx"] = itemList.length + 1; // Assign a new indx newData["is_active"] = "1"; itemList.add(newData); print(" Updated $type List: ${itineraryData[type]}"); }); print( " onItineraryUpdate - $type - ${itineraryData[type]!} "); widget.onItineraryUpdate(type, itineraryData[type]!); // Notify parent } void handleItinerarydelete(String type, Map data){ setState(() { // if(!itineraryData.containsKey(type)){ // return; // } if (!itineraryData.containsKey(type)) { itineraryData[type] = []; // Initialize if null } List> itemList = itineraryData[type]!; String? idKey = "${type.toLowerCase()}_id"; String? existingId = data[idKey]; // int? existingId = data["id"]; // String? existingId = data["id"]; int? existingIndex = data["indx"]; print("🗑️ Deleting item -> ID: $existingId, Index: $existingIndex"); // Delete by ID if(existingId != null && existingId != 0){ // itemList.removeWhere((item) => item[idKey]?.toString() == existingId.toString()); for (var item in itemList) { if (item[idKey]?.toString() == existingId.toString()) { item["is_active"] = 0; // Soft delete print("Updated is_active to 0 for ID: $existingId"); } } itineraryData[type] = List.from(itemList); print("Deleted by ID: $existingId"); } //Delete by Index else if(existingIndex != null && existingId !=0){ itemList.removeWhere((item) => item["indx"] == existingIndex); print("Deleted by ID: $existingIndex"); } else{ print("No Valid Deletion"); } itineraryData[type]= List.from(itemList); }); print( " onItineraryUpdate - $type - ${itineraryData[type]!} "); widget.onItineraryUpdate(type, itineraryData[type]!); // Notify parent } // void handleItineraryUpdate(String type, Map newData) { // setState(() { // if (!itineraryData.containsKey(type)) { // itineraryData[type] = []; // Initialize if null // } // // // Assign an index based on the current list length // int newIndex = itineraryData[type]!.length + 1; // newData["indx"] = newIndex; // Add an ID field // // itineraryData[type]!.add(newData); // Append new object // }); // // widget.onItineraryUpdate(type, itineraryData[type]!); // Notify parent // print("Updated $type List: ${itineraryData[type]}"); // } switch (selectedListOption) { case "Train": selectedListWidget = TrainListWidget( trainList : itineraryData["Train"]!, onOpen: handleEdit, onDeleteTrain: (data)=> handleItinerarydelete("Train", data), ); break; case "Taxi": selectedListWidget = TaxiListWidget( taxiList : itineraryData["Taxi"]! , onOpen: handleEdit, onDeleteTaxi: (data)=> handleItinerarydelete("Taxi", data),); break; case "Bus": selectedListWidget = BusListWidget(busList : itineraryData["Bus"]!, onOpen: handleEdit, onDeleteBus: (data) => handleItinerarydelete("Bus", data),); break; case "Insurance": selectedListWidget = InsuranceListWidget(insuranceList : itineraryData["Insurance"]!, onOpen: handleEdit, apiData: widget.apiData, onDeleteInsurance:(data) => handleItinerarydelete("Insurance", data),); break; case "Visa": selectedListWidget = VisaListWidget(visaList : itineraryData["Visa"]!, apiData: widget.apiData, apiCountryData : widget.apiCountryData, onOpen: handleEdit, onDeleteMiscellaneous: (data) => handleItinerarydelete("Visa", data),); break; case "Forex": selectedListWidget = ForexListWidget(forexList: itineraryData["Forex"]!, apiCountryData : widget.apiCountryData, onOpen: handleEdit, onDeleteForex: (data) => handleItinerarydelete("Forex", data),); break; case "Accomodation": selectedListWidget = AccomodationListWidget(accommodationList: itineraryData["Accomodation"]!, onOpen: handleEdit, onDeleteAccommodation:(data) => handleItinerarydelete("Accomodation", data)); break; case "Miscellaneous": selectedListWidget = MiscellaneousListWidget(miscellaneousList: itineraryData["Miscellaneous"]!, onOpen: handleEdit,apiData: widget.apiData, onDeleteMiscellaneous: (data) => handleItinerarydelete("Miscellaneous", data), ); break; case "Flight": default: selectedListWidget = FlightListWidget(flightList : itineraryData["Flight"]!, onOpen: handleEdit, onDeleteFlight: (data) => handleItinerarydelete("Flight", data) ); break; } switch (selectedOption) { case "Train": selectedWidget = TrainScreen(onClose: handleClose, apiData: widget.apiData, loginUser : widget.loginUser, onSavetrain :(data) => handleItineraryUpdate("Train", data), selectedItem: selectedItem); break; case "Taxi": selectedWidget = TaxiScreen(onClose: handleClose,apiData: widget.apiData, loginUser : widget.loginUser, onSavetaxi: (data)=> handleItineraryUpdate("Taxi", data), selectedItem: selectedItem); break; case "Bus": selectedWidget = BusScreen(onClose: handleClose, apiData: widget.apiData, loginUser : widget.loginUser, onSaveBus: (data)=> handleItineraryUpdate("Bus", data), selectedItem: selectedItem); break; case "Insurance": selectedWidget = InsuranceScreen(onClose: handleClose, apiData: widget.apiData, loginUser : widget.loginUser, onSaveInsurance:(data) => handleItineraryUpdate("Insurance", data), selectedItem: selectedItem); break; case "Visa": selectedWidget = VisaScreen(onClose: handleClose,apiData: widget.apiData, apiCountryData : widget.apiCountryData, loginUser : widget.loginUser, onSaveVisa: (data) => handleItineraryUpdate("Visa", data), selectedItem: selectedItem,); break; case "Miscellaneous": selectedWidget = MiscellaneousScreen(onClose: handleClose, apiData: widget.apiData, loginUser : widget.loginUser, onSaveMiscellaneous: (data) => handleItineraryUpdate("Miscellaneous", data), selectedItem: selectedItem, selectedIndex: selectedIndex, ); break; case "Accomodation": selectedWidget = AccomodationScreen( onClose: handleClose, loginUser : widget.loginUser, onSaveAccomadation: (data)=>handleItineraryUpdate("Accomodation", data), selectedItem: selectedItem, ); break; case "Forex": selectedWidget = ForexScreen( onClose: handleClose,apiData: widget.apiData, loginUser : widget.loginUser, apiCountryData : widget.apiCountryData, onSaveForex: (data)=>handleItineraryUpdate("Forex", data), selectedItem: selectedItem); break; case "Flight": default: selectedWidget = FlightScreen(onClose: handleClose,loginUser : widget.loginUser, onSaveFlight: (data)=>handleItineraryUpdate("Flight", data), apiData: widget.apiData, selectedItem: selectedItem ); break; } return ResponsiveBuilder(builder: (context, sizingInfo) { bool isMobile = sizingInfo.isMobile; bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop; return Column( // mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text("Itinerary", style: TextStyle( fontSize: 18, ),), ], ), SizedBox(height: 8), Container( decoration: BoxDecoration( border: Border.all(color: Color(0xFFF4F4FB)), borderRadius: BorderRadius.circular(1), color: Color(0xFFF4F4FB), ), padding: EdgeInsets.all(5), child: isMobile ? Expanded( child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: _buildOptions(), ), ), ) : Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, // mainAxisSize: MainAxisSize.min, children: _buildOptions(), ), ), Column( // mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ SizedBox(height: 2), isSelected ? selectedWidget : selectedListWidget, // TrainScreen() ], ), ], ); }); } List _buildOptions() { return [ _buildOption("Flight", itineraryData["Flight"]?.isNotEmpty ?? false), SizedBox(width: 20), _buildOption("Taxi", itineraryData["Taxi"]?.isNotEmpty ?? false), SizedBox(width: 20), _buildOption("Train", itineraryData["Train"]?.isNotEmpty ?? false), SizedBox(width: 20), _buildOption("Bus", itineraryData["Bus"]?.isNotEmpty ?? false), SizedBox(width: 20), _buildOption("Accomodation", itineraryData["Accomodation"]?.isNotEmpty ?? false), SizedBox(width: 20), _buildOption("Forex", itineraryData["Forex"]?.isNotEmpty ?? false), SizedBox(width: 20), _buildOption("Insurance", itineraryData["Insurance"]?.isNotEmpty ?? false), SizedBox(width: 20), _buildOption("Visa", itineraryData["Visa"]?.isNotEmpty ?? false), SizedBox(width: 20), _buildOption("Miscellaneous", itineraryData["Miscellaneous"]?.isNotEmpty ?? false), ]; } // List _buildOptions() { // return [ // _buildOption("Flight", itineraryData["Flight"]?.isNotEmpty ?? false), // _buildOption("Flight"), // SizedBox(width: 20), // _buildOption("Taxi"), // SizedBox(width: 20), // _buildOption("Train"), // SizedBox(width: 20), // _buildOption("Bus"), // SizedBox(width: 20), // _buildOption("Accomodation"), // SizedBox(width: 20), // _buildOption("Forex"), // SizedBox(width: 20), // _buildOption("Insurance"), // SizedBox(width: 20), // _buildOption("Visa"), // SizedBox(width: 20), // _buildOption("Miscellaneous"), // ]; // } Widget _buildOption(String title, bool hasData) { return GestureDetector( onTap: () { setState(() { selectedListOption = title; isSelected = false; }); }, child: Row( children: [ if(hasData) Icon(Icons.circle_notifications,color: Colors.green, size: 10,), SizedBox(width: 5), Text(title, style: TextStyle( fontSize: 13, color: selectedListOption == title ? Colors.blueAccent : Color(0xFF575A74), fontWeight: selectedListOption == title ? FontWeight.bold : FontWeight.normal,)), SizedBox(width: 5), SizedBox(width: 5), if (selectedListOption == title && widget.isViewMode == false) GestureDetector( onTap: () { setState(() { selectedOption = title; isSelected = true; selectedItem = null; }); }, child: Icon( Icons.add_circle, color: Colors.blueAccent, size: 18, ), ), ] ), ); } }