ui_input_formatters

This commit is contained in:
venbaittech 2025-10-27 17:35:57 +05:30
parent 52878d6810
commit aaff31e8d4
43 changed files with 1069 additions and 648 deletions

View File

@ -204,7 +204,8 @@ class _ListAllPlansState extends State<ListAllPlans> {
Future<List<Plan>> fetchPlans() async { Future<List<Plan>> fetchPlans() async {
late String apiUrldata; late String apiUrldata;
apiUrldata = '$apiUrl/api/plans?org_id=$orgId'; // apiUrldata = '$apiUrl/api/plans?org_id=$orgId';
apiUrldata = '$apiUrl/api/allPlans?org_id=$orgId';
// if (roleUser == "Org Admin") { // if (roleUser == "Org Admin") {
// apiUrldata = '$apiUrl/api/plans?org_id=$orgId'; // apiUrldata = '$apiUrl/api/plans?org_id=$orgId';
@ -283,7 +284,7 @@ class _ListAllPlansState extends State<ListAllPlans> {
} }
} }
void deletePlan(String planId) async { void deletePlan(String planId, userId) async {
bool confirmed = await apiService.showCancelConfirmationDialog( bool confirmed = await apiService.showCancelConfirmationDialog(
context, context,
layoutColor, layoutColor,
@ -293,6 +294,7 @@ class _ListAllPlansState extends State<ListAllPlans> {
try { try {
Map<String, dynamic> planData = await ApiService().getViewPlan( Map<String, dynamic> planData = await ApiService().getViewPlan(
planId, planId,
userId,
context, context,
); );
print("ViewAAA - $planData"); print("ViewAAA - $planData");
@ -1135,6 +1137,7 @@ class _ListAllPlansState extends State<ListAllPlans> {
); );
deletePlan( deletePlan(
plan.planId, plan.planId,
userId,
); );
}, },
), ),
@ -1455,6 +1458,7 @@ class _ListAllPlansState extends State<ListAllPlans> {
); );
deletePlan( deletePlan(
plan.planId, plan.planId,
userId,
); );
}, },
), ),

View File

@ -143,14 +143,17 @@ class _TripInformationState extends State<TripInformation> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
keyValueRow("Action", item["action"]), keyValueRow("Action", item["action"] ?? '-'),
keyValueRow("Approver", item["approver"]), keyValueRow("Approver", item["approver"] ?? '-'),
keyValueRow( keyValueRow(
"Is Action Done", "Is Action Done",
item["is_action_done"], item["is_action_done"] ?? '-',
),
keyValueRow("Action On", item["action_on"] ?? '-'),
keyValueRow(
"Email Status",
item["email_status"] ?? '-',
), ),
keyValueRow("Action On", item["action_on"]),
keyValueRow("Email Status", item["email_status"]),
], ],
), ),
), ),

View File

