travelAgent-restriction
|
Before Width: | Height: | Size: 544 B After Width: | Height: | Size: 355 B |
|
Before Width: | Height: | Size: 442 B After Width: | Height: | Size: 265 B |
|
Before Width: | Height: | Size: 721 B After Width: | Height: | Size: 442 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 622 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 772 B |
BIN
assets/images/IconsImg/favicon_ts.png
Normal file
|
After Width: | Height: | Size: 2.2 KiB |
@ -427,7 +427,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
@ -484,7 +484,7 @@
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
|
||||
@ -1,122 +1 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
{"images":[{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@3x.png","scale":"3x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@1x.png","scale":"1x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@1x.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@1x.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@1x.png","scale":"1x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@2x.png","scale":"2x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@1x.png","scale":"1x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@1x.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"Icon-App-83.5x83.5@2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"Icon-App-1024x1024@1x.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}}
|
||||
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 7.3 KiB |
|
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 185 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 241 B |
|
Before Width: | Height: | Size: 450 B After Width: | Height: | Size: 287 B |
|
Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 207 B |
|
Before Width: | Height: | Size: 462 B After Width: | Height: | Size: 287 B |
|
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 421 B |
|
Before Width: | Height: | Size: 406 B After Width: | Height: | Size: 241 B |
|
Before Width: | Height: | Size: 586 B After Width: | Height: | Size: 389 B |
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 527 B |
|
After Width: | Height: | Size: 281 B |
|
After Width: | Height: | Size: 475 B |
|
After Width: | Height: | Size: 283 B |
|
After Width: | Height: | Size: 509 B |
|
Before Width: | Height: | Size: 862 B After Width: | Height: | Size: 527 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 743 B |
|
After Width: | Height: | Size: 355 B |
|
After Width: | Height: | Size: 622 B |
|
Before Width: | Height: | Size: 762 B After Width: | Height: | Size: 388 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 649 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 721 B |
@ -583,16 +583,18 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
}
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
},
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: selectedOrg != null && selectedOrg!.isNotEmpty
|
||||
? "Update Organization"
|
||||
: "Create Organization",
|
||||
title:
|
||||
selectedOrg != null &&
|
||||
selectedOrg!.isNotEmpty
|
||||
? "Update Organization"
|
||||
: "Create Organization",
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -991,7 +993,7 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
case 'train':
|
||||
return Icons.train_outlined;
|
||||
case 'bus':
|
||||
return Icons.bus_alert_outlined;
|
||||
return Icons.directions_bus_rounded;
|
||||
case 'taxi':
|
||||
return Icons.local_taxi_outlined;
|
||||
case 'accomodation':
|
||||
|
||||
@ -3405,7 +3405,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Reason For Exceptional Class *", // Your label
|
||||
"Reason for travel policy exception*", // Your label
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
@ -3422,6 +3422,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
? MediaQuery.of(context).size.width * 0.42
|
||||
: null,
|
||||
isDesktop: widget.isDesktop,
|
||||
hasError: validationErrors["exceptional_plan_reason"] != null,
|
||||
child: SizedBox(
|
||||
height: 55,
|
||||
child: TextField(
|
||||
@ -3432,7 +3433,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
style: TextStyle(fontSize: 12),
|
||||
enabled: !widget.isViewMode,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Exceptional Description",
|
||||
labelText: "Reason for exception ",
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
@ -3440,6 +3441,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
// labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 1),
|
||||
),
|
||||
),
|
||||
|
||||
@ -11,7 +11,6 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
|
||||
import 'package:frontend/utils/auth_utils.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
@ -36,10 +35,12 @@ import 'package:universal_html/html.dart' as html;
|
||||
|
||||
class CreateTravelAgentFormDetials extends StatefulWidget {
|
||||
@override
|
||||
_CreateTravelAgentFormDetialsState createState() => _CreateTravelAgentFormDetialsState();
|
||||
_CreateTravelAgentFormDetialsState createState() =>
|
||||
_CreateTravelAgentFormDetialsState();
|
||||
}
|
||||
|
||||
class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDetials> {
|
||||
class _CreateTravelAgentFormDetialsState
|
||||
extends State<CreateTravelAgentFormDetials> {
|
||||
final ApiService apiService = ApiService();
|
||||
|
||||
final GlobalKey<PersonalDetailsState> personalDetailsKey =
|
||||
@ -92,7 +93,8 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
|
||||
// String? selectedGender = personalDetailsKey.currentState?.selectedGender;
|
||||
|
||||
String? selectedUserType;
|
||||
String? selectedRole = "5"; // here only harded // hardcoded due to travel agent
|
||||
String? selectedRole =
|
||||
"5"; // here only harded // hardcoded due to travel agent
|
||||
String? selectedLevel;
|
||||
String? selectedDepartment;
|
||||
String? selectedFirstApprover;
|
||||
@ -339,79 +341,6 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
|
||||
}
|
||||
|
||||
@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<String, dynamic>?;
|
||||
//
|
||||
// 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<String, dynamic>?; // 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();
|
||||
// }
|
||||
// }
|
||||
void initState() {
|
||||
super.initState();
|
||||
setState(() {
|
||||
@ -746,7 +675,7 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
|
||||
|
||||
print("USERDETAILS : $data");
|
||||
|
||||
final tabs = { "personal": "Personal Details" };
|
||||
final tabs = {"personal": "Personal Details"};
|
||||
|
||||
final tabKeys = tabs.keys.toList(); // ["personal", "office", "travel"]
|
||||
|
||||
@ -781,42 +710,14 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
|
||||
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("travel gnt Detail Submit");
|
||||
// printFormData();
|
||||
print("travel validation");
|
||||
bool isValid = false;
|
||||
bool isValid = false;
|
||||
|
||||
print("Start loader at: ${DateTime.now()}");
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (context) => const SavingLoader(),
|
||||
);
|
||||
if (selectedRole == "5") {
|
||||
print("NO validation");
|
||||
|
||||
@ -948,8 +849,8 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
|
||||
CreateTravelAgentData(userDetials);
|
||||
}
|
||||
}
|
||||
|
||||
if (mounted) Navigator.of(context, rootNavigator: true).pop();
|
||||
//
|
||||
// if (mounted) Navigator.of(context, rootNavigator: true).pop();
|
||||
}
|
||||
|
||||
bool isValidData(Map<String, dynamic> data) {
|
||||
@ -963,6 +864,7 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
|
||||
"mobile_no",
|
||||
"role_id",
|
||||
// "employeeCode",
|
||||
"agent_supported_service_ids",
|
||||
];
|
||||
|
||||
if (apiselectedUser == null) {
|
||||
@ -1002,6 +904,15 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
|
||||
errorMessages["email"] = "Invalid email format"; // Invalid email format
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ Validate agent_supported_service_ids list
|
||||
if (data["agent_supported_service_ids"] == null ||
|
||||
!(data["agent_supported_service_ids"] is List) ||
|
||||
(data["agent_supported_service_ids"] as List).isEmpty) {
|
||||
errorMessages["agent_supported_service_ids"] =
|
||||
"Select at least one service";
|
||||
}
|
||||
|
||||
return errorMessages.isEmpty; // Valid if there are no errors
|
||||
}
|
||||
|
||||
@ -1340,21 +1251,24 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
}
|
||||
title: 'Organization Settings',
|
||||
tooltip: 'Go To Organization Settings',
|
||||
onTap: (context) {
|
||||
context.go("/OrganizationSettings");
|
||||
},
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: 'Travel Agent',
|
||||
tooltip: 'Go To Travel Agent',
|
||||
onTap: (context) {
|
||||
context.go("/listTravelAgent");
|
||||
}
|
||||
title: 'Travel Agent',
|
||||
tooltip: 'Go To Travel Agent',
|
||||
onTap: (context) {
|
||||
context.go("/listTravelAgent");
|
||||
},
|
||||
),
|
||||
BreadcrumbItem(
|
||||
title: apiselectedUser != null ? "Edit Travel Agent" : "Create Travel Agent",
|
||||
title:
|
||||
apiselectedUser != null
|
||||
? "Edit Travel Agent"
|
||||
: "Create Travel Agent",
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -1532,7 +1446,7 @@ class _CreateTravelAgentFormDetialsState extends State<CreateTravelAgentFormDeti
|
||||
Map<String, String> getTabs(bool setSelectesUserType) {
|
||||
// print(setSelectesUserType);
|
||||
// if (setSelectesUserType || selectedRole == "5") {
|
||||
return {"personal": "Personal Details"};
|
||||
return {"personal": "Personal Details"};
|
||||
// } else {
|
||||
// return allTabs;
|
||||
// }
|
||||
|
||||
@ -257,7 +257,8 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
final filteredRole = roleList.where((item) => item['dropdown_key'] == '5').toList();
|
||||
final filteredRole =
|
||||
roleList.where((item) => item['dropdown_key'] == '5').toList();
|
||||
apiRoleData = filteredRole;
|
||||
});
|
||||
print("APIROLEData - $apiRoleData");
|
||||
@ -397,6 +398,17 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
// color: Color(0xFF212121)),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
|
||||
if (widget.errorMessages["agent_supported_service_ids"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Align(
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
widget.errorMessages["agent_supported_service_ids"]!,
|
||||
style: GoogleFonts.poppins(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
),
|
||||
],
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Color(0xFFF4F4FB)),
|
||||
@ -651,7 +663,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
width: MediaQuery.of(context).size.width * 0.015,
|
||||
),
|
||||
buildRole(),
|
||||
]
|
||||
],
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
@ -1201,7 +1213,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
countryMap = {
|
||||
for (var country in countryList)
|
||||
(country['country_code'] ?? ''):
|
||||
'${country['country_name'] ?? ''} (${country['country_code'] ?? ''})',
|
||||
'${country['country_name'] ?? ''} (${country['country_code'] ?? ''})',
|
||||
};
|
||||
|
||||
// Extract only country codes for processing
|
||||
@ -1234,19 +1246,19 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
fit: FlexFit.loose, // Allows flexible height
|
||||
menuProps: const MenuProps(backgroundColor: Colors.white),
|
||||
itemBuilder:
|
||||
// (context, item, isSelected) => Container(
|
||||
// padding: EdgeInsets.symmetric(
|
||||
// horizontal: 10,
|
||||
// vertical: 6,
|
||||
// ),
|
||||
// child: Text(
|
||||
// item,
|
||||
// style: GoogleFonts.poppins(fontSize: 11.5),
|
||||
// ),
|
||||
// ),
|
||||
(context, item, isSelected) {
|
||||
// (context, item, isSelected) => Container(
|
||||
// padding: EdgeInsets.symmetric(
|
||||
// horizontal: 10,
|
||||
// vertical: 6,
|
||||
// ),
|
||||
// child: Text(
|
||||
// item,
|
||||
// style: GoogleFonts.poppins(fontSize: 11.5),
|
||||
// ),
|
||||
// ),
|
||||
(context, item, isSelected) {
|
||||
print("contryItem - $item");
|
||||
final match = RegExp(r'^(.*)\s\((.*)\)$',).firstMatch(item);
|
||||
final match = RegExp(r'^(.*)\s\((.*)\)$').firstMatch(item);
|
||||
final countryName = match?.group(1) ?? '';
|
||||
final countryCode = match?.group(2) ?? '';
|
||||
return Padding(
|
||||
@ -1265,13 +1277,16 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
Text(
|
||||
countryCode,
|
||||
style: GoogleFonts.poppins(fontSize: 11.5,color:Colors.grey),
|
||||
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11.5,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);},
|
||||
);
|
||||
},
|
||||
constraints: BoxConstraints(maxHeight: 200),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
@ -1388,7 +1403,6 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
}
|
||||
|
||||
Widget buildRole() {
|
||||
|
||||
Map<String, String> roleMap = {
|
||||
for (var item in apiRoleData ?? [])
|
||||
item['dropdown_key'] as String: item['dropdown_value'] as String,
|
||||
@ -1415,7 +1429,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem: roleMap[selectedRole] ,
|
||||
selectedItem: roleMap[selectedRole],
|
||||
enabled: false, //enabled: !widget.isViewMode,
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true,
|
||||
@ -1424,16 +1438,16 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
menuProps: const MenuProps(backgroundColor: Colors.white),
|
||||
itemBuilder:
|
||||
(context, item, isSelected) => Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 6,
|
||||
),
|
||||
child: Text(
|
||||
item,
|
||||
style: GoogleFonts.poppins(fontSize: 11.5),
|
||||
),
|
||||
),
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 6,
|
||||
),
|
||||
child: Text(
|
||||
item,
|
||||
style: GoogleFonts.poppins(fontSize: 11.5),
|
||||
),
|
||||
),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Role...",
|
||||
@ -1450,33 +1464,33 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
dropdownBuilder:
|
||||
(context, selectedItem) => Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select Role",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select Role",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
onChanged:
|
||||
widget.isViewMode
|
||||
? null
|
||||
: (String? newValue) {
|
||||
widget.errorMessages.remove("role_id");
|
||||
if (newValue == null) return;
|
||||
final selectedKey =
|
||||
roleMap.entries
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
widget.isViewMode
|
||||
? null
|
||||
: (String? newValue) {
|
||||
widget.errorMessages.remove("role_id");
|
||||
if (newValue == null) return;
|
||||
final selectedKey =
|
||||
roleMap.entries
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
|
||||
setState(() {
|
||||
selectedRole = selectedKey;
|
||||
isTravelAgent = selectedKey == "5";
|
||||
});
|
||||
widget.onUserTypeChanged?.call(isTravelAgent);
|
||||
widget.onRoleChanged?.call(selectedKey);
|
||||
},
|
||||
setState(() {
|
||||
selectedRole = selectedKey;
|
||||
isTravelAgent = selectedKey == "5";
|
||||
});
|
||||
widget.onUserTypeChanged?.call(isTravelAgent);
|
||||
widget.onRoleChanged?.call(selectedKey);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -2,7 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
// import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'dart:html' as html;
|
||||
import 'package:frontend/config/apiUrl.dart'; // 1 newly added
|
||||
import 'package:frontend/services/apiService.dart';
|
||||
@ -31,7 +31,7 @@ class _MyAppState extends State<MyApp> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// SemanticsBinding.instance.ensureSemantics(); // ✅ Safe here
|
||||
SemanticsBinding.instance.ensureSemantics(); // ✅ Safe here
|
||||
if (kIsWeb) {
|
||||
final uri = Uri.parse(html.window.location.href);
|
||||
print("URI - $uri");
|
||||
@ -193,7 +193,7 @@ class _MyAppState extends State<MyApp> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp.router(
|
||||
title: 'TRIP MANAGEMENT',
|
||||
title: 'Trip Approval Tool',
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
//api url
|
||||
const String apiUrl = 'http://apitest.tripapprovaltool.com/tstat_be';
|
||||
// const String apiUrl = 'https://uat.tripapprovaltool.com/tstat_be';
|
||||
|
||||
@ -13,6 +13,7 @@ class CustomTextFieldWrapper extends StatefulWidget {
|
||||
final EdgeInsetsGeometry padding;
|
||||
final BorderRadius? borderRadius;
|
||||
final Color? layoutColor;
|
||||
final bool hasError;
|
||||
|
||||
const CustomTextFieldWrapper({
|
||||
super.key,
|
||||
@ -25,6 +26,7 @@ class CustomTextFieldWrapper extends StatefulWidget {
|
||||
this.padding = const EdgeInsets.symmetric(horizontal: 12),
|
||||
this.borderRadius,
|
||||
this.layoutColor,
|
||||
this.hasError = false,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -80,11 +82,24 @@ class _CustomTextFieldWrapperState extends State<CustomTextFieldWrapper> {
|
||||
color: Colors.white,
|
||||
borderRadius: widget.borderRadius ?? BorderRadius.circular(8),
|
||||
|
||||
// border: Border.all(
|
||||
// color: widget.isFocused ? layoutColor! : Color(0xFFD6D5E6),
|
||||
// // color: widget.isFocused ? Color(0xFF78B4FC) : Color(0xFFD6D5E6),
|
||||
// width: widget.isFocused ? 1.0 : 0.5,
|
||||
// ),
|
||||
border: Border.all(
|
||||
color: widget.isFocused ? layoutColor! : Color(0xFFD6D5E6),
|
||||
// color: widget.isFocused ? Color(0xFF78B4FC) : Color(0xFFD6D5E6),
|
||||
width: widget.isFocused ? 1.0 : 0.5,
|
||||
color:
|
||||
widget.hasError
|
||||
? Colors
|
||||
.red // 👈 show red if error
|
||||
: (widget.isFocused
|
||||
? layoutColor ??
|
||||
Colors
|
||||
.blue // focused border color
|
||||
: Color(0xFFD6D5E6)), // normal border
|
||||
width: widget.hasError ? 1.2 : (widget.isFocused ? 1.0 : 0.5),
|
||||
),
|
||||
|
||||
// boxShadow:
|
||||
// widget.isFocused
|
||||
// ? [
|
||||
|
||||
@ -30,13 +30,14 @@ class _CustomTextFieldUserWrapperState
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: widget.width ?? // Use custom width if provided, else default
|
||||
width:
|
||||
widget.width ?? // Use custom width if provided, else default
|
||||
(widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.25
|
||||
: MediaQuery.of(context).size.width * 0.8),
|
||||
padding: widget.padding,
|
||||
decoration: BoxDecoration(
|
||||
// color: widget.color,
|
||||
color: widget.color,
|
||||
// color: Color(0xFFF7F7FB),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(
|
||||
@ -44,16 +45,17 @@ class _CustomTextFieldUserWrapperState
|
||||
// color: widget.isFocused ? Color(0xFF78B4FC) : Color(0xFFD6D5E6),
|
||||
width: widget.isFocused ? 2.0 : 0.5,
|
||||
),
|
||||
boxShadow: widget.isFocused
|
||||
? [
|
||||
BoxShadow(
|
||||
color: Color.fromRGBO(120, 180, 252, 0.3),
|
||||
blurRadius: 10,
|
||||
spreadRadius: 2,
|
||||
offset: Offset(0, 4),
|
||||
),
|
||||
]
|
||||
: [],
|
||||
// boxShadow:
|
||||
// widget.isFocused
|
||||
// ? [
|
||||
// BoxShadow(
|
||||
// color: Color.fromRGBO(120, 180, 252, 0.3),
|
||||
// blurRadius: 10,
|
||||
// spreadRadius: 2,
|
||||
// offset: Offset(0, 4),
|
||||
// ),
|
||||
// ]
|
||||
// : [],
|
||||
),
|
||||
child: widget.child,
|
||||
);
|
||||
|
||||
66
pubspec.lock
@ -57,6 +57,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.2"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -270,6 +286,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
flutter_launcher_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_launcher_icons
|
||||
sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.14.4"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
@ -397,6 +421,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.5.4"
|
||||
image_picker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -469,6 +501,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.20.2"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_annotation
|
||||
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.9.0"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -629,6 +669,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.1.0"
|
||||
photo_view:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1050,6 +1098,22 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.5.0"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.7.2 <4.0.0"
|
||||
dart: ">=3.8.0 <4.0.0"
|
||||
flutter: ">=3.29.0"
|
||||
|
||||
@ -62,6 +62,7 @@ dependencies:
|
||||
flutter_html: ^3.0.0
|
||||
html2md: ^1.3.2
|
||||
flutter_quill_delta_from_html: ^1.5.2
|
||||
flutter_launcher_icons: ^0.14.4
|
||||
|
||||
|
||||
|
||||
@ -91,6 +92,7 @@ flutter:
|
||||
# the material Icons class.
|
||||
uses-material-design: true
|
||||
assets:
|
||||
|
||||
- assets/images/login/login_img1.png
|
||||
- assets/images/login/login_terminal.png
|
||||
- assets/images/login/login_travel.png
|
||||
@ -109,6 +111,10 @@ flutter:
|
||||
- assets/images/IconsImg/download.png
|
||||
- assets/images/IconsImg/planPdf_icon.png
|
||||
|
||||
flutter_icons:
|
||||
android: true
|
||||
ios: true
|
||||
image_path: "assets/images/IconsImg/favicon_ts.png"
|
||||
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
|
||||
BIN
web/favicon.png
|
Before Width: | Height: | Size: 917 B After Width: | Height: | Size: 2.2 KiB |
@ -25,7 +25,7 @@
|
||||
<!-- iOS meta tags & icons -->
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="frontend">
|
||||
<meta name="apple-mobile-web-app-title" content="Trip Approval Tool">
|
||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||
|
||||
<!-- Favicon -->
|
||||
|
||||