import 'dart:async'; import 'dart:convert'; import 'dart:html' as html; import 'dart:typed_data'; // Import for Uint8List import 'package:bcrypt/bcrypt.dart'; import 'package:dropdown_search/dropdown_search.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:frontend/Screens/userManagement/create_user/personal_details.dart'; import 'package:frontend/Screens/userManagement/create_user/traveller_details.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:http_parser/http_parser.dart' as http_parser; import 'package:intl/intl.dart'; import 'package:responsive_builder/responsive_builder.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http_parser/http_parser.dart'; import '../../../config/apiUrl.dart'; import '../../../routes/custom_appBar.dart'; import '../../../routes/custom_drawer.dart'; import '../../../services/apiService.dart'; import '../../../widgets/custom_text_field.dart'; import '../../../widgets/custom_text_forex.dart'; import '../../../widgets/custom_user_form.dart'; import 'office_details.dart'; import 'package:universal_html/html.dart' as html; class CreateUserFormDetials extends StatefulWidget { @override _CreateUserFormDetialsState createState() => _CreateUserFormDetialsState(); } class _CreateUserFormDetialsState extends State { final ApiService apiService = ApiService(); final GlobalKey personalDetailsKey = GlobalKey(); final GlobalKey travellerDetailsKey = GlobalKey(); // late List?> travelDetailsData; Map? travelDetailsData; Map? travelDetailsDataFromAPI; late TabController _tabController; String? userId; String? orgId; String? userIdApi; String? token; late bool isapiselectedUser = false; // Map to store controllers dynamically final Map controllers = {}; bool isViewMode = false; bool isEditProfile = false; // late final List? apiCountryData ; late List? apiCountryData; late List? apiCostData; late List? apiRoleData; late List? apiUserData; Map? apiselectedUser; List> selectedServiceIds = []; late List userList; late Future> futureUsers; List? resolvedUserData; late List userIdsApi; late Map userMap; Map errorMessages = {}; String? selectedTab; String? selectedCountry; String? selectedGender; // String? selectedGender = personalDetailsKey.currentState?.selectedGender; String? selectedUserType; String? selectedRole; String? selectedLevel; String? selectedDepartment; String? selectedFirstApprover; String? selectedSecondApprover; String? selectedThirdApprover; String? selectedSubstituteApprover; String? selectedFileNames; Uint8List? passportDocumentBytes; String? passportFileUrlFromApi; String? base64PDF; html.File? passportFile; List dataHeader = [ "Fname", "Lname", "email", "password", "dob", "gender", "mobileNumber", "alternateMobile", "address", "postalCode", "country", // "passportNumber", // "placeOfIssue", // "passportDoc", "userType", "roleId", "deptId", "levelId", "firstApproval", "secondApproval", "thirdApproval", "employeeCode", "delegationStartDate", "delegationEndDate", // "dateOfIssue", // "dateOfExpiry", "changePassword", ]; Color? layoutColor; Color? bodyColor; bool setSelectesUserType = false; Map get userDetials { Map data = { "first_name": controllers["Fname"]?.text, "last_name": controllers["Lname"]?.text, "email": controllers["email"]?.text, "password": controllers["password"]?.text, "mobile_no": controllers["mobileNumber"]?.text, "alternate_mobile_no": controllers["alternateMobile"]?.text, "date_of_birth": controllers["dob"]?.text, "address": controllers["address"]?.text, "gender": selectedGender, // "gender": personalDetailsKey.currentState?.selectedGender, "agent_supported_service_ids": selectedServiceIds, "postal_code": controllers["postalCode"]?.text, "country_code": selectedCountry, "employee_code": controllers["employeeCode"]?.text, "delegation_start_date": controllers["delegationStartDate"]?.text, "delegation_end_date": controllers["delegationEndDate"]?.text, "user_type": selectedUserType, "role_id": selectedRole, "department_id": selectedDepartment, "group_id": selectedLevel, "first_approver": selectedFirstApprover, "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, // "date_of_issue": controllers["dateOfIssue"]?.text, // "date_of_expiry": controllers["dateOfExpiry"]?.text, "created_by": userId, "is_active": "1", "org_id": orgId, "travel_details": travelDetailsData ?? {}, // "passport_fileData": passportFile, }; return data; } void handleUserTypeChange(bool isTravelAgent) { print("handleUserTypeChange- $isTravelAgent"); setState(() { setSelectesUserType = isTravelAgent; }); } Future updateData() async { // Ensure apiselectedUser is not null before printing if (apiselectedUser != null) { print("API Selected User Has Data - $widget.apiselectedUser"); setState(() { // ✅ Wrap in setState to update the UI if (apiselectedUser != null && apiselectedUser!.isNotEmpty) { isapiselectedUser = true; print("API Selected User Has Data - $apiselectedUser"); } userIdApi = apiselectedUser?["user_id"] ?? ""; controllers["Fname"]?.text = apiselectedUser?["first_name"] ?? ""; controllers["Lname"]?.text = apiselectedUser?["last_name"] ?? ""; controllers["email"]?.text = apiselectedUser?["email"] ?? ""; controllers["password"]?.text = ""; // controllers["password"]?.text = apiselectedUser?["password"] ?? ""; controllers["mobileNumber"]?.text = apiselectedUser?["mobile_no"] ?? ""; controllers["alternateMobile"]?.text = apiselectedUser?["alternate_mobile_no"] ?? ""; controllers["dob"]?.text = apiselectedUser?["date_of_birth"] ?? ""; controllers["address"]?.text = apiselectedUser?["address"] ?? ""; controllers["postalCode"]?.text = apiselectedUser?["postal_code"] ?? ""; controllers["employeeCode"]?.text = apiselectedUser?["employee_code"] ?? ""; controllers["delegationStartDate"]?.text = apiselectedUser?["delegation_start_date"] ?? ""; controllers["delegationEndDate"]?.text = apiselectedUser?["delegation_end_date"] ?? ""; controllers["passportNumber"]?.text = apiselectedUser?["passport_number"] ?? ""; controllers["placeOfIssue"]?.text = apiselectedUser?["place_of_issue"] ?? ""; if (apiselectedUser?["date_of_issue"] != null) { controllers["dateOfIssue"]?.text = apiselectedUser?["date_of_issue"] ?? ""; } if (apiselectedUser?["date_of_expiry"] != null) { controllers["dateOfExpiry"]?.text = apiselectedUser?["date_of_expiry"] ?? ""; } if (apiselectedUser?["country_code"] != null) { selectedCountry = apiselectedUser?["country_code"]?.toString() ?? ""; } if (apiselectedUser?["gender"] != null) { selectedGender = apiselectedUser?["gender"]?.toString().trim() ?? ""; } if (apiselectedUser?["user_type"] != null) { selectedUserType = apiselectedUser?["user_type"]?.toString().trim() ?? ""; } if (apiselectedUser?["role_id"] != null) { selectedRole = apiselectedUser?["role_id"]?.toString().trim() ?? ""; } if (apiselectedUser?["group_id"] != null) { selectedLevel = apiselectedUser?["group_id"]?.toString().trim() ?? ""; } // selectedDepartment = // apiselectedUser?["department_id"]?.toString().trim() ?? ""; if (apiselectedUser?["department_id"] != null) { selectedDepartment = apiselectedUser!["department_id"].toString(); } // print( // "selectedDepartment - $selectedDepartment - ${apiselectedUser?["department_id"]} "); if (apiselectedUser?["level_id"] != null) { selectedLevel = apiselectedUser?["level_id"]?.toString().trim() ?? ""; } if (apiselectedUser?["first_approver"] != null) { selectedFirstApprover = apiselectedUser?["first_approver"]?.toString() ?? ""; } if (apiselectedUser?["second_approver"] != null) { selectedSecondApprover = apiselectedUser?["second_approver"]?.toString() ?? ""; } if (apiselectedUser?["third_approver"] != null) { selectedThirdApprover = apiselectedUser?["third_approver"]?.toString() ?? ""; } if (apiselectedUser?["delegated_to_user_id"] != null) { print( "UPDADele- ${apiselectedUser?["delegated_to_user_id"]?.toString()}", ); selectedSubstituteApprover = apiselectedUser?["delegated_to_user_id"]?.toString() ?? ""; print("UPDADele1- $selectedSubstituteApprover"); } try { final raw = apiselectedUser!["agent_supported_service_ids"]; // Fix the invalid JSON (dangerous if the format changes) final fixedJson = raw.replaceAllMapped( RegExp(r'(\w+):'), // matches `service_id:` (match) => '"${match.group(1)}":', ); List decodedList = jsonDecode(fixedJson); selectedServiceIds = decodedList.map>((item) { final map = Map.from(item); return {"service_id": map['service_id'].toString()}; }).toList(); } catch (e) { print("❌ Error decoding fixed agent_supported_service_ids: $e"); selectedServiceIds = []; } print("Updated selectedGender: $selectedGender"); // Debugging travelDetailsDataFromAPI = apiselectedUser?["travel_details"]; print("travelDetailsDataFromAPI00 - $travelDetailsDataFromAPI"); // if (travelDetails != null) { // WidgetsBinding.instance.addPostFrameCallback((_) { // // Safe to call updateTravel now // travellerDetailsKey.currentState?.updateTravel(); // }); // } // Optionally load other travel-related fields like meal/seat preferences, etc. }); } else { print("API Selected User Has Data - No data available yet"); } } @override void initState() { super.initState(); prepareForNewEntry(); selectedTab = "personal"; // WidgetsFlutterBinding.ensureInitialized(); // Step 1: Set 'reloaded' flag before page unload // html.window.onBeforeUnload.listen((event) { // html.window.localStorage['reloaded'] = 'true'; // }); apiCountryData = null; apiUserData = null; // apiselectedUser = null; apiCostData = null; apiRoleData = null; // Initialize controllers for each field WidgetsBinding.instance.addPostFrameCallback((_) async { // final wasReloaded = html.window.localStorage['reloaded'] == 'true'; // // if (wasReloaded) { // html.window.localStorage.remove('reloaded'); // Clear it // context.go('/listUser'); // Navigate using go_router // } final extraData = GoRouterState.of(context).extra as Map?; if (extraData != null) { print("extraData: ${extraData['selectedUser']}"); setState(() { // apiCountryData = extraData['apiCountryData']; // apiUserData = extraData['apiUserData']; // // userList = apiUserData ?? []; // userMap = { // for (var user in userList) // user['user_id'].toString(): "${user['first_name']} ${user['last_name']}" // }; // userIdsApi = userMap.keys.toList(); // Handle selectedUser as a Map (not a List) apiselectedUser = extraData['selectedUser'] as Map?; // Cast it as a Map isViewMode = extraData['isViewMode'] ?? false; isEditProfile = extraData['isEditProfile'] ?? false; }); print("selectedUser: $apiselectedUser"); // Add another post-frame callback to check after setState // await Future.delayed(Duration( // milliseconds: 100)); // Optional delay to ensure UI has updated updateData(); } initializeData(); fetchCountries(); fetchDepartment(); fetchUsers(); fetchRoles(); loadInitialData(); }); for (var field in dataHeader) { controllers[field] = TextEditingController(); } } Future fetchCountries() async { try { List countries = await apiService.fetchCountryList(); setState(() { apiCountryData = countries; }); } catch (e) { print('Error fetching country list: $e'); } } Future fetchDepartment() async { try { List department = await apiService.fetchCostCenter(); setState(() { apiCostData = department; }); } catch (e) { print('Error fetching department list: $e'); } } Future fetchUsers() async { try { List users = await apiService.fetchUsers(); setState(() { // apiUserData = users; apiUserData = users.where((user) => user["role_id"] == "4").toList(); print("APIUSerDATa - $apiUserData"); userList = apiUserData ?? []; userMap = { for (var user in userList) user['user_id'].toString(): "${user['first_name']} ${user['last_name']}", }; userIdsApi = userMap.keys.toList(); }); } catch (e) { print('Error fetching country list: $e'); } } Future fetchRoles() async { try { final response = await apiService.fetchMasterDropdown(); if (response is Map && response.containsKey("role")) { List roleList = response["role"]; // Extract the list setState(() { apiRoleData = roleList; }); print("APIROLEData - $apiRoleData"); } else { print("Error: 'role' key not found or response is not a Map."); } } catch (e) { print('Error fetching role list: $e'); } } void printFormData() { for (var field in dataHeader) { print("$field: ${controllers[field]?.text}"); } } void loadInitialData() async { String? layoutString = await getLayoutColor(); String? bodyStringColor = await getBodyColor(); setState(() { layoutColor = layoutString != null ? Color(int.parse(layoutString)) : Colors.redAccent; bodyColor = bodyStringColor != null ? Color(int.parse(bodyStringColor)) : Colors.white; }); } Future initializeData() async { token = await getToken(); userId = await getUserId(); if (token == null || userId == null) { print("Token or USerId missing"); print("Retrieved Token: $token"); print("Retrieved UserId: $userId"); return; } else { setState(() {}); } } Future getToken() async { final prefs = await SharedPreferences.getInstance(); return prefs.getString('auth_token'); } Future getUserId() async { final prefs = await SharedPreferences.getInstance(); final userData = prefs.getString('user_data'); if (userData != null) { final decodedData = jsonDecode(userData); // Return the user_id from the decoded data return decodedData['user_id']?.toString(); } return null; } @override void dispose() { // Dispose all controllers to prevent memory leaks for (var controller in controllers.values) { controller.dispose(); } super.dispose(); } void prepareForNewEntry() { for (var controller in controllers.values) { controller.clear(); } } void handleGoBack() async { print("hello, please Go Back"); printFormData(); } void handleNext() async { print("USR Detail Next"); printFormData(); // travelDetailsData = [travellerDetailsKey.currentState?.travel_Detials]; travelDetailsData = travellerDetailsKey.currentState?.travel_Detials; print("TRAVEL DETAILS FROM CHILD: $travelDetailsData"); Map data = userDetials; print("USERDETAILS : $data"); final tabs = { "personal": "Personal Details", "office": "Office Details", "travel": "Travel Details", }; final tabKeys = tabs.keys.toList(); // ["personal", "office", "travel"] final currentIndex = tabKeys.indexOf(selectedTab ?? "personal"); print("currentIndex - $currentIndex"); bool isValid = false; final currentTab = tabKeys[currentIndex]; if (currentTab == "personal") { isValid = isValidData(userDetials); } else if (currentTab == "office") { isValid = isValidDataTwo(userDetials); } else { isValid = true; // Travel tab might not need validation at this point } if (!isValid) { print("Validation Failed on $currentTab: $userDetials"); setState(() {}); // To trigger UI update showing errors return; } if (currentIndex < tabKeys.length - 1) { // Move to next tab setState(() { selectedTab = tabKeys[currentIndex + 1]; }); } else { // Final step — submit or show done print("All tabs completed!"); // Submit the full form here } // if (!isValidData(data)) // { // print("USERDETAILS : $userDetials"); // print("Validation Failed: Required fields are missing."); // setState(() {}); // return; // Stop execution if validation fails // } else // { // print("USERDETAILS : $userDetials"); // // if (currentIndex < tabKeys.length - 1) { // // Move to next tab // setState(() { // selectedTab = tabKeys[currentIndex + 1]; // }); // } else { // // Already at last tab (travel), maybe submit form or show done message // print("All tabs completed!"); // // You can trigger full form submit here // } // } } void handleSubmit() async { print("USR Detail Submit"); // printFormData(); travelDetailsData = travellerDetailsKey.currentState?.travel_Detials; print("TRAVEL DETAILS FROM CHILD"); // print("TRAVEL DETAILS FROM CHILD: $travelDetailsData"); passportFile = travellerDetailsKey.currentState?.passportFile; print("passportFile : $passportFile"); Map data = userDetials; print("USERDETAILS : $data"); // Map data = userDetials; if (!isValidData(data) && isValidDataTwo(data)) { print("USERDETAILS : $userDetials"); print("Validation Failed: Required fields are missing."); setState(() {}); return; // Stop execution if validation fails } else { print("USERDETAILS : $userDetials"); orgId = await getOrgId(); createUserData(userDetials); } } bool isValidData(Map data) { errorMessages.clear(); // Reset errors // Required fields that must not be empty List requiredFields = [ "first_name", "last_name", "email", "mobile_no", "role_id", // "employeeCode", ]; if (apiselectedUser == null) { requiredFields.add("password"); } // Check validation for each field for (String field in requiredFields) { if (data[field] == null || data[field].toString().trim().isEmpty) { errorMessages[field] = "Required"; } } // Mobile number validation for both mobile_no and alternate_mobile_no if (data["mobile_no"] != null && data["mobile_no"].toString().isNotEmpty) { if (!RegExp(r"^\d{10}$").hasMatch(data["mobile_no"].toString())) { errorMessages["mobile_no"] = "Enter 10 digits"; // Invalid mobile number format } } if (data["alternate_mobile_no"] != null && data["alternate_mobile_no"].toString().isNotEmpty) { if (!RegExp( r"^\d{10}$", ).hasMatch(data["alternate_mobile_no"].toString())) { errorMessages["alternate_mobile_no"] = "Enter 10 digits"; // Invalid mobile number format } } // Email validation if (data["email"] != null && data["email"].toString().isNotEmpty) { if (!RegExp( r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$", ).hasMatch(data["email"].toString())) { errorMessages["email"] = "Invalid email format"; // Invalid email format } } return errorMessages.isEmpty; // Valid if there are no errors } bool isValidDataTwo(Map data) { errorMessages.clear(); // Reset errors // Required fields that must not be empty List requiredFields = ["employee_code"]; // Check validation for each field for (String field in requiredFields) { if (data[field] == null || data[field].toString().trim().isEmpty) { errorMessages[field] = "Required"; } } return errorMessages.isEmpty; // Valid if there are no errors } void _clearError(String field) { if (mounted && errorMessages.containsKey(field)) { setState(() { errorMessages.remove(field); }); } } void pickPDFWeb() { html.FileUploadInputElement uploadInput = html.FileUploadInputElement(); uploadInput.accept = '.pdf'; uploadInput.click(); uploadInput.onChange.listen((e) { final file = uploadInput.files!.first; // Ensure the file is a PDF if (!file.type.contains("pdf")) { print("Error: Not a PDF file"); return; } // 🔹 File size check: Ensure it does not exceed 3MB int maxFileSize = 3 * 1024 * 1024; // 3MB in bytes if (file.size > maxFileSize) { print('Error: File size exceeds 3MB'); return; } setState(() { selectedFileNames = file.name; passportFile = file; passportFileUrlFromApi = null; }); print('PDF File selected: ${file.name}'); }); } Future createUserData(Map userData) async { final bool isUpdating = apiselectedUser != null && apiselectedUser!.isNotEmpty; final uri = Uri.parse( isUpdating ? '$apiUrl/api/users/update/${apiselectedUser?["user_id"]}' : '$apiUrl/api/users/create', ); if (token == null) { throw Exception('Token not found. Please log in.'); } // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $token'; // If updating, spoof the method Laravel-style if (isUpdating) { request.fields['_method'] = 'PUT'; request.fields['user_id'] = apiselectedUser!["user_id"].toString(); } // userData.forEach((key, value) { // // if (value == null) { // // // skip nulls // // return; // // } // // if (key == 'travel_details' && value is Map) { // // 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) { // ✅ 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 if (passportFile != null) { try { final reader = html.FileReader(); reader.readAsArrayBuffer(passportFile!); await reader.onLoad.first; final data = reader.result as Uint8List; final multipartFile = http.MultipartFile.fromBytes( 'passport_document', data, filename: passportFile!.name, ); request.files.add(multipartFile); print("📎 File attached: ${passportFile!.name}"); } catch (e) { print("❌ Failed to read file: $e"); } } else { print("⚠️ No passport file selected."); } print("🚀 Sending request with fields: ${request.fields}"); try { final streamedResponse = await request.send(); final response = await http.Response.fromStream(streamedResponse); print("Response status: ${response.statusCode}"); print("Response body: ${response.body}"); if (response.statusCode == 200 || response.statusCode == 201) { dispose(); print("✅ User submitted successfully!"); print("📨 Response: ${response.body}"); context.go('/listUser'); } else { print("❌ Submission failed. Status: ${response.statusCode}"); print("📨 Body: ${response.body}"); } } catch (e) { print("🔥 Error submitting user: $e"); } } void handleChangePassword(String enteredPassword) { var hashedPassword = apiselectedUser?["password"]; // Get stored bcrypt hash print("HAshPAssword - $hashedPassword "); print("enteredPassword - $enteredPassword "); if (hashedPassword != null && hashedPassword.isNotEmpty) { bool isMatch = BCrypt.checkpw( enteredPassword, hashedPassword, ); // Compare passwords setState(() { // ✅ Ensure UI updates if (isMatch) { errorMessages["password"] = "New password is not similar to old password"; print(" Password match!"); } else { print(" Password NOT match!"); errorMessages.remove( "password", ); // Clear error if password is different } }); } else { print("No stored password found."); } } @override Widget build(BuildContext context) { return ResponsiveBuilder( builder: (context, sizingInfo) { bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop; return Scaffold( backgroundColor: Color(0xFFf5f5f5), // appBar: isDesktop ? null : const CustomAppBar(title: 'Create User '), // 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: [Expanded(child: buildData(isDesktop, context))], ), ), ); }, ); } Widget buildData(bool isDesktop, context) { return Container( margin: isDesktop ? const EdgeInsets.only(top: 10.0, bottom: 10.0) : null, padding: const EdgeInsets.only(left: 10, right: 10, top: 8), decoration: BoxDecoration( color: isDesktop ? Colors.white : Color(0xFFFCFCFC), ), child: Column( children: [ Expanded( child: Container( height: isDesktop ? MediaQuery.of(context).size.height * 0.98 : MediaQuery.of(context).size.height, child: Padding( padding: EdgeInsets.all(0.0), child: _buildUserDetails(isDesktop), ), ), ), Container( color: Colors.white, child: Padding( padding: const EdgeInsets.all(8.0), child: isDesktop ? Row( mainAxisAlignment: MainAxisAlignment.end, children: (selectedTab == "travel" || selectedRole == "5" || setSelectesUserType == true) ? _buildSubmit(isDesktop, layoutColor!) : _buildNext( isDesktop, layoutColor!, ), // _buildGoBack(isDesktop, layoutColor!), ) : Row( mainAxisAlignment: MainAxisAlignment.end, children: (selectedTab == "travel" || selectedRole == "5" || setSelectesUserType == true) ? _buildSubmit(isDesktop, layoutColor!) : _buildNext(isDesktop, layoutColor!), ), ), ), ], ), ); } Widget _buildUserDetails(bool isDesktop) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Text( apiselectedUser != null ? "Profile" : "Create New User", style: GoogleFonts.poppins( fontSize: isDesktop ? 15 : 12, fontWeight: FontWeight.w600, color: Colors.black, ), ), // if (isEditProfile) // IconButton( // icon: Icon( // Icons.edit, // color: Color(0xFF114D8B), // size: 14, // ), // onPressed: () { // setState(() { // isViewMode = !isViewMode; // }); // }) ], ), SizedBox(height: 18), isDesktop ? buildTabsForUser() : SingleChildScrollView( scrollDirection: Axis.horizontal, child: buildTabsForUser(), ), Container( // color: Colors.yellow.shade50, height: MediaQuery.of(context).size.height * 0.64, child: Row( children: [ Expanded(child: buildTabContents(isDesktop, isViewMode)), ], ), ), ], ), ), ], ); } Widget buildTabContents(isDesktop, isViewMode) { switch (selectedTab) { case "personal": return PersonalDetails( personalDetailsKey: personalDetailsKey, isDesktop: isDesktop, // pass isDesktop as a named argument isViewMode: isViewMode, userIdApi: userIdApi, controllers: controllers, errorMessages: errorMessages, selectedGender: selectedGender, selectedCountry: selectedCountry, selectedRole: selectedRole, apiselectedUser: isapiselectedUser, onUserTypeChanged: handleUserTypeChange, onGenderChanged: (gender) { setState(() { selectedGender = gender; }); }, onCountryChanged: (country) { setState(() { selectedCountry = country; }); }, onRoleChanged: (role) { setState(() { selectedRole = role; }); }, onServiceIdsChanged: (List> updatedList) { setState(() { selectedServiceIds = updatedList; }); }, initialSelectedServices: selectedServiceIds, ); case "office": return OfficeDetails( isDesktop: isDesktop, // pass isDesktop as a named argument isViewMode: isViewMode, userIdApi: userIdApi, controllers: controllers, errorMessages: errorMessages, selectedLevel: selectedLevel, selectedDepartment: selectedDepartment, selectedFirstApprover: selectedFirstApprover, selectedSecondApprover: selectedSecondApprover, selectedThirdApprover: selectedThirdApprover, selectedSubstituteApprover: selectedSubstituteApprover, onLevelChanged: (gender) { setState(() { selectedLevel = gender; }); }, onDepartmentChanged: (country) { setState(() { selectedDepartment = country; }); }, onFirstApproverChanged: (role) { setState(() { selectedFirstApprover = role; }); }, onSecondApproverChanged: (role) { setState(() { selectedSecondApprover = role; }); }, onThirdApproverChanged: (role) { setState(() { selectedThirdApprover = role; }); }, onFirstSubsApproverChanged: (role) { setState(() { selectedSubstituteApprover = role; print("onFirstSubsApproverChanged - $selectedSubstituteApprover"); }); }, ); case "travel": final fullName = "${controllers["Fname"]?.text ?? ""} ${controllers["Lname"]?.text ?? ""}" .trim(); return TravellerDetails( key: travellerDetailsKey, isDesktop: isDesktop, isViewMode: isViewMode, controllers: controllers, errorMessages: errorMessages, travelDetails: travelDetailsDataFromAPI, // 👈 Pass this down passportFileUrlFromApi: passportFileUrlFromApi, userIdApi: userIdApi, fullName: fullName, ); default: return PersonalDetails( personalDetailsKey: personalDetailsKey, isDesktop: isDesktop, // pass isDesktop as a named argument isViewMode: isViewMode, userIdApi: userIdApi, controllers: controllers, errorMessages: errorMessages, selectedGender: selectedGender, selectedCountry: selectedCountry, apiselectedUser: isapiselectedUser, onUserTypeChanged: handleUserTypeChange, onServiceIdsChanged: (List> updatedList) { setState(() { selectedServiceIds = updatedList; }); }, ); } } Widget buildTabsForUser() { // final tabs = { // "personal": "Personal Details", // "office": "Office Details", // "travel": "Travel Details", // }; final Map allTabs = { "personal": "Personal Details", "office": "Office Details", "travel": "Travel Details", }; Map getTabs(bool setSelectesUserType) { if (setSelectesUserType || selectedRole == "5") { return {"personal": "Personal Details"}; } else { return allTabs; } } final tabs = getTabs(setSelectesUserType); return Row( crossAxisAlignment: CrossAxisAlignment.end, // important children: tabs.entries.map((entry) { final targetTab = entry.key; print("TargetsTAb: $targetTab"); final isSelected = selectedTab == entry.key; print("isSelected: $isSelected"); return GestureDetector( onTap: () { setState(() { bool isValid = false; final currentTab = selectedTab; if (currentTab == "personal") { isValid = isValidData(userDetials); if (isValid) { selectedTab = entry.key; } } else if (currentTab == "office" && targetTab == "personal") { selectedTab = entry.key; } else if (currentTab == "office") { isValid = isValidDataTwo(userDetials); if (isValid) { selectedTab = entry.key; } } else { isValid = true; // Travel tab might not need validation at this point selectedTab = entry.key; } }); }, child: Padding( padding: const EdgeInsets.only( right: 24.0, ), // space between tabs child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( entry.value, style: GoogleFonts.poppins( fontSize: 12, fontWeight: FontWeight.w600, color: isSelected ? Color(0xFF114D8B) : Color(0xFF475569), ), ), const SizedBox(height: 8), AnimatedContainer( duration: Duration(milliseconds: 300), height: 2, width: isSelected ? 50 : 0, // small line color: Color(0xFF114D8B), ), ], ), ), ); }).toList(), ); } // ---- Submit --------------------------------------- List _buildGoBack(isDesktop, Color layoutColor) { return [ MouseRegion( cursor: isViewMode ? SystemMouseCursors.forbidden : SystemMouseCursors.click, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: isViewMode ? layoutColor : layoutColor, // Keep original color foregroundColor: isViewMode ? Colors.white : 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, width: 2), ), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), onPressed: handleGoBack, child: Text("Back"), ), ), ]; } List _buildNext(isDesktop, Color layoutColor) { return [ MouseRegion( cursor: isViewMode ? SystemMouseCursors.forbidden : SystemMouseCursors.click, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: isViewMode ? layoutColor : layoutColor, // Keep original color foregroundColor: isViewMode ? Colors.white : 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, width: 2), ), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), onPressed: handleNext, // onPressed: // isViewMode ? null : handleNext, // Disable when in view mode child: Text("Next"), ), ), ]; } List _buildBack(isDesktop, Color layoutColor) { return [ MouseRegion( cursor: isViewMode ? SystemMouseCursors.forbidden : SystemMouseCursors.click, child: TextButton( style: ElevatedButton.styleFrom( backgroundColor: isViewMode ? layoutColor : layoutColor, // Keep original color foregroundColor: isViewMode ? Colors.white : Colors.red, // Keep original color disabledBackgroundColor: layoutColor, // Ensure color remains when disabled disabledForegroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), side: BorderSide(color: layoutColor, width: 2), ), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), onPressed: handleNext, // onPressed: // isViewMode ? null : handleNext, // Disable when in view mode child: Text("Next"), ), ), ]; } List _buildSubmit(isDesktop, Color layoutColor) { return [ ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.white, foregroundColor: layoutColor, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), side: BorderSide(color: layoutColor, width: 2), ), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), onPressed: () { isEditProfile ? context.go('/listPlan') : context.go('/listUser'); }, child: Text("Cancel"), ), SizedBox(width: 20), if (!isViewMode) MouseRegion( cursor: isViewMode ? SystemMouseCursors.forbidden : SystemMouseCursors.click, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: isViewMode ? layoutColor : layoutColor, // Keep original color foregroundColor: isViewMode ? Colors.white : 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, width: 2), ), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), ), onPressed: isViewMode ? null : handleSubmit, // Disable when in view mode child: Text("Submit"), ), ), ]; } } class DatabaseHelper { // Example: Singleton pattern to ensure only one instance of the class exists static final DatabaseHelper _instance = DatabaseHelper._internal(); // Private constructor to prevent external instantiation DatabaseHelper._internal(); // Public method to access the instance static DatabaseHelper get instance => _instance; // Add your database methods here Future fetchData() async { // Implement data fetching logic } }