@ -364,6 +364,7 @@ class _TravelAgentListPlansState extends State<TravelAgentListPlans> {
try { try {
Map<String, dynamic> planData = await ApiService().getViewPlan( Map<String, dynamic> planData = await ApiService().getViewPlan(
planId, planId,
userId,
context, context,
); );
print("ViewAAA - $planData"); print("ViewAAA - $planData");

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
Future<dynamic> showApprovalDialog( Future<dynamic> showApprovalDialog(
BuildContext context, BuildContext context,
@ -115,6 +116,11 @@ Future<dynamic> showApprovalDialog(
TextField( TextField(
style: TextStyle(fontFamily: "Inter", fontSize: 14), style: TextStyle(fontFamily: "Inter", fontSize: 14),
maxLines: 3, maxLines: 3,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
onChanged: (value) => remarks = value, onChanged: (value) => remarks = value,
decoration: InputDecoration( decoration: InputDecoration(
hintText: "Remarks...", hintText: "Remarks...",
@ -263,8 +269,14 @@ Future<String?> showRejectDialog1(
const Text("Please enter reason for rejection."), const Text("Please enter reason for rejection."),
const SizedBox(height: 10), const SizedBox(height: 10),
TextField( TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
maxLines: 3, maxLines: 3,
onChanged: (value) => remarks = value, onChanged: (value) => remarks = value,
decoration: const InputDecoration( decoration: const InputDecoration(
hintText: "Remarks...", hintText: "Remarks...",
hintStyle: TextStyle( hintStyle: TextStyle(

View File

@ -256,7 +256,7 @@ class _ApprovalListState extends State<ApprovalList> {
} }
} }
void deletePlan(String planId) async { void deletePlan(String planId, userId) async {
// try { // try {
// Map<String, dynamic> planData = await getViewPlan(planId); // Map<String, dynamic> planData = await getViewPlan(planId);
// print("ViewAAA - $planData"); // print("ViewAAA - $planData");
@ -275,6 +275,7 @@ class _ApprovalListState extends State<ApprovalList> {
try { try {
Map<String, dynamic> planData = await ApiService().getViewPlan( Map<String, dynamic> planData = await ApiService().getViewPlan(
planId, planId,
userId,
context, context,
); );
print("ViewAAA - $planData"); print("ViewAAA - $planData");
@ -1207,6 +1208,7 @@ class _ApprovalListState extends State<ApprovalList> {
); );
deletePlan( deletePlan(
plan.planId, plan.planId,
userId,
); );
}, },
), ),

View File

@ -4,6 +4,7 @@ import 'dart:html' as html;
import 'package:encrypt/encrypt.dart' as encrypt; import 'package:encrypt/encrypt.dart' as encrypt;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:frontend/config/apiUrl.dart'; import 'package:frontend/config/apiUrl.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
@ -580,6 +581,7 @@ class _LoginWidgetState extends State<LoginWidget> {
_buildLabel("Email Address"), _buildLabel("Email Address"),
TextFormField( TextFormField(
controller: _emailController, controller: _emailController,
inputFormatters: [],
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
fontSize: 11, fontSize: 11,

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -314,6 +315,11 @@ class CostCenterDataState extends State<CostCenterData> {
child: TextField( child: TextField(
controller: controllers["name"], controller: controllers["name"],
focusNode: focusNodes["nameFocusNode"], focusNode: focusNodes["nameFocusNode"],
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: "Name", labelText: "Name",
@ -356,6 +362,11 @@ class CostCenterDataState extends State<CostCenterData> {
child: TextField( child: TextField(
controller: controllers["description"], controller: controllers["description"],
focusNode: focusNodes["descriptionFocusNode"], focusNode: focusNodes["descriptionFocusNode"],
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
maxLines: null, maxLines: null,
expands: true, expands: true,

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -313,6 +314,11 @@ class DepartmentDataState extends State<DepartmentData> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
controller: controllers["dropdown_value"], controller: controllers["dropdown_value"],
focusNode: focusNodes["dropdown_valueFocusNode"], focusNode: focusNodes["dropdown_valueFocusNode"],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),

View File

@ -320,6 +320,7 @@ class DepartmentListState extends State<DepartmentList> {
height: 40, height: 40,
child: TextField( child: TextField(
controller: searchController, controller: searchController,
onChanged: filterDepartment, onChanged: filterDepartment,
decoration: InputDecoration( decoration: InputDecoration(
hintText: "Search ...", hintText: "Search ...",

View File

@ -176,11 +176,6 @@ class _UserSelectionDialogState extends State<UserSelectionDialog> {
await apiService.logout(context); await apiService.logout(context);
return null; return null;
// throw Exception('Failed to load users'); // throw Exception('Failed to load users');
} else if (response.statusCode == 403) {
print("403-FORB");
await apiService.logout(context);
return null;
// throw Exception('Failed to load users');
} else { } else {
throw Exception( throw Exception(
'Failed to load users. Status Code: ${response.statusCode}', 'Failed to load users. Status Code: ${response.statusCode}',

View File

@ -4,6 +4,7 @@ import 'dart:io';
import 'package:dropdown_search/dropdown_search.dart'; import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:frontend/Screens/organization/mailSettings.dart'; import 'package:frontend/Screens/organization/mailSettings.dart';
import 'package:frontend/Screens/organization/themeColor.dart'; import 'package:frontend/Screens/organization/themeColor.dart';
import 'package:frontend/utils/auth_utils.dart'; import 'package:frontend/utils/auth_utils.dart';
@ -481,6 +482,9 @@ class _groupState extends State<Group> {
height: 40, height: 40,
child: TextField( child: TextField(
controller: controllers["name"], controller: controllers["name"],
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
onChanged: (value) { onChanged: (value) {
_clearError("name"); _clearError("name");
@ -527,6 +531,9 @@ class _groupState extends State<Group> {
height: 40, height: 40,
child: TextField( child: TextField(
controller: controllers["description"], controller: controllers["description"],
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
onChanged: (value) { onChanged: (value) {
_clearError("description"); _clearError("description");
}, },

View File

@ -426,7 +426,11 @@ class GroupDataState extends State<GroupData> {
height: 40, height: 40,
child: TextField( child: TextField(
focusNode: focusNodes["nameFocusNode"], focusNode: focusNodes["nameFocusNode"],
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
controller: controllers["name"], controller: controllers["name"],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: const InputDecoration( decoration: const InputDecoration(
@ -779,7 +783,11 @@ class GroupDataState extends State<GroupData> {
child: TextField( child: TextField(
controller: controllers["description"], controller: controllers["description"],
focusNode: focusNodes["descriptionFocusNode"], focusNode: focusNodes["descriptionFocusNode"],
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
maxLines: null, maxLines: null,
expands: true, expands: true,

View File

@ -372,6 +372,11 @@ class HotelsDataState extends State<HotelsData> {
height: 40, height: 40,
child: TextField( child: TextField(
focusNode: focusNodes["hotel_nameFocusNode"], focusNode: focusNodes["hotel_nameFocusNode"],
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
controller: controllers["hotel_name"], controller: controllers["hotel_name"],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: const InputDecoration( decoration: const InputDecoration(
@ -415,6 +420,11 @@ class HotelsDataState extends State<HotelsData> {
child: TextField( child: TextField(
focusNode: focusNodes["hotel_chainFocusNode"], focusNode: focusNodes["hotel_chainFocusNode"],
controller: controllers["hotel_chain"], controller: controllers["hotel_chain"],
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: "Hotel Chain", labelText: "Hotel Chain",
@ -458,6 +468,7 @@ class HotelsDataState extends State<HotelsData> {
child: TextField( child: TextField(
focusNode: focusNodes["categoryFocusNode"], focusNode: focusNodes["categoryFocusNode"],
controller: controllers["category"], controller: controllers["category"],
inputFormatters: [ inputFormatters: [
FilteringTextInputFormatter.allow( FilteringTextInputFormatter.allow(
RegExp(r'[a-z A-Z0-9 ]'), RegExp(r'[a-z A-Z0-9 ]'),
@ -665,6 +676,11 @@ class HotelsDataState extends State<HotelsData> {
height: 40, height: 40,
child: TextField( child: TextField(
focusNode: focusNodes["cityFocusNode"], focusNode: focusNodes["cityFocusNode"],
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
controller: controllers["city"], controller: controllers["city"],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: const InputDecoration( decoration: const InputDecoration(

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -379,6 +380,11 @@ class HotelsDataListState extends State<HotelsDataList> {
height: 40, height: 40,
child: TextField( child: TextField(
controller: searchController, controller: searchController,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
onChanged: filterHotels, onChanged: filterHotels,
decoration: InputDecoration( decoration: InputDecoration(
hintText: "Search ...", hintText: "Search ...",

View File

@ -1,5 +1,6 @@
import 'package:dropdown_search/dropdown_search.dart'; import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:responsive_builder/responsive_builder.dart'; import 'package:responsive_builder/responsive_builder.dart';
@ -664,6 +665,9 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
focusNode: _destinationFocusNode, focusNode: _destinationFocusNode,
controller: _destinationController, controller: _destinationController,
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Destination", labelText: "Destination",
labelStyle: TextStyle(fontSize: 12, color: Colors.grey), labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
@ -1503,6 +1507,9 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
child: TextField( child: TextField(
focusNode: _commentsFocusNode, focusNode: _commentsFocusNode,
controller: _commentsController, controller: _commentsController,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Comments", labelText: "Comments",

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:responsive_builder/responsive_builder.dart'; import 'package:responsive_builder/responsive_builder.dart';
@ -466,6 +467,9 @@ class _BusScreenState extends State<BusScreen> {
focusNode: _fromFocusNode, focusNode: _fromFocusNode,
controller: _fromController, controller: _fromController,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: "From", labelText: "From",
labelStyle: TextStyle(fontSize: 12, color: Colors.grey), labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
@ -503,6 +507,9 @@ class _BusScreenState extends State<BusScreen> {
child: TextField( child: TextField(
focusNode: _toFocusNode, focusNode: _toFocusNode,
controller: _toController, controller: _toController,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: "To", labelText: "To",
@ -548,6 +555,7 @@ class _BusScreenState extends State<BusScreen> {
child: TextField( child: TextField(
focusNode: _dateFocusNode, focusNode: _dateFocusNode,
controller: _dateController, controller: _dateController,
readOnly: true, readOnly: true,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: const InputDecoration( decoration: const InputDecoration(
@ -656,6 +664,9 @@ class _BusScreenState extends State<BusScreen> {
child: TextField( child: TextField(
focusNode: _commentsFocusNode, focusNode: _commentsFocusNode,
controller: _buscommentsController, controller: _buscommentsController,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Comments", labelText: "Comments",

View File

@ -1,5 +1,6 @@
import 'package:dropdown_search/dropdown_search.dart'; import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:frontend/services/apiService.dart'; import 'package:frontend/services/apiService.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
@ -2520,6 +2521,9 @@ class FlightScreenState extends State<FlightScreen> {
focusNode: focusNodes["_comments1FocusNode"], focusNode: focusNodes["_comments1FocusNode"],
// controller: _commentsController, // controller: _commentsController,
controller: textControllers["_comments1Controller"], controller: textControllers["_comments1Controller"],
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
// maxLines: 6, // maxLines: 6,
// keyboardType: TextInputType.multiline, // keyboardType: TextInputType.multiline,
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),

View File

@ -1147,6 +1147,11 @@ class _ForexScreenState extends State<ForexScreen> {
child: TextField( child: TextField(
focusNode: focusNodes["_forexStartDate"], focusNode: focusNodes["_forexStartDate"],
controller: textControllers["_forexStartDate"], controller: textControllers["_forexStartDate"],
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
readOnly: true, readOnly: true,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: InputDecoration( decoration: InputDecoration(
@ -1234,6 +1239,11 @@ class _ForexScreenState extends State<ForexScreen> {
child: TextField( child: TextField(
focusNode: focusNodes["_forexEndDate"], focusNode: focusNodes["_forexEndDate"],
controller: textControllers["_forexEndDate"], controller: textControllers["_forexEndDate"],
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
readOnly: true, readOnly: true,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: const InputDecoration( decoration: const InputDecoration(
@ -1678,6 +1688,7 @@ class _ForexScreenState extends State<ForexScreen> {
height: 30, height: 30,
child: TextField( child: TextField(
focusNode: focusNodes["_transport"], focusNode: focusNodes["_transport"],
controller: textControllers["_transport"], controller: textControllers["_transport"],
onChanged: (value) { onChanged: (value) {
setState(() { setState(() {
@ -2232,6 +2243,9 @@ class _ForexScreenState extends State<ForexScreen> {
child: TextField( child: TextField(
focusNode: focusNodes["_comments"], focusNode: focusNodes["_comments"],
controller: textControllers["_comments"], controller: textControllers["_comments"],
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Comments", labelText: "Comments",
@ -2340,6 +2354,11 @@ class _ForexScreenState extends State<ForexScreen> {
onChanged: (value) { onChanged: (value) {
errorMessages.remove("delivery_location"); errorMessages.remove("delivery_location");
}, },
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Location", labelText: "Location",

View File

@ -1,5 +1,6 @@
import 'package:dropdown_search/dropdown_search.dart'; import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:responsive_builder/responsive_builder.dart'; import 'package:responsive_builder/responsive_builder.dart';
@ -1180,7 +1181,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
height: 40, height: 40,
child: TextField( child: TextField(
focusNode: focusNodes["nominee_nameFocusNode"], focusNode: focusNodes["nominee_nameFocusNode"],
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
// focusNode: _nomineeFocusNode, // focusNode: _nomineeFocusNode,
controller: _nomineeController, controller: _nomineeController,
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
@ -1290,6 +1293,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
focusNode: focusNodes["nominee_relationshipFocusNode"], focusNode: focusNodes["nominee_relationshipFocusNode"],
controller: _nomineerelationController, controller: _nomineerelationController,
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Nominee Relationship", labelText: "Nominee Relationship",
labelStyle: TextStyle(fontSize: 12, color: Colors.grey), labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
@ -1340,6 +1346,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
// focusNode: _commentsFocusNode, // focusNode: _commentsFocusNode,
focusNode: focusNodes["commentsFocusNode"], focusNode: focusNodes["commentsFocusNode"],
controller: _insuranceCommentsController, controller: _insuranceCommentsController,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Comments", labelText: "Comments",

View File

@ -1,5 +1,6 @@
import 'package:dropdown_search/dropdown_search.dart'; import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:responsive_builder/responsive_builder.dart'; import 'package:responsive_builder/responsive_builder.dart';
@ -391,12 +392,18 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
if (selectedItem == null || selectedItem.isEmpty) { if (selectedItem == null || selectedItem.isEmpty) {
return Text( return Text(
"Select ", "Select ",
style: GoogleFonts.poppins(color: Colors.grey, fontSize: 13), style: GoogleFonts.poppins(
color: Colors.grey,
fontSize: 13,
),
); );
} }
return Text( return Text(
selectedItem['dropdown_value'] ?? '', selectedItem['dropdown_value'] ?? '',
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
); );
}, },
onChanged: onChanged:
@ -408,7 +415,9 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
print("Updating form data: -> ${newValue ?? ""}"); print("Updating form data: -> ${newValue ?? ""}");
} }
: null, : null,
),),) ),
),
),
), ),
), ),
if (errorMessages["special_request"] != null) ...[ if (errorMessages["special_request"] != null) ...[
@ -443,6 +452,9 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
focusNode: _commentsFocusNode, focusNode: _commentsFocusNode,
controller: _commentsController, controller: _commentsController,
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:responsive_builder/responsive_builder.dart'; import 'package:responsive_builder/responsive_builder.dart';
@ -11,8 +12,12 @@ class ForexScreen extends StatefulWidget {
final Function(String tab, String key, String value) updateFormData; final Function(String tab, String key, String value) updateFormData;
final Function(bool) onClose; final Function(bool) onClose;
ForexScreen({required this.formData, required this.updateFormData, ForexScreen({
required this.onClose, this.apiData}); required this.formData,
required this.updateFormData,
required this.onClose,
this.apiData,
});
@override @override
_ForexScreenState createState() => _ForexScreenState(); _ForexScreenState createState() => _ForexScreenState();
@ -95,57 +100,55 @@ class _ForexScreenState extends State<ForexScreen> {
}); });
}); });
_tripTypeController = TextEditingController(
text: widget.formData["tripType"] ?? "",
_tripTypeController = );
TextEditingController(text: widget.formData["tripType"] ?? ""); _hotelNameController = TextEditingController(
_hotelNameController = text: widget.formData["_hotelName"] ?? "",
TextEditingController(text: widget.formData["_hotelName"] ?? ""); );
_fromController = _fromController = TextEditingController(
TextEditingController(text: widget.formData["_from"] ?? ""); text: widget.formData["_from"] ?? "",
_toController = );
TextEditingController(text: widget.formData["_Check_In_Time"] ?? ""); _toController = TextEditingController(
_dateController = text: widget.formData["_Check_In_Time"] ?? "",
TextEditingController(text: widget.formData["_Check_Out"] ?? ""); );
_endDateController = _dateController = TextEditingController(
TextEditingController(text: widget.formData["_Check_In"] ?? ""); text: widget.formData["_Check_Out"] ?? "",
_timeController = );
TextEditingController(text: widget.formData["_Check_Out_Time"] ?? ""); _endDateController = TextEditingController(
_commentsController = text: widget.formData["_Check_In"] ?? "",
TextEditingController(text: widget.formData["_comments"] ?? ""); );
_timeController = TextEditingController(
text: widget.formData["_Check_Out_Time"] ?? "",
);
_commentsController = TextEditingController(
text: widget.formData["_comments"] ?? "",
);
// Save data when user types // Save data when user types
_tripTypeController.addListener(() { _tripTypeController.addListener(() {
widget.updateFormData( widget.updateFormData("Bus", "_tripType", _tripTypeController.text);
"Bus", "_tripType", _tripTypeController.text);
}); // Save data when user types }); // Save data when user types
_hotelNameController.addListener(() { _hotelNameController.addListener(() {
widget.updateFormData( widget.updateFormData("Bus", "_hotelName", _hotelNameController.text);
"Bus", "_hotelName", _hotelNameController.text);
}); });
_fromController.addListener(() { _fromController.addListener(() {
widget.updateFormData( widget.updateFormData("Bus", "_from", _fromController.text);
"Bus", "_from", _fromController.text);
}); });
_toController.addListener(() { _toController.addListener(() {
widget.updateFormData( widget.updateFormData("Bus", "_Check_In_Time", _toController.text);
"Bus", "_Check_In_Time", _toController.text);
}); });
_dateController.addListener(() { _dateController.addListener(() {
widget.updateFormData( widget.updateFormData("Bus", "_Check_Out", _dateController.text);
"Bus", "_Check_Out", _dateController.text);
}); });
_endDateController.addListener(() { _endDateController.addListener(() {
widget.updateFormData( widget.updateFormData("Bus", "_Check_In", _endDateController.text);
"Bus", "_Check_In", _endDateController.text);
}); });
_timeController.addListener(() { _timeController.addListener(() {
widget.updateFormData( widget.updateFormData("Bus", "_Check_Out_Time", _timeController.text);
"Bus", "_Check_Out_Time", _timeController.text);
}); });
_commentsController.addListener(() { _commentsController.addListener(() {
widget.updateFormData( widget.updateFormData("Bus", "_comments", _commentsController.text);
"Bus", "_comments", _commentsController.text);
}); });
} }
@ -163,13 +166,13 @@ class _ForexScreenState extends State<ForexScreen> {
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
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;
return Container( return Container(
color: Color(0xFFF4F4FB), color: Color(0xFFF4F4FB),
@ -192,24 +195,28 @@ class _ForexScreenState extends State<ForexScreen> {
), ),
), ),
), ),
Text("Forex List", Text(
style: "Forex List",
TextStyle(fontSize: 18, fontWeight: FontWeight.bold,color: Color(0xFF575A74))), style: TextStyle(
SizedBox( fontSize: 18,
height: 6, fontWeight: FontWeight.bold,
color: Color(0xFF575A74),
), ),
),
SizedBox(height: 6),
Padding( Padding(
padding: const EdgeInsets.all(28.0), padding: const EdgeInsets.all(28.0),
child: Center( child: Center(
child: Column(children: _buildAccomadtionForm(isDesktop)), child: Column(children: _buildAccomadtionForm(isDesktop)),
), ),
) ),
], ],
), ),
), ),
), ),
); );
}); },
);
} }
List<Widget> _buildAccomadtionForm(bool isDesktop) { List<Widget> _buildAccomadtionForm(bool isDesktop) {
@ -222,14 +229,12 @@ class _ForexScreenState extends State<ForexScreen> {
List<List<Widget>> rowBuilders = [ List<List<Widget>> rowBuilders = [
_builClassType(isDesktop), _builClassType(isDesktop),
_buildSecondRow(isDesktop) _buildSecondRow(isDesktop),
]; ];
return [ return [
...buildResponsiveRow(_buildFirstRow(isDesktop)), ...buildResponsiveRow(_buildFirstRow(isDesktop)),
// Iterate over rowBuilders and wrap each in a responsive container // Iterate over rowBuilders and wrap each in a responsive container
...rowBuilders.expand((row) => buildResponsiveRow(row)), ...rowBuilders.expand((row) => buildResponsiveRow(row)),
@ -247,21 +252,19 @@ class _ForexScreenState extends State<ForexScreen> {
]; ];
} }
List<Widget> _buildFirstRow(isDesktop) { List<Widget> _buildFirstRow(isDesktop) {
DateTime? _selectedCheckOutDate; DateTime? _selectedCheckOutDate;
DateTime? _selectedEndDate; DateTime? _selectedEndDate;
Future<void> _selectCheckOutDate(BuildContext context) async { Future<void> _selectCheckOutDate(BuildContext context) async {
DateTime now = DateTime.now(); DateTime now = DateTime.now();
DateTime today = DateTime(now.year, now.month, now.day); DateTime today = DateTime(now.year, now.month, now.day);
DateTime? pickedDate = await showDatePicker( DateTime? pickedDate = await showDatePicker(
context: context, context: context,
initialDate: _selectedCheckOutDate != null && _selectedCheckOutDate!.isAfter(today) initialDate:
_selectedCheckOutDate != null &&
_selectedCheckOutDate!.isAfter(today)
? _selectedCheckOutDate! ? _selectedCheckOutDate!
: today, : today,
firstDate: today, firstDate: today,
@ -274,16 +277,18 @@ class _ForexScreenState extends State<ForexScreen> {
_dateController.text = DateFormat('yyyy-MM-dd').format(pickedDate); _dateController.text = DateFormat('yyyy-MM-dd').format(pickedDate);
}); });
} }
}; }
;
Future<void> _selectForexEndDate(BuildContext context) async { Future<void> _selectForexEndDate(BuildContext context) async {
DateTime now = DateTime.now(); DateTime now = DateTime.now();
DateTime today = DateTime(now.year, now.month, now.day); DateTime today = DateTime(now.year, now.month, now.day);
DateTime? pickedDate = await showDatePicker( DateTime? pickedDate = await showDatePicker(
context: context, context: context,
initialDate: _selectedEndDate != null && _selectedEndDate!.isAfter(today) initialDate:
_selectedEndDate != null && _selectedEndDate!.isAfter(today)
? _selectedEndDate! ? _selectedEndDate!
: today, : today,
firstDate: today, firstDate: today,
@ -298,7 +303,6 @@ class _ForexScreenState extends State<ForexScreen> {
} }
} }
return [ return [
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -308,7 +312,8 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldWrapper( CustomTextFieldWrapper(
@ -330,23 +335,20 @@ class _ForexScreenState extends State<ForexScreen> {
floatingLabelBehavior: FloatingLabelBehavior.never, floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none, border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16), contentPadding: EdgeInsets.symmetric(vertical: 16),
suffixIcon: Icon(Icons.calendar_today, suffixIcon: Icon(
size: 16, color: Colors.grey), Icons.calendar_today,
size: 16,
color: Colors.grey,
),
), ),
), ),
), ),
), ),
), ),
), ),
], ],
), ),
if (isDesktop) if (isDesktop) Spacer() else SizedBox(height: 8),
Spacer()
else
SizedBox(
height: 8,
),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -355,7 +357,8 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldWrapper( CustomTextFieldWrapper(
@ -377,46 +380,50 @@ class _ForexScreenState extends State<ForexScreen> {
floatingLabelBehavior: FloatingLabelBehavior.never, floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none, border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16), contentPadding: EdgeInsets.symmetric(vertical: 16),
suffixIcon: Icon(Icons.calendar_today, suffixIcon: Icon(
size: 16, color: Colors.grey), Icons.calendar_today,
size: 16,
color: Colors.grey,
),
), ),
), ),
), ),
), ),
), ),
), ),
], ],
), ),
]; ];
} }
List<Widget> _buildTripType(bool isDesktop) { List<Widget> _buildTripType(bool isDesktop) {
List<dynamic> purposeList = widget.apiData?['flight_trip_type'] ?? []; List<dynamic> purposeList = widget.apiData?['flight_trip_type'] ?? [];
List<DropdownMenuItem<String>> dropdownItems = purposeList List<DropdownMenuItem<String>> dropdownItems =
.map((item)=>DropdownMenuItem<String>( purposeList
.map(
(item) => DropdownMenuItem<String>(
value: item['dropdown_value'], value: item['dropdown_value'],
child: Text(item['dropdown_value']), child: Text(item['dropdown_value']),
)).toList(); ),
)
.toList();
if (dropdownItems.isEmpty) { if (dropdownItems.isEmpty) {
dropdownItems.add( dropdownItems.add(
DropdownMenuItem<String>( DropdownMenuItem<String>(
value: null, value: null,
child: Text("No options available", style: TextStyle(color: Colors.grey)), child: Text(
"No options available",
style: TextStyle(color: Colors.grey),
),
), ),
); );
} }
// Default selected value // Default selected value
String? selectedPurpose = dropdownItems.isNotEmpty ? dropdownItems.first.value : null; String? selectedPurpose =
dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
return [ return [
CustomTextFieldWrapper( CustomTextFieldWrapper(
@ -432,51 +439,62 @@ class _ForexScreenState extends State<ForexScreen> {
decoration: InputDecoration( decoration: InputDecoration(
border: InputBorder.none, border: InputBorder.none,
contentPadding: EdgeInsets.symmetric( contentPadding: EdgeInsets.symmetric(
horizontal: 10), // Proper padding horizontal: 10,
), // Proper padding
), ),
onChanged: purposeList.isNotEmpty onChanged:
purposeList.isNotEmpty
? (newValue) { ? (newValue) {
setState(() { setState(() {
selectedPurpose = newValue; selectedPurpose = newValue;
}); });
print("Updating form data: Flight -> trip_type -> ${newValue ?? ""}"); print(
"Updating form data: Flight -> trip_type -> ${newValue ?? ""}",
);
widget.updateFormData(
widget.updateFormData("Flight", "trip_type", newValue ?? ""); "Flight",
"trip_type",
newValue ?? "",
);
} }
: null, : null,
items: dropdownItems, items: dropdownItems,
), ),
), ),
), ),
]; ];
} }
List<Widget> _builClassType(bool isDesktop) { List<Widget> _builClassType(bool isDesktop) {
List<dynamic> purposeList = widget.apiData?['flight_class'] ?? []; List<dynamic> purposeList = widget.apiData?['flight_class'] ?? [];
List<DropdownMenuItem<String>> dropdownItems = purposeList List<DropdownMenuItem<String>> dropdownItems =
.map((item)=>DropdownMenuItem<String>( purposeList
.map(
(item) => DropdownMenuItem<String>(
value: item['dropdown_value'], value: item['dropdown_value'],
child: Text(item['dropdown_value']), child: Text(item['dropdown_value']),
)).toList(); ),
)
.toList();
if (dropdownItems.isEmpty) { if (dropdownItems.isEmpty) {
dropdownItems.add( dropdownItems.add(
DropdownMenuItem<String>( DropdownMenuItem<String>(
value: null, value: null,
child: Text("No options available", style: TextStyle(color: Colors.grey)), child: Text(
"No options available",
style: TextStyle(color: Colors.grey),
),
), ),
); );
} }
// Default selected value // Default selected value
String? selectedPurpose = dropdownItems.isNotEmpty ? dropdownItems.first.value : null; String? selectedPurpose =
dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
return [ return [
Column( Column(
@ -487,7 +505,8 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldWrapper( CustomTextFieldWrapper(
@ -504,9 +523,11 @@ class _ForexScreenState extends State<ForexScreen> {
decoration: InputDecoration( decoration: InputDecoration(
border: InputBorder.none, border: InputBorder.none,
contentPadding: EdgeInsets.symmetric( contentPadding: EdgeInsets.symmetric(
horizontal: 10), // Proper padding horizontal: 10,
), // Proper padding
), ),
onChanged: purposeList.isNotEmpty onChanged:
purposeList.isNotEmpty
? (newValue) { ? (newValue) {
setState(() { setState(() {
selectedPurpose = newValue; selectedPurpose = newValue;
@ -535,10 +556,8 @@ class _ForexScreenState extends State<ForexScreen> {
]; ];
} }
List<Widget> _buildSecondRow(bool isDesktop) { List<Widget> _buildSecondRow(bool isDesktop) {
return [ return [
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -547,15 +566,20 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper( CustomTextFieldItnerarySubWrapper(
isFocused: _fromFocus, isFocused: _fromFocus,
isDesktop: isDesktop, isDesktop: isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
],
focusNode: _fromFocusNode, focusNode: _fromFocusNode,
controller: _fromController, controller: _fromController,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
@ -565,19 +589,13 @@ class _ForexScreenState extends State<ForexScreen> {
floatingLabelBehavior: FloatingLabelBehavior.never, floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none, border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16), contentPadding: EdgeInsets.symmetric(vertical: 16),
), ),
), ),
), ),
), ),
], ],
), ),
if (isDesktop) if (isDesktop) Spacer() else SizedBox(height: 8),
Spacer()
else
SizedBox(
height: 8,
),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -586,7 +604,8 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper( CustomTextFieldItnerarySubWrapper(
@ -611,12 +630,7 @@ class _ForexScreenState extends State<ForexScreen> {
), ),
], ],
), ),
if (isDesktop) if (isDesktop) Spacer() else SizedBox(height: 8),
Spacer()
else
SizedBox(
height: 8,
),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -625,7 +639,8 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper( CustomTextFieldItnerarySubWrapper(
@ -643,19 +658,13 @@ class _ForexScreenState extends State<ForexScreen> {
floatingLabelBehavior: FloatingLabelBehavior.never, floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none, border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16), contentPadding: EdgeInsets.symmetric(vertical: 16),
), ),
), ),
), ),
), ),
], ],
), ),
if (isDesktop) if (isDesktop) Spacer() else SizedBox(height: 8),
Spacer()
else
SizedBox(
height: 8,
),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -664,7 +673,8 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper( CustomTextFieldItnerarySubWrapper(
@ -680,7 +690,11 @@ class _ForexScreenState extends State<ForexScreen> {
"Rs ", "Rs ",
// focusNode: _toFocusNode, // focusNode: _toFocusNode,
// controller: _toController, // controller: _toController,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w600,color: Color(0xFF575A74)), style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w600,
color: Color(0xFF575A74),
),
// decoration: const InputDecoration( // decoration: const InputDecoration(
// labelText: "To", // labelText: "To",
// labelStyle: TextStyle(fontSize: 12, color: Colors.grey), // labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
@ -694,34 +708,38 @@ class _ForexScreenState extends State<ForexScreen> {
), ),
], ],
), ),
]; ];
} }
List<Widget> _buildCardDetailsRow(bool isDesktop) { List<Widget> _buildCardDetailsRow(bool isDesktop) {
List<dynamic> purposeList = widget.apiData?['flight_class'] ?? []; List<dynamic> purposeList = widget.apiData?['flight_class'] ?? [];
List<DropdownMenuItem<String>> dropdownItems = purposeList List<DropdownMenuItem<String>> dropdownItems =
.map((item)=>DropdownMenuItem<String>( purposeList
.map(
(item) => DropdownMenuItem<String>(
value: item['dropdown_value'], value: item['dropdown_value'],
child: Text(item['dropdown_value']), child: Text(item['dropdown_value']),
)).toList(); ),
)
.toList();
if (dropdownItems.isEmpty) { if (dropdownItems.isEmpty) {
dropdownItems.add( dropdownItems.add(
DropdownMenuItem<String>( DropdownMenuItem<String>(
value: null, value: null,
child: Text("No options available", style: TextStyle(color: Colors.grey)), child: Text(
"No options available",
style: TextStyle(color: Colors.grey),
),
), ),
); );
} }
// Default selected value // Default selected value
String? selectedPurpose = dropdownItems.isNotEmpty ? dropdownItems.first.value : null; String? selectedPurpose =
dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
return [ return [
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -730,7 +748,8 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper( CustomTextFieldItnerarySubWrapper(
@ -748,7 +767,6 @@ class _ForexScreenState extends State<ForexScreen> {
floatingLabelBehavior: FloatingLabelBehavior.never, floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none, border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16), contentPadding: EdgeInsets.symmetric(vertical: 16),
), ),
), ),
), ),
@ -756,12 +774,7 @@ class _ForexScreenState extends State<ForexScreen> {
], ],
), ),
if (isDesktop) if (isDesktop) Spacer() else SizedBox(height: 8),
Spacer()
else
SizedBox(
height: 8,
),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -770,7 +783,8 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper( CustomTextFieldItnerarySubWrapper(
@ -787,9 +801,11 @@ class _ForexScreenState extends State<ForexScreen> {
decoration: InputDecoration( decoration: InputDecoration(
border: InputBorder.none, border: InputBorder.none,
contentPadding: EdgeInsets.symmetric( contentPadding: EdgeInsets.symmetric(
horizontal: 10), // Proper padding horizontal: 10,
), // Proper padding
), ),
onChanged: purposeList.isNotEmpty onChanged:
purposeList.isNotEmpty
? (newValue) { ? (newValue) {
setState(() { setState(() {
selectedPurpose = newValue; selectedPurpose = newValue;
@ -802,12 +818,7 @@ class _ForexScreenState extends State<ForexScreen> {
), ),
], ],
), ),
if (isDesktop) if (isDesktop) Spacer() else SizedBox(height: 8),
Spacer()
else
SizedBox(
height: 8,
),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -816,7 +827,8 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper( CustomTextFieldItnerarySubWrapper(
@ -841,12 +853,7 @@ class _ForexScreenState extends State<ForexScreen> {
), ),
], ],
), ),
if (isDesktop) if (isDesktop) Spacer() else SizedBox(height: 8),
Spacer()
else
SizedBox(
height: 8,
),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -855,7 +862,8 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper( CustomTextFieldItnerarySubWrapper(
@ -873,16 +881,12 @@ class _ForexScreenState extends State<ForexScreen> {
floatingLabelBehavior: FloatingLabelBehavior.never, floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none, border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16), contentPadding: EdgeInsets.symmetric(vertical: 16),
), ),
), ),
), ),
), ),
], ],
), ),
]; ];
} }
@ -896,13 +900,15 @@ class _ForexScreenState extends State<ForexScreen> {
style: TextStyle( style: TextStyle(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
color: Color(0xFF575A74)), color: Color(0xFF575A74),
),
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldWrapper( CustomTextFieldWrapper(
isFocused: _commentsFocus, // Dropdown doesn't use focus isFocused: _commentsFocus, // Dropdown doesn't use focus
isDesktop: isDesktop, isDesktop: isDesktop,
width: isDesktop width:
isDesktop
? MediaQuery.of(context).size.width * 0.4 ? MediaQuery.of(context).size.width * 0.4
: MediaQuery.of(context).size.width * 0.66, : MediaQuery.of(context).size.width * 0.66,
child: TextField( child: TextField(
@ -921,7 +927,7 @@ class _ForexScreenState extends State<ForexScreen> {
), ),
), ),
], ],
) ),
]; ];
} }
@ -944,10 +950,14 @@ class _ForexScreenState extends State<ForexScreen> {
), ),
Text( Text(
"Check If You Don't Have a forex Account", "Check If You Don't Have a forex Account",
style: TextStyle(fontSize: 12, fontWeight: FontWeight.w600, color: Color(0xFF575A74)), style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Color(0xFF575A74),
),
), ),
], ],
) ),
]; ];
} }
@ -960,9 +970,7 @@ class _ForexScreenState extends State<ForexScreen> {
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: Colors.grey[400], // Light grey color backgroundColor: Colors.grey[400], // Light grey color
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
borderRadius: BorderRadius.circular(8),
),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
), ),
child: Text( child: Text(
@ -971,7 +979,6 @@ class _ForexScreenState extends State<ForexScreen> {
), ),
), ),
SizedBox(width: 10), // Space between buttons SizedBox(width: 10), // Space between buttons
// Save Changes Button // Save Changes Button
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: () {
@ -979,9 +986,7 @@ class _ForexScreenState extends State<ForexScreen> {
}, },
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue, // Primary color for save backgroundColor: Colors.blue, // Primary color for save
shape: RoundedRectangleBorder( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
borderRadius: BorderRadius.circular(8),
),
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12), padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
), ),
child: Text( child: Text(

View File

@ -348,6 +348,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
child: TextField( child: TextField(
focusNode: _numPassengerFocusNode, focusNode: _numPassengerFocusNode,
controller: _numPassengerController, controller: _numPassengerController,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
keyboardType: TextInputType.numberWithOptions(decimal: true), keyboardType: TextInputType.numberWithOptions(decimal: true),
inputFormatters: [ inputFormatters: [
@ -850,6 +851,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
focusNode: _destinationFocusNode, focusNode: _destinationFocusNode,
controller: _destinationController, controller: _destinationController,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: "Destination", labelText: "Destination",
labelStyle: TextStyle(fontSize: 12, color: Colors.grey), labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
@ -888,6 +892,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
focusNode: _locationFocusNode, focusNode: _locationFocusNode,
controller: _locationController, controller: _locationController,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: "Pickup Location", labelText: "Pickup Location",
labelStyle: TextStyle(fontSize: 12, color: Colors.grey), labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
@ -932,6 +939,11 @@ class _TaxiScreenState extends State<TaxiScreen> {
child: TextField( child: TextField(
focusNode: _dateFocusNode, focusNode: _dateFocusNode,
controller: _dateController, controller: _dateController,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
readOnly: true, readOnly: true,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: const InputDecoration( decoration: const InputDecoration(
@ -985,6 +997,11 @@ class _TaxiScreenState extends State<TaxiScreen> {
child: TextField( child: TextField(
focusNode: _timeFocusNode, focusNode: _timeFocusNode,
controller: _timeController, controller: _timeController,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
readOnly: true, readOnly: true,
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: const InputDecoration( decoration: const InputDecoration(
@ -1045,6 +1062,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
focusNode: _commentsFocusNode, focusNode: _commentsFocusNode,
controller: _taxiCommentsController, controller: _taxiCommentsController,
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Comments", labelText: "Comments",
labelStyle: TextStyle(fontSize: 12, color: Colors.grey), labelStyle: TextStyle(fontSize: 12, color: Colors.grey),

View File

@ -1,5 +1,6 @@
import 'package:dropdown_search/dropdown_search.dart'; import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:responsive_builder/responsive_builder.dart'; import 'package:responsive_builder/responsive_builder.dart';
@ -466,6 +467,9 @@ class _TrainScreenState extends State<TrainScreen> {
focusNode: _trainNoFocusNode, focusNode: _trainNoFocusNode,
controller: _trainNoController, controller: _trainNoController,
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
],
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Train number", labelText: "Train number",
labelStyle: TextStyle(fontSize: 12, color: Colors.grey), labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
@ -1356,6 +1360,9 @@ class _TrainScreenState extends State<TrainScreen> {
// maxLines: 6, // maxLines: 6,
// keyboardType: TextInputType.multiline, // keyboardType: TextInputType.multiline,
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Comments", labelText: "Comments",
labelStyle: TextStyle(fontSize: 12, color: Colors.grey), labelStyle: TextStyle(fontSize: 12, color: Colors.grey),

View File

@ -1,5 +1,6 @@
import 'package:dropdown_search/dropdown_search.dart'; import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:responsive_builder/responsive_builder.dart'; import 'package:responsive_builder/responsive_builder.dart';
@ -576,7 +577,9 @@ class _VisaScreenState extends State<VisaScreen> {
itemBuilder: (context, item, isSelected) { itemBuilder: (context, item, isSelected) {
print("contryItem - $item"); print("contryItem - $item");
final match = RegExp(r'^(.*)\s\((.*)\)$').firstMatch(item); final match = RegExp(
r'^(.*)\s\((.*)\)$',
).firstMatch(item);
final countryName = match?.group(1) ?? ''; final countryName = match?.group(1) ?? '';
final countryCode = match?.group(2) ?? ''; final countryCode = match?.group(2) ?? '';
return Container( return Container(
@ -663,7 +666,9 @@ class _VisaScreenState extends State<VisaScreen> {
.key; .key;
}); });
}, },
),),), ),
),
),
), ),
), ),
if (errorMessages["country_code"] != null) ...[ if (errorMessages["country_code"] != null) ...[
@ -794,7 +799,10 @@ class _VisaScreenState extends State<VisaScreen> {
), ),
), ),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: layoutColor, width: 0.5), borderSide: BorderSide(
color: layoutColor,
width: 0.5,
),
), ),
contentPadding: EdgeInsets.symmetric( contentPadding: EdgeInsets.symmetric(
horizontal: 10, horizontal: 10,
@ -837,7 +845,9 @@ class _VisaScreenState extends State<VisaScreen> {
}); });
} }
: null, : null,
),),), ),
),
),
), ),
), ),
if (errorMessages["type_of_visa"] != null) ...[ if (errorMessages["type_of_visa"] != null) ...[
@ -933,6 +943,9 @@ class _VisaScreenState extends State<VisaScreen> {
child: TextField( child: TextField(
focusNode: _commentsFocusNode, focusNode: _commentsFocusNode,
controller: _visaCommentsController, controller: _visaCommentsController,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Comments", labelText: "Comments",

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:io' as io show Directory, File; import 'dart:io' as io show Directory, File;
import 'package:delta_to_html/delta_to_html.dart'; import 'package:delta_to_html/delta_to_html.dart';
import 'package:flutter/cupertino.dart' as dom; import 'package:flutter/cupertino.dart' as dom;
import 'package:flutter/services.dart';
import 'package:flutter_quill/flutter_quill.dart' hide Text; import 'package:flutter_quill/flutter_quill.dart' hide Text;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart' hide Text; import 'package:flutter_quill/flutter_quill.dart' hide Text;
@ -636,6 +637,9 @@ class TemplateState extends State<Template> {
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["subjectFocusNode"], focusNode: focusNodes["subjectFocusNode"],
controller: controllers["subject"], controller: controllers["subject"],
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
onChanged: (value) { onChanged: (value) {
// _clearError("local_id_num"); // _clearError("local_id_num");
}, },

View File

@ -4,6 +4,7 @@ import 'dart:async';
import 'dart:io' as io show Directory, File; import 'dart:io' as io show Directory, File;
import 'package:delta_to_html/delta_to_html.dart'; import 'package:delta_to_html/delta_to_html.dart';
import 'package:flutter/cupertino.dart' as dom; import 'package:flutter/cupertino.dart' as dom;
import 'package:flutter/services.dart';
import 'package:flutter_quill/flutter_quill.dart' hide Text; import 'package:flutter_quill/flutter_quill.dart' hide Text;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_quill/flutter_quill.dart' hide Text; import 'package:flutter_quill/flutter_quill.dart' hide Text;
@ -754,6 +755,9 @@ class TemplateForexState extends State<TemplateForex> {
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["subjectFocusNode"], focusNode: focusNodes["subjectFocusNode"],
controller: controllers["subject"], controller: controllers["subject"],
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
onChanged: (value) { onChanged: (value) {
// _clearError("local_id_num"); // _clearError("local_id_num");
}, },

View File

@ -1,5 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:frontend/services/apiService.dart'; import 'package:frontend/services/apiService.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -332,6 +333,9 @@ class _MailSettingState extends State<MailSetting> {
height: 40, height: 40,
child: TextField( child: TextField(
// focusNode: _destinationFocusNode, // focusNode: _destinationFocusNode,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
focusNode: focusNodes["userNameFocusNode"], focusNode: focusNodes["userNameFocusNode"],
controller: controllers["userName"], controller: controllers["userName"],
onChanged: (value) { onChanged: (value) {
@ -577,6 +581,7 @@ class _MailSettingState extends State<MailSetting> {
child: TextField( child: TextField(
// focusNode: _destinationFocusNode, // focusNode: _destinationFocusNode,
focusNode: focusNodes["portFocusNode"], focusNode: focusNodes["portFocusNode"],
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
controller: controllers["port"], controller: controllers["port"],
onChanged: (value) { onChanged: (value) {
_clearError("mail_port"); _clearError("mail_port");

View File

@ -1,7 +1,9 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:frontend/Screens/organization/mailSettings.dart'; import 'package:frontend/Screens/organization/mailSettings.dart';
import 'package:frontend/Screens/organization/themeColor.dart'; import 'package:frontend/Screens/organization/themeColor.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
@ -652,6 +654,45 @@ class _OrgSetUpState extends State<OrgSetUp> {
Future<void> _pickImage() async { Future<void> _pickImage() async {
final picker = ImagePicker(); final picker = ImagePicker();
final XFile? pickedFile = await picker.pickImage(
source: ImageSource.gallery,
// For web: allow only specific file types
// This only works on web
preferredCameraDevice: CameraDevice.rear, // optional
);
if (pickedFile != null) {
// Check the file extension manually
final allowedExtensions = ['jpg', 'jpeg', 'png'];
final fileExtension = pickedFile.name.split('.').last.toLowerCase();
if (!allowedExtensions.contains(fileExtension)) {
print('❌ Invalid file type. Please select a JPG or PNG image.');
return;
}
if (kIsWeb) {
try {
final bytes = await pickedFile.readAsBytes();
print('✅ Image loaded, size: ${bytes.length} bytes');
setState(() {
_imageBytes = bytes;
});
} catch (e) {
print('❌ Error reading image bytes: $e');
}
} else {
// Handle mobile image if needed
print('✅ Image picked: ${pickedFile.path}');
}
} else {
print('⚠️ Image picking canceled.');
}
}
Future<void> _pickImage2() async {
final picker = ImagePicker();
final XFile? pickedFile = await picker.pickImage( final XFile? pickedFile = await picker.pickImage(
source: ImageSource.gallery, source: ImageSource.gallery,
); );
@ -772,7 +813,11 @@ class _OrgSetUpState extends State<OrgSetUp> {
Expanded( Expanded(
child: TextFormField( child: TextFormField(
controller: _orgNameController, controller: _orgNameController,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
fontSize: 16, fontSize: 16,
color: Color(0xFF114D8B), color: Color(0xFF114D8B),
@ -787,6 +832,7 @@ class _OrgSetUpState extends State<OrgSetUp> {
FloatingLabelBehavior.never, FloatingLabelBehavior.never,
border: InputBorder.none, border: InputBorder.none,
isDense: true, isDense: true,
// contentPadding: // contentPadding:
// EdgeInsets.symmetric(vertical: 14), // EdgeInsets.symmetric(vertical: 14),
), ),
@ -794,6 +840,8 @@ class _OrgSetUpState extends State<OrgSetUp> {
), ),
), ),
Spacer(), Spacer(),
Column(
children: [
GestureDetector( GestureDetector(
onTap: _pickImage, onTap: _pickImage,
@ -828,7 +876,10 @@ class _OrgSetUpState extends State<OrgSetUp> {
return const CircleAvatar( return const CircleAvatar(
radius: 20, radius: 20,
backgroundColor: Colors.redAccent, backgroundColor: Colors.redAccent,
child: Icon(Icons.error, size: 10), child: Icon(
Icons.error,
size: 10,
),
); );
}, },
), ),
@ -836,9 +887,28 @@ class _OrgSetUpState extends State<OrgSetUp> {
: const CircleAvatar( : const CircleAvatar(
radius: 20, radius: 20,
backgroundColor: Colors.amber, backgroundColor: Colors.amber,
child: Icon(Icons.add_a_photo, size: 10), child: Icon(
Icons.add_a_photo,
size: 10,
), ),
), ),
),
SizedBox(
// width: 200,
child: Text(
"* Allow types jpg, jpeg, png",
// maxLines: 2,
// softWrap: true,
style: GoogleFonts.poppins(
fontSize: 9,
fontWeight: FontWeight.w400,
color: Colors.grey,
),
),
),
],
),
], ],
), ),
), ),

View File

@ -865,6 +865,7 @@ class ForexDataState extends State<ForexData> {
focusNode: focusNodes["perdiemAmountFocusNode"], focusNode: focusNodes["perdiemAmountFocusNode"],
controller: controllers["perdiemAmount"], controller: controllers["perdiemAmount"],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: "Perdiem Amount", labelText: "Perdiem Amount",
labelStyle: TextStyle(fontSize: 11, color: Colors.grey), labelStyle: TextStyle(fontSize: 11, color: Colors.grey),

View File

@ -3222,6 +3222,11 @@ class CreateNewPlansState extends State<CreateNewPlan> {
focusNode: focusNodes["so_numberFocusNode"], focusNode: focusNodes["so_numberFocusNode"],
controller: _soNumberController, controller: _soNumberController,
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
decoration: InputDecoration( decoration: InputDecoration(
labelText: "SO Number", labelText: "SO Number",
labelStyle: TextStyle(fontSize: 12, color: Colors.grey), labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
@ -3416,6 +3421,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
TextField( TextField(
controller: _excepntldescriptionController, controller: _excepntldescriptionController,
maxLines: 3, maxLines: 3,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
],
decoration: InputDecoration( decoration: InputDecoration(
hintText: "Enter reason...", hintText: "Enter reason...",
hintStyle: GoogleFonts.poppins(fontSize: 10), hintStyle: GoogleFonts.poppins(fontSize: 10),
@ -3510,6 +3518,11 @@ class CreateNewPlansState extends State<CreateNewPlan> {
child: SizedBox( child: SizedBox(
height: 55, height: 55,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
focusNode: focusNodes["excepntldescriptionFocusNode"], focusNode: focusNodes["excepntldescriptionFocusNode"],
controller: _excepntldescriptionController, controller: _excepntldescriptionController,
maxLines: 2, maxLines: 2,
@ -3610,6 +3623,12 @@ class CreateNewPlansState extends State<CreateNewPlan> {
focusNode: focusNodes["descriptionFocusNode"], focusNode: focusNodes["descriptionFocusNode"],
controller: _descriptionController, controller: _descriptionController,
maxLines: 2, maxLines: 2,
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
keyboardType: TextInputType.multiline, keyboardType: TextInputType.multiline,
style: TextStyle(fontSize: 12), style: TextStyle(fontSize: 12),
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
@ -3743,6 +3762,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
color: Colors.black, color: Colors.black,
), ),
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Trip Name *", labelText: "Trip Name *",
labelStyle: GoogleFonts.poppins( labelStyle: GoogleFonts.poppins(
@ -4278,19 +4298,36 @@ class CreateNewPlansState extends State<CreateNewPlan> {
selectedIstravelUser = isTraveller; selectedIstravelUser = isTraveller;
}); });
print("USer entered : $otherUserName $userId $isTraveller"); print("USer entered : $otherUserName $userId $isTraveller");
print('---UserSelectionDialog');
// NOTE : Traveller use same trip token for self user,
// Trip Token changed for Other Employee -Selects userId should pass
if (isTraveller) { if (isTraveller) {
await apiService.handleTripWiseToken( print('---TRAVELLER');
selfId!, print('---TRAVELLER- $userId');
context, fetchUserDetails();
); // since userId is for traveller _selectedTripType = null;
getSelectedPlanFor();
fetchUsrDtlFromSelectedTripUser();
dynamicItineraryKey.currentState?.loadOrgSelectedAlServices();
dynamicItineraryKey.currentState?.updateSelectedServices();
// await apiService.handleTripWiseToken(
// // selfId!,
// userId,
// context,
// ); // since userId is for traveller
} else { } else {
print('---NONTRAVELLER');
print('---NONTRAVELLER $userId');
await apiService.handleTripWiseToken( await apiService.handleTripWiseToken(
userId, userId,
context, context,
); // fallback to selfId ); // fallback to selfId
} }
print('UserSelectionDialog-1');
getSelectedPlanFor(); getSelectedPlanFor();
print('UserSelectionDialog-2');
fetchUsrDtlFromSelectedTripUser(); fetchUsrDtlFromSelectedTripUser();
dynamicItineraryKey.currentState?.loadOrgSelectedAlServices(); dynamicItineraryKey.currentState?.loadOrgSelectedAlServices();

View File

@ -59,7 +59,7 @@ class _ListPlansState extends State<ListPlans> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
print("LSIT PLan -1");
_checkAuthAndLoadData(); _checkAuthAndLoadData();
checkbackbutton(); checkbackbutton();
@ -69,6 +69,7 @@ class _ListPlansState extends State<ListPlans> {
} }
void checkbackbutton() async { void checkbackbutton() async {
print("LSIT PLan -3");
roleUser = await getRoleUser(); roleUser = await getRoleUser();
print(roleUser); print(roleUser);
if (roleUser == "User") { if (roleUser == "User") {
@ -79,6 +80,14 @@ class _ListPlansState extends State<ListPlans> {
print("msUser - $msUser"); print("msUser - $msUser");
html.window.history.pushState(null, '', html.window.location.href); html.window.history.pushState(null, '', html.window.location.href);
print("locationLP - $location");
// if (location!.contains('/listPlan')) {
// // Do nothing or show "Press again to exit" toast
// print("Blocked back on /listPlan");
// } else {
// print("/listPlan ..");
// }
if (!msUser) { if (!msUser) {
_popStateListener = html.window.onPopState.listen((event) { _popStateListener = html.window.onPopState.listen((event) {
if (!_dialogShown && mounted) { if (!_dialogShown && mounted) {
@ -99,6 +108,7 @@ class _ListPlansState extends State<ListPlans> {
} }
void _showBackConfirmationDialog() { void _showBackConfirmationDialog() {
print('List planstt');
if (!mounted) return; if (!mounted) return;
_dialogShown = true; _dialogShown = true;
@ -144,11 +154,12 @@ class _ListPlansState extends State<ListPlans> {
} }
void _checkAuthAndLoadData() async { void _checkAuthAndLoadData() async {
print("LSIT PLan -2");
final String? token = await getToken(); // Your async function to get token final String? token = await getToken(); // Your async function to get token
if (token == null || token.isEmpty) { if (token == null || token.isEmpty) {
// Token doesn't exist → redirect to login // Token doesn't exist → redirect to login
// apiService.logout(context);
context.go( context.go(
"/", "/",
); // or use: router.go("/") if you're using `GoRouter` directly ); // or use: router.go("/") if you're using `GoRouter` directly
@ -358,7 +369,7 @@ class _ListPlansState extends State<ListPlans> {
} }
} }
void deletePlan(String planId) async { void deletePlan(String planId, userId) async {
// try { // try {
// Map<String, dynamic> planData = await ApiService.getViewPlan(planId); // Map<String, dynamic> planData = await ApiService.getViewPlan(planId);
// print("ViewAAA - $planData"); // print("ViewAAA - $planData");
@ -377,6 +388,7 @@ class _ListPlansState extends State<ListPlans> {
try { try {
Map<String, dynamic> planData = await ApiService().getViewPlan( Map<String, dynamic> planData = await ApiService().getViewPlan(
planId, planId,
userId,
context, context,
); );
print("ViewAAA - $planData"); print("ViewAAA - $planData");
@ -1255,6 +1267,7 @@ class _ListPlansState extends State<ListPlans> {
); );
deletePlan( deletePlan(
plan.planId, plan.planId,
userId,
); );
}, },
), ),
@ -1601,6 +1614,7 @@ class _ListPlansState extends State<ListPlans> {
); );
deletePlan( deletePlan(
plan.planId, plan.planId,
userId,
); );
}, },
), ),

View File

@ -5,6 +5,7 @@ import 'dart:ui' as html;
import 'dart:async'; import 'dart:async';
import 'dart:html' as html; import 'dart:html' as html;
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'dart:ui' as web; import 'dart:ui' as web;
@ -953,6 +954,9 @@ class _PolicyState extends State<Policy> {
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12), style: GoogleFonts.poppins(fontSize: 12),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
focusNode: focusNodes["policyFocusNode"], focusNode: focusNodes["policyFocusNode"],
controller: _policyController, controller: _policyController,
onChanged: (value) => _clearError("name"), onChanged: (value) => _clearError("name"),

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:dropdown_search/dropdown_search.dart'; import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -3798,6 +3799,11 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12), style: GoogleFonts.poppins(fontSize: 12),
controller: costController[ServiceId], controller: costController[ServiceId],
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
// enabled: !isViewMode, // enabled: !isViewMode,
onChanged: (value) { onChanged: (value) {
printData(); printData();

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -311,6 +312,11 @@ class PurposeOfTravelDataState extends State<PurposeOfTravelData> {
child: TextField( child: TextField(
controller: controllers["dropdown_value"], controller: controllers["dropdown_value"],
focusNode: focusNodes["dropdown_valueFocusNode"], focusNode: focusNodes["dropdown_valueFocusNode"],
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
decoration: const InputDecoration( decoration: const InputDecoration(
labelText: "Name", labelText: "Name",

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -340,6 +341,11 @@ class TravellerDataState extends State<TravellerData> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
controller: controllers["first_name"], controller: controllers["first_name"],
focusNode: focusNodes["first_nameFocusNode"], focusNode: focusNodes["first_nameFocusNode"],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),
@ -385,6 +391,11 @@ class TravellerDataState extends State<TravellerData> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(
RegExp(r'[a-zA-Z0-9 _-]'),
),
],
controller: controllers["last_name"], controller: controllers["last_name"],
focusNode: focusNodes["last_nameFocusNode"], focusNode: focusNodes["last_nameFocusNode"],
style: const TextStyle(fontSize: 12), style: const TextStyle(fontSize: 12),

View File

@ -815,6 +815,9 @@ class PersonalDetailsState extends State<PersonalDetails> {
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
focusNode: focusNodes["FnameFocusNode"], focusNode: focusNodes["FnameFocusNode"],
controller: widget.controllers["Fname"], controller: widget.controllers["Fname"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
@ -869,6 +872,9 @@ class PersonalDetailsState extends State<PersonalDetails> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: TextStyle(fontSize: 12, color: Colors.black), style: TextStyle(fontSize: 12, color: Colors.black),
focusNode: focusNodes["LnameFocusNode"], focusNode: focusNodes["LnameFocusNode"],
controller: widget.controllers["Lname"], controller: widget.controllers["Lname"],
@ -916,6 +922,9 @@ class PersonalDetailsState extends State<PersonalDetails> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: TextStyle(fontSize: 12, color: Colors.black), style: TextStyle(fontSize: 12, color: Colors.black),
focusNode: focusNodes["CnameFocusNode"], focusNode: focusNodes["CnameFocusNode"],
controller: widget.controllers["Cname"], controller: widget.controllers["Cname"],

View File

@ -551,6 +551,9 @@ class OfficeDetailsState extends State<OfficeDetails> {
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
focusNode: _employeeCodeFocusNode, focusNode: _employeeCodeFocusNode,
controller: widget.controllers["employeeCode"], controller: widget.controllers["employeeCode"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,

View File

@ -861,6 +861,9 @@ class PersonalDetailsState extends State<PersonalDetails> {
// focusNode: focusNodes["FnameFocusNode"], // focusNode: focusNodes["FnameFocusNode"],
focusNode: _fnameFocusNode, // 👈 Use it here focusNode: _fnameFocusNode, // 👈 Use it here
controller: widget.controllers["Fname"], controller: widget.controllers["Fname"],
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
autofocus: true, autofocus: true,
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
onChanged: (value) { onChanged: (value) {
@ -910,6 +913,9 @@ class PersonalDetailsState extends State<PersonalDetails> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
],
style: TextStyle(fontSize: 12, color: Colors.black), style: TextStyle(fontSize: 12, color: Colors.black),
focusNode: _lnameFocusNode, focusNode: _lnameFocusNode,
autofocus: true, autofocus: true,

View File

@ -1221,6 +1221,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
],
focusNode: focusNodes["FnameFocusNode"], focusNode: focusNodes["FnameFocusNode"],
controller: controllers["Fname"], controller: controllers["Fname"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
@ -1264,6 +1267,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
],
focusNode: focusNodes["MnameFocusNode"], focusNode: focusNodes["MnameFocusNode"],
controller: controllers["Mname"], controller: controllers["Mname"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
@ -1310,6 +1316,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
],
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["LnameFocusNode"], focusNode: focusNodes["LnameFocusNode"],
controller: controllers["Lname"], controller: controllers["Lname"],
@ -1548,6 +1557,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
],
focusNode: focusNodes["placeOfIssueFocusNode"], focusNode: focusNodes["placeOfIssueFocusNode"],
controller: controllers["placeOfIssue"], controller: controllers["placeOfIssue"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
@ -2339,6 +2351,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
controller: controllers["local_id_num"], controller: controllers["local_id_num"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
onChanged: (value) { onChanged: (value) {
_clearError("local_id_num"); _clearError("local_id_num");
}, },
@ -2476,6 +2491,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
controller: controllers["full_name_as_id"], controller: controllers["full_name_as_id"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
onChanged: (value) { onChanged: (value) {
@ -2710,6 +2728,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["d_meal_prefFocusNode"], focusNode: focusNodes["d_meal_prefFocusNode"],
controller: controllers["d_meal_pref"], controller: controllers["d_meal_pref"],
@ -2755,6 +2776,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
controller: controllers["d_additonal_Info"], controller: controllers["d_additonal_Info"],
focusNode: focusNodes["d_additonal_InfoFocusNode"], focusNode: focusNodes["d_additonal_InfoFocusNode"],
@ -2988,7 +3012,11 @@ class TravellerDetailsState extends State<TravellerDetails> {
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
controller: controllers["i_meal_pref"], controller: controllers["i_meal_pref"],
focusNode: focusNodes["i_meal_prefFocusNode"], focusNode: focusNodes["i_meal_prefFocusNode"],
@ -3034,6 +3062,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
controller: controllers["i_additonal_Info"], controller: controllers["i_additonal_Info"],
focusNode: focusNodes["i_additonal_InfoFocusNode"], focusNode: focusNodes["i_additonal_InfoFocusNode"],
@ -3629,6 +3660,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
],
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
controller: entry["controller_flier_number"], controller: entry["controller_flier_number"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
@ -3893,6 +3927,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
],
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
controller: entry["controller_membership"], controller: entry["controller_membership"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,

View File

@ -1,8 +1,11 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:frontend/config/apiUrl.dart'; import 'package:frontend/config/apiUrl.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:image_picker/image_picker.dart';
import 'package:shared_preferences/shared_preferences.dart'; // don't forget import 'package:shared_preferences/shared_preferences.dart'; // don't forget
import '../services/apiService.dart'; import '../services/apiService.dart';
import '../utils/auth_utils.dart'; import '../utils/auth_utils.dart';
@ -37,6 +40,8 @@ class _CustomAppBarState extends State<CustomAppBar> {
late TabSelection selectedTab; late TabSelection selectedTab;
final ImagePicker _picker = ImagePicker();
String? token; String? token;
Map<String, dynamic>? userData; Map<String, dynamic>? userData;
Map<String, dynamic>? fetchedUserData; Map<String, dynamic>? fetchedUserData;
@ -48,6 +53,9 @@ class _CustomAppBarState extends State<CustomAppBar> {
Color? layoutColor = Colors.white10; Color? layoutColor = Colors.white10;
Color? bodyColor; Color? bodyColor;
File? _pickedImageFile;
String? _errorMessage;
void initState() { void initState() {
super.initState(); super.initState();
// initializeData(); // initializeData();
@ -104,6 +112,14 @@ class _CustomAppBarState extends State<CustomAppBar> {
return prefs.getString("auth_token"); return prefs.getString("auth_token");
} }
bool isValidImageUrl(String? url) {
if (url == null) return false;
final lowerUrl = url.toLowerCase();
return lowerUrl.endsWith('.jpg') ||
lowerUrl.endsWith('.jpeg') ||
lowerUrl.endsWith('.png');
}
Future<Map<String, dynamic>?> getUserData() async { Future<Map<String, dynamic>?> getUserData() async {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
final String? userDataString = prefs.getString('user_data'); final String? userDataString = prefs.getString('user_data');

View File

@ -84,7 +84,7 @@ final GoRouter router = GoRouter(
// ); // );
}, },
routes: [ routes: [
GoRoute(path: '/home', builder: (context, state) => HomePage()), // GoRoute(path: '/home', builder: (context, state) => HomePage()),
GoRoute( GoRoute(
path: '/listAllPlan', path: '/listAllPlan',
builder: (context, state) => ListAllPlans(), builder: (context, state) => ListAllPlans(),

View File

@ -36,6 +36,8 @@ class OrganizationSettingState extends State<OrganizationSetting> {
// String? bodyStringColor = await getBodyColor(); // String? bodyStringColor = await getBodyColor();
roleUser = await getRoleUser(); roleUser = await getRoleUser();
if (roleUser == 'Org Admin' || roleUser == 'Travel Admin') {
setState(() { setState(() {
layoutColor = layoutColor =
layoutString != null layoutString != null
@ -56,6 +58,9 @@ class OrganizationSettingState extends State<OrganizationSetting> {
// ? Color(int.parse(bodyStringColor)) // ? Color(int.parse(bodyStringColor))
// : Colors.white; // : Colors.white;
}); });
} else {
apiService.logout(context);
}
} }
@override @override

View File

@ -743,9 +743,11 @@ class ApiService {
Future<Map<String, dynamic>> getViewPlan( Future<Map<String, dynamic>> getViewPlan(
String planId, String planId,
userId,
BuildContext context, BuildContext context,
) async { ) async {
final String apiUrldata = '$apiUrl/api/plans/cancle_plan?plan_id=$planId'; final String apiUrldata =
'$apiUrl/api/plans/cancle_plan?plan_id=$planId&updated_by=$userId';
// final String apiUrldata = '$apiUrl/api/plans/find/$planId'; // final String apiUrldata = '$apiUrl/api/plans/find/$planId';
print("API URL: $apiUrldata"); print("API URL: $apiUrldata");