ui_input_formatters
This commit is contained in:
parent
52878d6810
commit
aaff31e8d4
@ -204,7 +204,8 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
Future<List<Plan>> fetchPlans() async {
|
||||
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") {
|
||||
// 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(
|
||||
context,
|
||||
layoutColor,
|
||||
@ -293,6 +294,7 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
try {
|
||||
Map<String, dynamic> planData = await ApiService().getViewPlan(
|
||||
planId,
|
||||
userId,
|
||||
context,
|
||||
);
|
||||
print("ViewAAA - $planData");
|
||||
@ -1135,6 +1137,7 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
);
|
||||
deletePlan(
|
||||
plan.planId,
|
||||
userId,
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -1455,6 +1458,7 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
);
|
||||
deletePlan(
|
||||
plan.planId,
|
||||
userId,
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@ -143,14 +143,17 @@ class _TripInformationState extends State<TripInformation> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
keyValueRow("Action", item["action"]),
|
||||
keyValueRow("Approver", item["approver"]),
|
||||
keyValueRow("Action", item["action"] ?? '-'),
|
||||
keyValueRow("Approver", item["approver"] ?? '-'),
|
||||
keyValueRow(
|
||||
"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"]),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -364,6 +364,7 @@ class _TravelAgentListPlansState extends State<TravelAgentListPlans> {
|
||||
try {
|
||||
Map<String, dynamic> planData = await ApiService().getViewPlan(
|
||||
planId,
|
||||
userId,
|
||||
context,
|
||||
);
|
||||
print("ViewAAA - $planData");
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
Future<dynamic> showApprovalDialog(
|
||||
BuildContext context,
|
||||
@ -115,6 +116,11 @@ Future<dynamic> showApprovalDialog(
|
||||
TextField(
|
||||
style: TextStyle(fontFamily: "Inter", fontSize: 14),
|
||||
maxLines: 3,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
onChanged: (value) => remarks = value,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Remarks...",
|
||||
@ -263,8 +269,14 @@ Future<String?> showRejectDialog1(
|
||||
const Text("Please enter reason for rejection."),
|
||||
const SizedBox(height: 10),
|
||||
TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
maxLines: 3,
|
||||
onChanged: (value) => remarks = value,
|
||||
|
||||
decoration: const InputDecoration(
|
||||
hintText: "Remarks...",
|
||||
hintStyle: TextStyle(
|
||||
|
||||
@ -256,7 +256,7 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
}
|
||||
}
|
||||
|
||||
void deletePlan(String planId) async {
|
||||
void deletePlan(String planId, userId) async {
|
||||
// try {
|
||||
// Map<String, dynamic> planData = await getViewPlan(planId);
|
||||
// print("ViewAAA - $planData");
|
||||
@ -275,6 +275,7 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
try {
|
||||
Map<String, dynamic> planData = await ApiService().getViewPlan(
|
||||
planId,
|
||||
userId,
|
||||
context,
|
||||
);
|
||||
print("ViewAAA - $planData");
|
||||
@ -1207,6 +1208,7 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
);
|
||||
deletePlan(
|
||||
plan.planId,
|
||||
userId,
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@ -4,6 +4,7 @@ import 'dart:html' as html;
|
||||
import 'package:encrypt/encrypt.dart' as encrypt;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:frontend/config/apiUrl.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
@ -580,6 +581,7 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
_buildLabel("Email Address"),
|
||||
TextFormField(
|
||||
controller: _emailController,
|
||||
inputFormatters: [],
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 11,
|
||||
|
||||
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
@ -314,6 +315,11 @@ class CostCenterDataState extends State<CostCenterData> {
|
||||
child: TextField(
|
||||
controller: controllers["name"],
|
||||
focusNode: focusNodes["nameFocusNode"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Name",
|
||||
@ -356,6 +362,11 @@ class CostCenterDataState extends State<CostCenterData> {
|
||||
child: TextField(
|
||||
controller: controllers["description"],
|
||||
focusNode: focusNodes["descriptionFocusNode"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
maxLines: null,
|
||||
expands: true,
|
||||
|
||||
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
@ -313,6 +314,11 @@ class DepartmentDataState extends State<DepartmentData> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
controller: controllers["dropdown_value"],
|
||||
focusNode: focusNodes["dropdown_valueFocusNode"],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
|
||||
@ -320,6 +320,7 @@ class DepartmentListState extends State<DepartmentList> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: searchController,
|
||||
|
||||
onChanged: filterDepartment,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search ...",
|
||||
|
||||
@ -176,11 +176,6 @@ class _UserSelectionDialogState extends State<UserSelectionDialog> {
|
||||
await apiService.logout(context);
|
||||
return null;
|
||||
// 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 {
|
||||
throw Exception(
|
||||
'Failed to load users. Status Code: ${response.statusCode}',
|
||||
|
||||
@ -4,6 +4,7 @@ import 'dart:io';
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:frontend/Screens/organization/mailSettings.dart';
|
||||
import 'package:frontend/Screens/organization/themeColor.dart';
|
||||
import 'package:frontend/utils/auth_utils.dart';
|
||||
@ -481,6 +482,9 @@ class _groupState extends State<Group> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: controllers["name"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: TextStyle(fontSize: 12),
|
||||
onChanged: (value) {
|
||||
_clearError("name");
|
||||
@ -527,6 +531,9 @@ class _groupState extends State<Group> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: controllers["description"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
onChanged: (value) {
|
||||
_clearError("description");
|
||||
},
|
||||
|
||||
@ -426,7 +426,11 @@ class GroupDataState extends State<GroupData> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["nameFocusNode"],
|
||||
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
controller: controllers["name"],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
@ -779,7 +783,11 @@ class GroupDataState extends State<GroupData> {
|
||||
child: TextField(
|
||||
controller: controllers["description"],
|
||||
focusNode: focusNodes["descriptionFocusNode"],
|
||||
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
maxLines: null,
|
||||
expands: true,
|
||||
|
||||
@ -372,6 +372,11 @@ class HotelsDataState extends State<HotelsData> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["hotel_nameFocusNode"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
controller: controllers["hotel_name"],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
@ -415,6 +420,11 @@ class HotelsDataState extends State<HotelsData> {
|
||||
child: TextField(
|
||||
focusNode: focusNodes["hotel_chainFocusNode"],
|
||||
controller: controllers["hotel_chain"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Hotel Chain",
|
||||
@ -458,9 +468,10 @@ class HotelsDataState extends State<HotelsData> {
|
||||
child: TextField(
|
||||
focusNode: focusNodes["categoryFocusNode"],
|
||||
controller: controllers["category"],
|
||||
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 ]'),
|
||||
RegExp(r'[a-z A-Z0-9 ]'),
|
||||
),
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
@ -665,6 +676,11 @@ class HotelsDataState extends State<HotelsData> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["cityFocusNode"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
controller: controllers["city"],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
|
||||
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
@ -379,6 +380,11 @@ class HotelsDataListState extends State<HotelsDataList> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: searchController,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
onChanged: filterHotels,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search ...",
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
@ -664,6 +665,9 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
focusNode: _destinationFocusNode,
|
||||
controller: _destinationController,
|
||||
style: TextStyle(fontSize: 12),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
labelText: "Destination",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
@ -1503,6 +1507,9 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
child: TextField(
|
||||
focusNode: _commentsFocusNode,
|
||||
controller: _commentsController,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Comments",
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
@ -466,6 +467,9 @@ class _BusScreenState extends State<BusScreen> {
|
||||
focusNode: _fromFocusNode,
|
||||
controller: _fromController,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
decoration: const InputDecoration(
|
||||
labelText: "From",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
@ -503,6 +507,9 @@ class _BusScreenState extends State<BusScreen> {
|
||||
child: TextField(
|
||||
focusNode: _toFocusNode,
|
||||
controller: _toController,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "To",
|
||||
@ -548,6 +555,7 @@ class _BusScreenState extends State<BusScreen> {
|
||||
child: TextField(
|
||||
focusNode: _dateFocusNode,
|
||||
controller: _dateController,
|
||||
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
@ -656,6 +664,9 @@ class _BusScreenState extends State<BusScreen> {
|
||||
child: TextField(
|
||||
focusNode: _commentsFocusNode,
|
||||
controller: _buscommentsController,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Comments",
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:frontend/services/apiService.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@ -2520,6 +2521,9 @@ class FlightScreenState extends State<FlightScreen> {
|
||||
focusNode: focusNodes["_comments1FocusNode"],
|
||||
// controller: _commentsController,
|
||||
controller: textControllers["_comments1Controller"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
// maxLines: 6,
|
||||
// keyboardType: TextInputType.multiline,
|
||||
style: TextStyle(fontSize: 12),
|
||||
|
||||
@ -1147,6 +1147,11 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_forexStartDate"],
|
||||
controller: textControllers["_forexStartDate"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
@ -1234,6 +1239,11 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_forexEndDate"],
|
||||
controller: textControllers["_forexEndDate"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
@ -1678,6 +1688,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
height: 30,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_transport"],
|
||||
|
||||
controller: textControllers["_transport"],
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
@ -2232,6 +2243,9 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_comments"],
|
||||
controller: textControllers["_comments"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Comments",
|
||||
@ -2340,6 +2354,11 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
onChanged: (value) {
|
||||
errorMessages.remove("delivery_location");
|
||||
},
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Location",
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
@ -1180,7 +1181,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["nominee_nameFocusNode"],
|
||||
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
// focusNode: _nomineeFocusNode,
|
||||
controller: _nomineeController,
|
||||
style: TextStyle(fontSize: 12),
|
||||
@ -1290,6 +1293,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
||||
focusNode: focusNodes["nominee_relationshipFocusNode"],
|
||||
controller: _nomineerelationController,
|
||||
style: TextStyle(fontSize: 12),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
labelText: "Nominee Relationship",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
@ -1340,6 +1346,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
||||
// focusNode: _commentsFocusNode,
|
||||
focusNode: focusNodes["commentsFocusNode"],
|
||||
controller: _insuranceCommentsController,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Comments",
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
@ -125,9 +126,9 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
||||
|
||||
setState(() {
|
||||
layoutColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(layoutString))
|
||||
: Colors.redAccent;
|
||||
layoutString != null
|
||||
? Color(int.parse(layoutString))
|
||||
: Colors.redAccent;
|
||||
});
|
||||
}
|
||||
|
||||
@ -309,106 +310,114 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: null,//MediaQuery.of(context).size.width * 0.66,
|
||||
: null, //MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
child: Focus(
|
||||
focusNode: _hotelNameFocusNode,
|
||||
onFocusChange: (hasFocus) {
|
||||
setState(() {
|
||||
_hotelNameFocused = hasFocus;
|
||||
});
|
||||
child: Focus(
|
||||
focusNode: _hotelNameFocusNode,
|
||||
onFocusChange: (hasFocus) {
|
||||
setState(() {
|
||||
_hotelNameFocused = hasFocus;
|
||||
});
|
||||
},
|
||||
child: GestureDetector(
|
||||
//
|
||||
onTap: () {
|
||||
// Request focus when user taps
|
||||
_hotelNameFocusNode?.requestFocus();
|
||||
},
|
||||
child: GestureDetector(
|
||||
//
|
||||
onTap: () {
|
||||
// Request focus when user taps
|
||||
_hotelNameFocusNode?.requestFocus();
|
||||
},
|
||||
child: DropdownSearch<Map<String, dynamic>>(
|
||||
// focusNode: _taxiReqFocusNode,
|
||||
items: purposeList.cast<Map<String, dynamic>>(),
|
||||
selectedItem: purposeList.firstWhere(
|
||||
(item) => item['dropdown_key'] == selectedSpecialType,
|
||||
orElse: () => {},
|
||||
),
|
||||
itemAsString: (item) => item['dropdown_value'] ?? '',
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: false,
|
||||
fit: FlexFit.loose,
|
||||
menuProps: const MenuProps(backgroundColor: Colors.white),
|
||||
itemBuilder: (context, item, isSelected) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 5,
|
||||
child: DropdownSearch<Map<String, dynamic>>(
|
||||
// focusNode: _taxiReqFocusNode,
|
||||
items: purposeList.cast<Map<String, dynamic>>(),
|
||||
selectedItem: purposeList.firstWhere(
|
||||
(item) => item['dropdown_key'] == selectedSpecialType,
|
||||
orElse: () => {},
|
||||
),
|
||||
itemAsString: (item) => item['dropdown_value'] ?? '',
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: false,
|
||||
fit: FlexFit.loose,
|
||||
menuProps: const MenuProps(backgroundColor: Colors.white),
|
||||
itemBuilder: (context, item, isSelected) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 5,
|
||||
),
|
||||
child: Text(
|
||||
item['dropdown_value'] ?? '',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
// border: InputBorder.none,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_hotelNameFocused ?? false)
|
||||
? layoutColor!
|
||||
: Colors.white,
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_hotelNameFocused ?? false)
|
||||
? layoutColor
|
||||
: Colors.white,
|
||||
// : const Color(0xFFD6D5E6),
|
||||
width: 0.5,
|
||||
// const Color(0xFFD6D5E6),
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: layoutColor, width: 0.5),
|
||||
),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 10,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
item['dropdown_value'] ?? '',
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) {
|
||||
if (selectedItem == null || selectedItem.isEmpty) {
|
||||
return Text(
|
||||
"Select ",
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.grey,
|
||||
fontSize: 13,
|
||||
),
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
selectedItem['dropdown_value'] ?? '',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
// border: InputBorder.none,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_hotelNameFocused ?? false)
|
||||
? layoutColor!
|
||||
: Colors.white,
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_hotelNameFocused ?? false)
|
||||
? layoutColor
|
||||
: Colors.white,
|
||||
// : const Color(0xFFD6D5E6),
|
||||
width: 0.5,
|
||||
// const Color(0xFFD6D5E6),
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: layoutColor, width: 0.5),
|
||||
),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 10,
|
||||
),
|
||||
);
|
||||
},
|
||||
onChanged:
|
||||
purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedSpecialType = newValue as String?;
|
||||
});
|
||||
print("Updating form data: -> ${newValue ?? ""}");
|
||||
}
|
||||
: null,
|
||||
),
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) {
|
||||
if (selectedItem == null || selectedItem.isEmpty) {
|
||||
return Text(
|
||||
"Select ",
|
||||
style: GoogleFonts.poppins(color: Colors.grey, fontSize: 13),
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
selectedItem['dropdown_value'] ?? '',
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
);
|
||||
},
|
||||
onChanged:
|
||||
purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedSpecialType = newValue as String?;
|
||||
});
|
||||
print("Updating form data: -> ${newValue ?? ""}");
|
||||
}
|
||||
: null,
|
||||
),),)
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["special_request"] != null) ...[
|
||||
@ -439,10 +448,13 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: null,//MediaQuery.of(context).size.width * 0.66,
|
||||
: null, //MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
focusNode: _commentsFocusNode,
|
||||
controller: _commentsController,
|
||||
style: TextStyle(fontSize: 12),
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:intl/intl.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(bool) onClose;
|
||||
|
||||
ForexScreen({required this.formData, required this.updateFormData,
|
||||
required this.onClose, this.apiData});
|
||||
ForexScreen({
|
||||
required this.formData,
|
||||
required this.updateFormData,
|
||||
required this.onClose,
|
||||
this.apiData,
|
||||
});
|
||||
|
||||
@override
|
||||
_ForexScreenState createState() => _ForexScreenState();
|
||||
@ -95,57 +100,55 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
_tripTypeController =
|
||||
TextEditingController(text: widget.formData["tripType"] ?? "");
|
||||
_hotelNameController =
|
||||
TextEditingController(text: widget.formData["_hotelName"] ?? "");
|
||||
_fromController =
|
||||
TextEditingController(text: widget.formData["_from"] ?? "");
|
||||
_toController =
|
||||
TextEditingController(text: widget.formData["_Check_In_Time"] ?? "");
|
||||
_dateController =
|
||||
TextEditingController(text: widget.formData["_Check_Out"] ?? "");
|
||||
_endDateController =
|
||||
TextEditingController(text: widget.formData["_Check_In"] ?? "");
|
||||
_timeController =
|
||||
TextEditingController(text: widget.formData["_Check_Out_Time"] ?? "");
|
||||
_commentsController =
|
||||
TextEditingController(text: widget.formData["_comments"] ?? "");
|
||||
_tripTypeController = TextEditingController(
|
||||
text: widget.formData["tripType"] ?? "",
|
||||
);
|
||||
_hotelNameController = TextEditingController(
|
||||
text: widget.formData["_hotelName"] ?? "",
|
||||
);
|
||||
_fromController = TextEditingController(
|
||||
text: widget.formData["_from"] ?? "",
|
||||
);
|
||||
_toController = TextEditingController(
|
||||
text: widget.formData["_Check_In_Time"] ?? "",
|
||||
);
|
||||
_dateController = TextEditingController(
|
||||
text: widget.formData["_Check_Out"] ?? "",
|
||||
);
|
||||
_endDateController = TextEditingController(
|
||||
text: widget.formData["_Check_In"] ?? "",
|
||||
);
|
||||
_timeController = TextEditingController(
|
||||
text: widget.formData["_Check_Out_Time"] ?? "",
|
||||
);
|
||||
_commentsController = TextEditingController(
|
||||
text: widget.formData["_comments"] ?? "",
|
||||
);
|
||||
|
||||
// Save data when user types
|
||||
_tripTypeController.addListener(() {
|
||||
widget.updateFormData(
|
||||
"Bus", "_tripType", _tripTypeController.text);
|
||||
widget.updateFormData("Bus", "_tripType", _tripTypeController.text);
|
||||
}); // Save data when user types
|
||||
_hotelNameController.addListener(() {
|
||||
widget.updateFormData(
|
||||
"Bus", "_hotelName", _hotelNameController.text);
|
||||
widget.updateFormData("Bus", "_hotelName", _hotelNameController.text);
|
||||
});
|
||||
_fromController.addListener(() {
|
||||
widget.updateFormData(
|
||||
"Bus", "_from", _fromController.text);
|
||||
widget.updateFormData("Bus", "_from", _fromController.text);
|
||||
});
|
||||
_toController.addListener(() {
|
||||
widget.updateFormData(
|
||||
"Bus", "_Check_In_Time", _toController.text);
|
||||
widget.updateFormData("Bus", "_Check_In_Time", _toController.text);
|
||||
});
|
||||
_dateController.addListener(() {
|
||||
widget.updateFormData(
|
||||
"Bus", "_Check_Out", _dateController.text);
|
||||
widget.updateFormData("Bus", "_Check_Out", _dateController.text);
|
||||
});
|
||||
_endDateController.addListener(() {
|
||||
widget.updateFormData(
|
||||
"Bus", "_Check_In", _endDateController.text);
|
||||
widget.updateFormData("Bus", "_Check_In", _endDateController.text);
|
||||
});
|
||||
_timeController.addListener(() {
|
||||
widget.updateFormData(
|
||||
"Bus", "_Check_Out_Time", _timeController.text);
|
||||
widget.updateFormData("Bus", "_Check_Out_Time", _timeController.text);
|
||||
});
|
||||
_commentsController.addListener(() {
|
||||
widget.updateFormData(
|
||||
"Bus", "_comments", _commentsController.text);
|
||||
widget.updateFormData("Bus", "_comments", _commentsController.text);
|
||||
});
|
||||
}
|
||||
|
||||
@ -163,56 +166,60 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ResponsiveBuilder(builder: (context, sizingInfo) {
|
||||
bool isMobile = sizingInfo.isMobile;
|
||||
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInfo) {
|
||||
bool isMobile = sizingInfo.isMobile;
|
||||
bool isDesktop =
|
||||
sizingInfo.deviceScreenType == DeviceScreenType.desktop;
|
||||
|
||||
return Container(
|
||||
color: Color(0xFFF4F4FB),
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
widget.onClose(false);
|
||||
},
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
size: 18,
|
||||
return Container(
|
||||
color: Color(0xFFF4F4FB),
|
||||
child: Form(
|
||||
key: _formKey,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Align(
|
||||
alignment: Alignment.centerRight,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
widget.onClose(false);
|
||||
},
|
||||
child: Icon(
|
||||
Icons.close,
|
||||
size: 18,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Forex List",
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
),
|
||||
Text("Forex List",
|
||||
style:
|
||||
TextStyle(fontSize: 18, fontWeight: FontWeight.bold,color: Color(0xFF575A74))),
|
||||
SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(28.0),
|
||||
child: Center(
|
||||
child: Column(children: _buildAccomadtionForm(isDesktop)),
|
||||
SizedBox(height: 6),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(28.0),
|
||||
child: Center(
|
||||
child: Column(children: _buildAccomadtionForm(isDesktop)),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> _buildAccomadtionForm (bool isDesktop) {
|
||||
List<Widget> _buildAccomadtionForm(bool isDesktop) {
|
||||
List<Widget> buildResponsiveRow(List<Widget> children) {
|
||||
return [
|
||||
isDesktop ? Row(children: children) : Column(children: children),
|
||||
@ -222,14 +229,12 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
|
||||
List<List<Widget>> rowBuilders = [
|
||||
_builClassType(isDesktop),
|
||||
_buildSecondRow(isDesktop)
|
||||
_buildSecondRow(isDesktop),
|
||||
];
|
||||
|
||||
return [
|
||||
|
||||
...buildResponsiveRow(_buildFirstRow(isDesktop)),
|
||||
|
||||
|
||||
// Iterate over rowBuilders and wrap each in a responsive container
|
||||
...rowBuilders.expand((row) => buildResponsiveRow(row)),
|
||||
|
||||
@ -247,23 +252,21 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
List<Widget> _buildFirstRow(isDesktop) {
|
||||
|
||||
DateTime? _selectedCheckOutDate;
|
||||
DateTime? _selectedEndDate;
|
||||
|
||||
|
||||
Future<void> _selectCheckOutDate(BuildContext context) async {
|
||||
DateTime now = DateTime.now();
|
||||
DateTime today = DateTime(now.year, now.month, now.day);
|
||||
|
||||
DateTime? pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: _selectedCheckOutDate != null && _selectedCheckOutDate!.isAfter(today)
|
||||
? _selectedCheckOutDate!
|
||||
: today,
|
||||
initialDate:
|
||||
_selectedCheckOutDate != null &&
|
||||
_selectedCheckOutDate!.isAfter(today)
|
||||
? _selectedCheckOutDate!
|
||||
: today,
|
||||
firstDate: today,
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
@ -274,18 +277,20 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
_dateController.text = DateFormat('yyyy-MM-dd').format(pickedDate);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
Future<void> _selectForexEndDate(BuildContext context) async {
|
||||
|
||||
DateTime now = DateTime.now();
|
||||
DateTime today = DateTime(now.year, now.month, now.day);
|
||||
|
||||
DateTime? pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: _selectedEndDate != null && _selectedEndDate!.isAfter(today)
|
||||
? _selectedEndDate!
|
||||
: today,
|
||||
initialDate:
|
||||
_selectedEndDate != null && _selectedEndDate!.isAfter(today)
|
||||
? _selectedEndDate!
|
||||
: today,
|
||||
firstDate: today,
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
@ -298,7 +303,6 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -306,9 +310,10 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
Text(
|
||||
"Forex Start Date",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
@ -330,32 +335,30 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: Icon(Icons.calendar_today,
|
||||
size: 16, color: Colors.grey),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Forex End Date",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
@ -377,46 +380,50 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: Icon(Icons.calendar_today,
|
||||
size: 16, color: Colors.grey),
|
||||
suffixIcon: Icon(
|
||||
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<DropdownMenuItem<String>> dropdownItems = purposeList
|
||||
.map((item)=>DropdownMenuItem<String>(
|
||||
value: item['dropdown_value'],
|
||||
child: Text(item['dropdown_value']),
|
||||
)).toList();
|
||||
List<DropdownMenuItem<String>> dropdownItems =
|
||||
purposeList
|
||||
.map(
|
||||
(item) => DropdownMenuItem<String>(
|
||||
value: item['dropdown_value'],
|
||||
child: Text(item['dropdown_value']),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
||||
if (dropdownItems.isEmpty) {
|
||||
dropdownItems.add(
|
||||
DropdownMenuItem<String>(
|
||||
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
|
||||
String? selectedPurpose = dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
|
||||
|
||||
String? selectedPurpose =
|
||||
dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
|
||||
|
||||
return [
|
||||
CustomTextFieldWrapper(
|
||||
@ -432,51 +439,62 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 10), // Proper padding
|
||||
horizontal: 10,
|
||||
), // Proper padding
|
||||
),
|
||||
onChanged: purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedPurpose = newValue;
|
||||
});
|
||||
print("Updating form data: Flight -> trip_type -> ${newValue ?? ""}");
|
||||
onChanged:
|
||||
purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedPurpose = newValue;
|
||||
});
|
||||
print(
|
||||
"Updating form data: Flight -> trip_type -> ${newValue ?? ""}",
|
||||
);
|
||||
|
||||
|
||||
widget.updateFormData("Flight", "trip_type", newValue ?? "");
|
||||
}
|
||||
: null,
|
||||
widget.updateFormData(
|
||||
"Flight",
|
||||
"trip_type",
|
||||
newValue ?? "",
|
||||
);
|
||||
}
|
||||
: null,
|
||||
|
||||
items: dropdownItems,
|
||||
),
|
||||
|
||||
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
List<Widget> _builClassType(bool isDesktop){
|
||||
|
||||
List<Widget> _builClassType(bool isDesktop) {
|
||||
List<dynamic> purposeList = widget.apiData?['flight_class'] ?? [];
|
||||
|
||||
List<DropdownMenuItem<String>> dropdownItems = purposeList
|
||||
.map((item)=>DropdownMenuItem<String>(
|
||||
value: item['dropdown_value'],
|
||||
child: Text(item['dropdown_value']),
|
||||
)).toList();
|
||||
List<DropdownMenuItem<String>> dropdownItems =
|
||||
purposeList
|
||||
.map(
|
||||
(item) => DropdownMenuItem<String>(
|
||||
value: item['dropdown_value'],
|
||||
child: Text(item['dropdown_value']),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
||||
if (dropdownItems.isEmpty) {
|
||||
dropdownItems.add(
|
||||
DropdownMenuItem<String>(
|
||||
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
|
||||
String? selectedPurpose = dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
|
||||
String? selectedPurpose =
|
||||
dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
|
||||
|
||||
return [
|
||||
Column(
|
||||
@ -485,9 +503,10 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
Text(
|
||||
"Class *",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
@ -504,15 +523,17 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 10), // Proper padding
|
||||
horizontal: 10,
|
||||
), // Proper padding
|
||||
),
|
||||
onChanged: purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedPurpose = newValue;
|
||||
});
|
||||
}
|
||||
: null,
|
||||
onChanged:
|
||||
purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedPurpose = newValue;
|
||||
});
|
||||
}
|
||||
: null,
|
||||
items: dropdownItems,
|
||||
),
|
||||
|
||||
@ -535,27 +556,30 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
List<Widget> _buildSecondRow(bool isDesktop) {
|
||||
return [
|
||||
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Transport",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: _fromFocus,
|
||||
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
|
||||
],
|
||||
focusNode: _fromFocusNode,
|
||||
controller: _fromController,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
@ -565,28 +589,23 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Accomodation",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
@ -611,21 +630,17 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Telephone",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
@ -633,7 +648,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
child: TextField(
|
||||
focusNode: _fromFocusNode,
|
||||
controller: _fromController,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
@ -643,34 +658,29 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Other Expenses",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: _toFocus,
|
||||
isDesktop: isDesktop,
|
||||
color:Colors.transparent,
|
||||
color: Colors.transparent,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
|
||||
@ -680,7 +690,11 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
"Rs ",
|
||||
// focusNode: _toFocusNode,
|
||||
// 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(
|
||||
// labelText: "To",
|
||||
// labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
@ -694,43 +708,48 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
List<Widget> _buildCardDetailsRow(bool isDesktop) {
|
||||
|
||||
List<dynamic> purposeList = widget.apiData?['flight_class'] ?? [];
|
||||
|
||||
List<DropdownMenuItem<String>> dropdownItems = purposeList
|
||||
.map((item)=>DropdownMenuItem<String>(
|
||||
value: item['dropdown_value'],
|
||||
child: Text(item['dropdown_value']),
|
||||
)).toList();
|
||||
List<DropdownMenuItem<String>> dropdownItems =
|
||||
purposeList
|
||||
.map(
|
||||
(item) => DropdownMenuItem<String>(
|
||||
value: item['dropdown_value'],
|
||||
child: Text(item['dropdown_value']),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
|
||||
if (dropdownItems.isEmpty) {
|
||||
dropdownItems.add(
|
||||
DropdownMenuItem<String>(
|
||||
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
|
||||
String? selectedPurpose = dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
|
||||
String? selectedPurpose =
|
||||
dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
|
||||
return [
|
||||
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Card Number*",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
@ -738,7 +757,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
child: TextField(
|
||||
focusNode: _fromFocusNode,
|
||||
controller: _fromController,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
@ -748,7 +767,6 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -756,21 +774,17 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
],
|
||||
),
|
||||
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Currency*",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
@ -787,36 +801,34 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 10), // Proper padding
|
||||
horizontal: 10,
|
||||
), // Proper padding
|
||||
),
|
||||
onChanged: purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedPurpose = newValue;
|
||||
});
|
||||
}
|
||||
: null,
|
||||
onChanged:
|
||||
purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedPurpose = newValue;
|
||||
});
|
||||
}
|
||||
: null,
|
||||
items: dropdownItems,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Card*",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
@ -841,21 +853,17 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
if (isDesktop) Spacer() else SizedBox(height: 8),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Cash*",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
@ -863,7 +871,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
child: TextField(
|
||||
focusNode: _fromFocusNode,
|
||||
controller: _fromController,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
@ -873,16 +881,12 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
@ -894,17 +898,19 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
Text(
|
||||
"Delivery Location",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: _commentsFocus, // Dropdown doesn't use focus
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.4
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.4
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
child: TextField(
|
||||
focusNode: _commentsFocusNode,
|
||||
controller: _commentsController,
|
||||
@ -921,7 +927,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@ -944,10 +950,14 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
Text(
|
||||
"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(
|
||||
backgroundColor: Colors.grey[400], // Light grey color
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
),
|
||||
child: Text(
|
||||
@ -971,7 +979,6 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10), // Space between buttons
|
||||
|
||||
// Save Changes Button
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
@ -979,9 +986,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
},
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.blue, // Primary color for save
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
),
|
||||
child: Text(
|
||||
@ -991,4 +996,4 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -348,6 +348,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
child: TextField(
|
||||
focusNode: _numPassengerFocusNode,
|
||||
controller: _numPassengerController,
|
||||
|
||||
style: const TextStyle(fontSize: 12),
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
@ -850,6 +851,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
focusNode: _destinationFocusNode,
|
||||
controller: _destinationController,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Destination",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
@ -888,6 +892,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
focusNode: _locationFocusNode,
|
||||
controller: _locationController,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Pickup Location",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
@ -932,6 +939,11 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
child: TextField(
|
||||
focusNode: _dateFocusNode,
|
||||
controller: _dateController,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
@ -985,6 +997,11 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
child: TextField(
|
||||
focusNode: _timeFocusNode,
|
||||
controller: _timeController,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
@ -1045,6 +1062,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
focusNode: _commentsFocusNode,
|
||||
controller: _taxiCommentsController,
|
||||
style: TextStyle(fontSize: 12),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
labelText: "Comments",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
@ -466,6 +467,9 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
focusNode: _trainNoFocusNode,
|
||||
controller: _trainNoController,
|
||||
style: TextStyle(fontSize: 12),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
labelText: "Train number",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
@ -1356,6 +1360,9 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
// maxLines: 6,
|
||||
// keyboardType: TextInputType.multiline,
|
||||
style: TextStyle(fontSize: 12),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
labelText: "Comments",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
@ -163,9 +164,9 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
|
||||
setState(() {
|
||||
layoutColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(layoutString))
|
||||
: Colors.redAccent;
|
||||
layoutString != null
|
||||
? Color(int.parse(layoutString))
|
||||
: Colors.redAccent;
|
||||
});
|
||||
}
|
||||
|
||||
@ -549,7 +550,7 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
width:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
: null,//MediaQuery.of(context).size.width * 0.66,
|
||||
: null, //MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: Focus(
|
||||
@ -566,104 +567,108 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
// Request focus when user taps
|
||||
_countryFocusNode?.requestFocus();
|
||||
},
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem: countryMap[selectedCountry],
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true,
|
||||
fit: FlexFit.loose,
|
||||
constraints: BoxConstraints(maxHeight: 200),
|
||||
menuProps: const MenuProps(backgroundColor: Colors.white),
|
||||
itemBuilder: (context, item, isSelected) {
|
||||
print("contryItem - $item");
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem: countryMap[selectedCountry],
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true,
|
||||
fit: FlexFit.loose,
|
||||
constraints: BoxConstraints(maxHeight: 200),
|
||||
menuProps: const MenuProps(backgroundColor: Colors.white),
|
||||
itemBuilder: (context, item, isSelected) {
|
||||
print("contryItem - $item");
|
||||
|
||||
final match = RegExp(r'^(.*)\s\((.*)\)$').firstMatch(item);
|
||||
final countryName = match?.group(1) ?? '';
|
||||
final countryCode = match?.group(2) ?? '';
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 6,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 1.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
countryName,
|
||||
style: GoogleFonts.poppins(fontSize: 11.5),
|
||||
final match = RegExp(
|
||||
r'^(.*)\s\((.*)\)$',
|
||||
).firstMatch(item);
|
||||
final countryName = match?.group(1) ?? '';
|
||||
final countryCode = match?.group(2) ?? '';
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 6,
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(right: 1.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
countryName,
|
||||
style: GoogleFonts.poppins(fontSize: 11.5),
|
||||
),
|
||||
Text(
|
||||
countryCode,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11.5,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Text(
|
||||
countryCode,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11.5,
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search ...",
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
items: countryMap.values.toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
// border: InputBorder.none,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_countryFocused ?? false)
|
||||
? layoutColor!
|
||||
: Colors.white,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_countryFocused ?? false)
|
||||
? layoutColor
|
||||
: Colors.white,
|
||||
// : const Color(0xFFD6D5E6),
|
||||
width: 1,
|
||||
// const Color(0xFFD6D5E6),
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: layoutColor, width: 1),
|
||||
),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
dropdownBuilder:
|
||||
(context, selectedItem) => Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
);
|
||||
},
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search ...",
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
selectedCountry =
|
||||
countryMap.entries
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
});
|
||||
},
|
||||
),),),
|
||||
items: countryMap.values.toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
// border: InputBorder.none,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_countryFocused ?? false)
|
||||
? layoutColor!
|
||||
: Colors.white,
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_countryFocused ?? false)
|
||||
? layoutColor
|
||||
: Colors.white,
|
||||
// : const Color(0xFFD6D5E6),
|
||||
width: 1,
|
||||
// const Color(0xFFD6D5E6),
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: layoutColor, width: 1),
|
||||
),
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
dropdownBuilder:
|
||||
(context, selectedItem) => Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
selectedCountry =
|
||||
countryMap.entries
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["country_code"] != null) ...[
|
||||
@ -729,115 +734,120 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
child: Focus(
|
||||
focusNode: _tripTypeFocusNode,
|
||||
onFocusChange: (hasFocus) {
|
||||
setState(() {
|
||||
_tripTypeFocused = hasFocus;
|
||||
});
|
||||
child: Focus(
|
||||
focusNode: _tripTypeFocusNode,
|
||||
onFocusChange: (hasFocus) {
|
||||
setState(() {
|
||||
_tripTypeFocused = hasFocus;
|
||||
});
|
||||
},
|
||||
child: GestureDetector(
|
||||
//
|
||||
onTap: () {
|
||||
// Request focus when user taps
|
||||
_tripTypeFocusNode?.requestFocus();
|
||||
},
|
||||
child: GestureDetector(
|
||||
//
|
||||
onTap: () {
|
||||
// Request focus when user taps
|
||||
_tripTypeFocusNode?.requestFocus();
|
||||
},
|
||||
child: DropdownSearch<Map<String, dynamic>>(
|
||||
items: purposeList.cast<Map<String, dynamic>>(),
|
||||
selectedItem: purposeList.firstWhere(
|
||||
(item) => item['dropdown_key'] == selectedPurpose,
|
||||
orElse: () => {},
|
||||
),
|
||||
itemAsString: (item) => item['dropdown_value'] ?? '',
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: false,
|
||||
fit: FlexFit.loose,
|
||||
menuProps: const MenuProps(backgroundColor: Colors.white),
|
||||
itemBuilder: (context, item, isSelected) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 5,
|
||||
child: DropdownSearch<Map<String, dynamic>>(
|
||||
items: purposeList.cast<Map<String, dynamic>>(),
|
||||
selectedItem: purposeList.firstWhere(
|
||||
(item) => item['dropdown_key'] == selectedPurpose,
|
||||
orElse: () => {},
|
||||
),
|
||||
itemAsString: (item) => item['dropdown_value'] ?? '',
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: false,
|
||||
fit: FlexFit.loose,
|
||||
menuProps: const MenuProps(backgroundColor: Colors.white),
|
||||
itemBuilder: (context, item, isSelected) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 5,
|
||||
),
|
||||
child: Text(
|
||||
item['dropdown_value'] ?? '',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
// border: InputBorder.none,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_tripTypeFocused ?? false)
|
||||
? layoutColor!
|
||||
: Colors.white,
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_tripTypeFocused ?? false)
|
||||
? layoutColor
|
||||
: Colors.white,
|
||||
// : const Color(0xFFD6D5E6),
|
||||
width: 0.5,
|
||||
// const Color(0xFFD6D5E6),
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: layoutColor,
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 10,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
item['dropdown_value'] ?? '',
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) {
|
||||
if (selectedItem == null || selectedItem.isEmpty) {
|
||||
return Text(
|
||||
"Select ",
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.grey,
|
||||
fontSize: 13,
|
||||
),
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
selectedItem['dropdown_value'] ?? '',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
// border: InputBorder.none,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_tripTypeFocused ?? false)
|
||||
? layoutColor!
|
||||
: Colors.white,
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_tripTypeFocused ?? false)
|
||||
? layoutColor
|
||||
: Colors.white,
|
||||
// : const Color(0xFFD6D5E6),
|
||||
width: 0.5,
|
||||
// const Color(0xFFD6D5E6),
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: layoutColor, width: 0.5),
|
||||
),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 10,
|
||||
),
|
||||
);
|
||||
},
|
||||
// focusNode: _tripTypeFocusNode, // Assign the correct focus node
|
||||
// value: selectedPurpose,
|
||||
// style: TextStyle(fontSize: 12),
|
||||
// decoration: InputDecoration(
|
||||
// border: InputBorder.none,
|
||||
// contentPadding:
|
||||
// EdgeInsets.symmetric(horizontal: 10), // Proper padding
|
||||
// ),
|
||||
onChanged:
|
||||
purposeList.isNotEmpty
|
||||
? (Map<String, dynamic>? newValue) {
|
||||
setState(() {
|
||||
selectedPurpose = newValue?['dropdown_key'];
|
||||
print("Selected Purpose: ${selectedPurpose}");
|
||||
});
|
||||
}
|
||||
: null,
|
||||
),
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) {
|
||||
if (selectedItem == null || selectedItem.isEmpty) {
|
||||
return Text(
|
||||
"Select ",
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.grey,
|
||||
fontSize: 13,
|
||||
),
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
selectedItem['dropdown_value'] ?? '',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
);
|
||||
},
|
||||
// focusNode: _tripTypeFocusNode, // Assign the correct focus node
|
||||
// value: selectedPurpose,
|
||||
// style: TextStyle(fontSize: 12),
|
||||
// decoration: InputDecoration(
|
||||
// border: InputBorder.none,
|
||||
// contentPadding:
|
||||
// EdgeInsets.symmetric(horizontal: 10), // Proper padding
|
||||
// ),
|
||||
onChanged:
|
||||
purposeList.isNotEmpty
|
||||
? (Map<String, dynamic>? newValue) {
|
||||
setState(() {
|
||||
selectedPurpose = newValue?['dropdown_key'];
|
||||
print("Selected Purpose: ${selectedPurpose}");
|
||||
});
|
||||
}
|
||||
: null,
|
||||
),),),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["type_of_visa"] != null) ...[
|
||||
@ -933,6 +943,9 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
child: TextField(
|
||||
focusNode: _commentsFocusNode,
|
||||
controller: _visaCommentsController,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Comments",
|
||||
|
||||
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
import 'dart:io' as io show Directory, File;
|
||||
import 'package:delta_to_html/delta_to_html.dart';
|
||||
import 'package:flutter/cupertino.dart' as dom;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_quill/flutter_quill.dart' hide Text;
|
||||
import 'package:flutter/material.dart';
|
||||
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),
|
||||
focusNode: focusNodes["subjectFocusNode"],
|
||||
controller: controllers["subject"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
onChanged: (value) {
|
||||
// _clearError("local_id_num");
|
||||
},
|
||||
|
||||
@ -4,6 +4,7 @@ import 'dart:async';
|
||||
import 'dart:io' as io show Directory, File;
|
||||
import 'package:delta_to_html/delta_to_html.dart';
|
||||
import 'package:flutter/cupertino.dart' as dom;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_quill/flutter_quill.dart' hide Text;
|
||||
import 'package:flutter/material.dart';
|
||||
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),
|
||||
focusNode: focusNodes["subjectFocusNode"],
|
||||
controller: controllers["subject"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
onChanged: (value) {
|
||||
// _clearError("local_id_num");
|
||||
},
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:frontend/services/apiService.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
@ -332,6 +333,9 @@ class _MailSettingState extends State<MailSetting> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
// focusNode: _destinationFocusNode,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
focusNode: focusNodes["userNameFocusNode"],
|
||||
controller: controllers["userName"],
|
||||
onChanged: (value) {
|
||||
@ -577,6 +581,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
child: TextField(
|
||||
// focusNode: _destinationFocusNode,
|
||||
focusNode: focusNodes["portFocusNode"],
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
controller: controllers["port"],
|
||||
onChanged: (value) {
|
||||
_clearError("mail_port");
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:frontend/Screens/organization/mailSettings.dart';
|
||||
import 'package:frontend/Screens/organization/themeColor.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
@ -652,6 +654,45 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
|
||||
Future<void> _pickImage() async {
|
||||
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(
|
||||
source: ImageSource.gallery,
|
||||
);
|
||||
@ -772,7 +813,11 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: _orgNameController,
|
||||
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16,
|
||||
color: Color(0xFF114D8B),
|
||||
@ -787,6 +832,7 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
isDense: true,
|
||||
|
||||
// contentPadding:
|
||||
// EdgeInsets.symmetric(vertical: 14),
|
||||
),
|
||||
@ -794,50 +840,74 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: _pickImage,
|
||||
Column(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: _pickImage,
|
||||
|
||||
child:
|
||||
_imageBytes != null
|
||||
? ClipOval(
|
||||
child: Image.memory(
|
||||
_imageBytes!,
|
||||
// width: 50,
|
||||
// height: 50,
|
||||
width:
|
||||
responsiveLogoWidth, // Use responsive width
|
||||
height: responsiveLogoHeight,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
)
|
||||
: selectedOrg?['logo'] != null
|
||||
? ClipRect(
|
||||
child: Image.network(
|
||||
selectedOrg!['logo'],
|
||||
width:
|
||||
responsiveLogoWidth, // Use responsive width
|
||||
height: responsiveLogoHeight,
|
||||
// width: 250,
|
||||
// height: 55,
|
||||
fit: BoxFit.contain,
|
||||
errorBuilder: (
|
||||
context,
|
||||
error,
|
||||
stackTrace,
|
||||
) {
|
||||
return const CircleAvatar(
|
||||
radius: 20,
|
||||
backgroundColor: Colors.redAccent,
|
||||
child: Icon(Icons.error, size: 10),
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
: const CircleAvatar(
|
||||
radius: 20,
|
||||
backgroundColor: Colors.amber,
|
||||
child: Icon(Icons.add_a_photo, size: 10),
|
||||
),
|
||||
child:
|
||||
_imageBytes != null
|
||||
? ClipOval(
|
||||
child: Image.memory(
|
||||
_imageBytes!,
|
||||
// width: 50,
|
||||
// height: 50,
|
||||
width:
|
||||
responsiveLogoWidth, // Use responsive width
|
||||
height: responsiveLogoHeight,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
)
|
||||
: selectedOrg?['logo'] != null
|
||||
? ClipRect(
|
||||
child: Image.network(
|
||||
selectedOrg!['logo'],
|
||||
width:
|
||||
responsiveLogoWidth, // Use responsive width
|
||||
height: responsiveLogoHeight,
|
||||
// width: 250,
|
||||
// height: 55,
|
||||
fit: BoxFit.contain,
|
||||
errorBuilder: (
|
||||
context,
|
||||
error,
|
||||
stackTrace,
|
||||
) {
|
||||
return const CircleAvatar(
|
||||
radius: 20,
|
||||
backgroundColor: Colors.redAccent,
|
||||
child: Icon(
|
||||
Icons.error,
|
||||
size: 10,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
)
|
||||
: const CircleAvatar(
|
||||
radius: 20,
|
||||
backgroundColor: Colors.amber,
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -865,6 +865,7 @@ class ForexDataState extends State<ForexData> {
|
||||
focusNode: focusNodes["perdiemAmountFocusNode"],
|
||||
controller: controllers["perdiemAmount"],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Perdiem Amount",
|
||||
labelStyle: TextStyle(fontSize: 11, color: Colors.grey),
|
||||
|
||||
@ -3222,6 +3222,11 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
focusNode: focusNodes["so_numberFocusNode"],
|
||||
controller: _soNumberController,
|
||||
style: TextStyle(fontSize: 12),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
labelText: "SO Number",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
@ -3416,6 +3421,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
TextField(
|
||||
controller: _excepntldescriptionController,
|
||||
maxLines: 3,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
hintText: "Enter reason...",
|
||||
hintStyle: GoogleFonts.poppins(fontSize: 10),
|
||||
@ -3510,6 +3518,11 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
child: SizedBox(
|
||||
height: 55,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
focusNode: focusNodes["excepntldescriptionFocusNode"],
|
||||
controller: _excepntldescriptionController,
|
||||
maxLines: 2,
|
||||
@ -3610,6 +3623,12 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
focusNode: focusNodes["descriptionFocusNode"],
|
||||
controller: _descriptionController,
|
||||
maxLines: 2,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
|
||||
keyboardType: TextInputType.multiline,
|
||||
style: TextStyle(fontSize: 12),
|
||||
enabled: !widget.isViewMode,
|
||||
@ -3743,6 +3762,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
color: Colors.black,
|
||||
),
|
||||
enabled: !widget.isViewMode,
|
||||
|
||||
decoration: InputDecoration(
|
||||
labelText: "Trip Name *",
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
@ -3765,7 +3785,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
keyboardType: TextInputType.text,
|
||||
scrollPhysics: BouncingScrollPhysics(),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -4278,19 +4298,36 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
selectedIstravelUser = 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) {
|
||||
await apiService.handleTripWiseToken(
|
||||
selfId!,
|
||||
context,
|
||||
); // since userId is for traveller
|
||||
print('---TRAVELLER');
|
||||
print('---TRAVELLER- $userId');
|
||||
fetchUserDetails();
|
||||
_selectedTripType = null;
|
||||
getSelectedPlanFor();
|
||||
fetchUsrDtlFromSelectedTripUser();
|
||||
dynamicItineraryKey.currentState?.loadOrgSelectedAlServices();
|
||||
dynamicItineraryKey.currentState?.updateSelectedServices();
|
||||
|
||||
// await apiService.handleTripWiseToken(
|
||||
// // selfId!,
|
||||
// userId,
|
||||
// context,
|
||||
// ); // since userId is for traveller
|
||||
} else {
|
||||
print('---NONTRAVELLER');
|
||||
print('---NONTRAVELLER $userId');
|
||||
await apiService.handleTripWiseToken(
|
||||
userId,
|
||||
context,
|
||||
); // fallback to selfId
|
||||
}
|
||||
print('UserSelectionDialog-1');
|
||||
getSelectedPlanFor();
|
||||
print('UserSelectionDialog-2');
|
||||
fetchUsrDtlFromSelectedTripUser();
|
||||
|
||||
dynamicItineraryKey.currentState?.loadOrgSelectedAlServices();
|
||||
|
||||
@ -59,7 +59,7 @@ class _ListPlansState extends State<ListPlans> {
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
print("LSIT PLan -1");
|
||||
_checkAuthAndLoadData();
|
||||
checkbackbutton();
|
||||
|
||||
@ -69,6 +69,7 @@ class _ListPlansState extends State<ListPlans> {
|
||||
}
|
||||
|
||||
void checkbackbutton() async {
|
||||
print("LSIT PLan -3");
|
||||
roleUser = await getRoleUser();
|
||||
print(roleUser);
|
||||
if (roleUser == "User") {
|
||||
@ -79,6 +80,14 @@ class _ListPlansState extends State<ListPlans> {
|
||||
print("msUser - $msUser");
|
||||
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) {
|
||||
_popStateListener = html.window.onPopState.listen((event) {
|
||||
if (!_dialogShown && mounted) {
|
||||
@ -99,6 +108,7 @@ class _ListPlansState extends State<ListPlans> {
|
||||
}
|
||||
|
||||
void _showBackConfirmationDialog() {
|
||||
print('List planstt');
|
||||
if (!mounted) return;
|
||||
|
||||
_dialogShown = true;
|
||||
@ -144,11 +154,12 @@ class _ListPlansState extends State<ListPlans> {
|
||||
}
|
||||
|
||||
void _checkAuthAndLoadData() async {
|
||||
print("LSIT PLan -2");
|
||||
final String? token = await getToken(); // Your async function to get token
|
||||
|
||||
if (token == null || token.isEmpty) {
|
||||
// Token doesn't exist → redirect to login
|
||||
|
||||
// apiService.logout(context);
|
||||
context.go(
|
||||
"/",
|
||||
); // 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 {
|
||||
// Map<String, dynamic> planData = await ApiService.getViewPlan(planId);
|
||||
// print("ViewAAA - $planData");
|
||||
@ -377,6 +388,7 @@ class _ListPlansState extends State<ListPlans> {
|
||||
try {
|
||||
Map<String, dynamic> planData = await ApiService().getViewPlan(
|
||||
planId,
|
||||
userId,
|
||||
context,
|
||||
);
|
||||
print("ViewAAA - $planData");
|
||||
@ -1255,6 +1267,7 @@ class _ListPlansState extends State<ListPlans> {
|
||||
);
|
||||
deletePlan(
|
||||
plan.planId,
|
||||
userId,
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -1601,6 +1614,7 @@ class _ListPlansState extends State<ListPlans> {
|
||||
);
|
||||
deletePlan(
|
||||
plan.planId,
|
||||
userId,
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
@ -5,6 +5,7 @@ import 'dart:ui' as html;
|
||||
import 'dart:async';
|
||||
import 'dart:html' as html;
|
||||
import 'dart:typed_data';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'dart:ui' as web;
|
||||
|
||||
@ -953,6 +954,9 @@ class _PolicyState extends State<Policy> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
focusNode: focusNodes["policyFocusNode"],
|
||||
controller: _policyController,
|
||||
onChanged: (value) => _clearError("name"),
|
||||
|
||||
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
@ -3798,6 +3799,11 @@ class PolicyCriteriaState extends State<PolicyCriteria> {
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
controller: costController[ServiceId],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
// enabled: !isViewMode,
|
||||
onChanged: (value) {
|
||||
printData();
|
||||
|
||||
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
@ -311,6 +312,11 @@ class PurposeOfTravelDataState extends State<PurposeOfTravelData> {
|
||||
child: TextField(
|
||||
controller: controllers["dropdown_value"],
|
||||
focusNode: focusNodes["dropdown_valueFocusNode"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Name",
|
||||
|
||||
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
@ -340,6 +341,11 @@ class TravellerDataState extends State<TravellerData> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
controller: controllers["first_name"],
|
||||
focusNode: focusNodes["first_nameFocusNode"],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
@ -385,6 +391,11 @@ class TravellerDataState extends State<TravellerData> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(
|
||||
RegExp(r'[a-zA-Z0-9 _-]'),
|
||||
),
|
||||
],
|
||||
controller: controllers["last_name"],
|
||||
focusNode: focusNodes["last_nameFocusNode"],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
|
||||
@ -815,6 +815,9 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
focusNode: focusNodes["FnameFocusNode"],
|
||||
controller: widget.controllers["Fname"],
|
||||
enabled: !widget.isViewMode,
|
||||
@ -869,6 +872,9 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["LnameFocusNode"],
|
||||
controller: widget.controllers["Lname"],
|
||||
@ -916,6 +922,9 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["CnameFocusNode"],
|
||||
controller: widget.controllers["Cname"],
|
||||
|
||||
@ -551,6 +551,9 @@ class OfficeDetailsState extends State<OfficeDetails> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
focusNode: _employeeCodeFocusNode,
|
||||
controller: widget.controllers["employeeCode"],
|
||||
enabled: !widget.isViewMode,
|
||||
|
||||
@ -861,6 +861,9 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
// focusNode: focusNodes["FnameFocusNode"],
|
||||
focusNode: _fnameFocusNode, // 👈 Use it here
|
||||
controller: widget.controllers["Fname"],
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
autofocus: true,
|
||||
enabled: !widget.isViewMode,
|
||||
onChanged: (value) {
|
||||
@ -910,6 +913,9 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
|
||||
],
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
focusNode: _lnameFocusNode,
|
||||
autofocus: true,
|
||||
|
||||
@ -1221,6 +1221,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
|
||||
],
|
||||
focusNode: focusNodes["FnameFocusNode"],
|
||||
controller: controllers["Fname"],
|
||||
enabled: !widget.isViewMode,
|
||||
@ -1264,6 +1267,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
|
||||
],
|
||||
focusNode: focusNodes["MnameFocusNode"],
|
||||
controller: controllers["Mname"],
|
||||
enabled: !widget.isViewMode,
|
||||
@ -1310,6 +1316,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
|
||||
],
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["LnameFocusNode"],
|
||||
controller: controllers["Lname"],
|
||||
@ -1548,6 +1557,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
|
||||
],
|
||||
focusNode: focusNodes["placeOfIssueFocusNode"],
|
||||
controller: controllers["placeOfIssue"],
|
||||
enabled: !widget.isViewMode,
|
||||
@ -2339,6 +2351,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
controller: controllers["local_id_num"],
|
||||
enabled: !widget.isViewMode,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
onChanged: (value) {
|
||||
_clearError("local_id_num");
|
||||
},
|
||||
@ -2476,6 +2491,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
controller: controllers["full_name_as_id"],
|
||||
enabled: !widget.isViewMode,
|
||||
onChanged: (value) {
|
||||
@ -2710,6 +2728,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["d_meal_prefFocusNode"],
|
||||
controller: controllers["d_meal_pref"],
|
||||
@ -2755,6 +2776,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
controller: controllers["d_additonal_Info"],
|
||||
focusNode: focusNodes["d_additonal_InfoFocusNode"],
|
||||
@ -2988,7 +3012,11 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
controller: controllers["i_meal_pref"],
|
||||
focusNode: focusNodes["i_meal_prefFocusNode"],
|
||||
@ -3034,6 +3062,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
controller: controllers["i_additonal_Info"],
|
||||
focusNode: focusNodes["i_additonal_InfoFocusNode"],
|
||||
@ -3629,6 +3660,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9_-]')),
|
||||
],
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
controller: entry["controller_flier_number"],
|
||||
enabled: !widget.isViewMode,
|
||||
@ -3893,6 +3927,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9 _-]')),
|
||||
],
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
controller: entry["controller_membership"],
|
||||
enabled: !widget.isViewMode,
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frontend/config/apiUrl.dart';
|
||||
import 'package:go_router/go_router.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 '../services/apiService.dart';
|
||||
import '../utils/auth_utils.dart';
|
||||
@ -37,6 +40,8 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
|
||||
late TabSelection selectedTab;
|
||||
|
||||
final ImagePicker _picker = ImagePicker();
|
||||
|
||||
String? token;
|
||||
Map<String, dynamic>? userData;
|
||||
Map<String, dynamic>? fetchedUserData;
|
||||
@ -48,6 +53,9 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
Color? layoutColor = Colors.white10;
|
||||
Color? bodyColor;
|
||||
|
||||
File? _pickedImageFile;
|
||||
String? _errorMessage;
|
||||
|
||||
void initState() {
|
||||
super.initState();
|
||||
// initializeData();
|
||||
@ -104,6 +112,14 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
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 {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final String? userDataString = prefs.getString('user_data');
|
||||
|
||||
@ -84,7 +84,7 @@ final GoRouter router = GoRouter(
|
||||
// );
|
||||
},
|
||||
routes: [
|
||||
GoRoute(path: '/home', builder: (context, state) => HomePage()),
|
||||
// GoRoute(path: '/home', builder: (context, state) => HomePage()),
|
||||
GoRoute(
|
||||
path: '/listAllPlan',
|
||||
builder: (context, state) => ListAllPlans(),
|
||||
|
||||
@ -36,26 +36,31 @@ class OrganizationSettingState extends State<OrganizationSetting> {
|
||||
|
||||
// String? bodyStringColor = await getBodyColor();
|
||||
roleUser = await getRoleUser();
|
||||
setState(() {
|
||||
layoutColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(layoutString))
|
||||
: Colors.redAccent;
|
||||
|
||||
secondColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(secondString!))
|
||||
: Colors.orange;
|
||||
if (roleUser == 'Org Admin' || roleUser == 'Travel Admin') {
|
||||
setState(() {
|
||||
layoutColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(layoutString))
|
||||
: Colors.redAccent;
|
||||
|
||||
thridColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(thridString!))
|
||||
: Colors.orangeAccent;
|
||||
// bodyColor =
|
||||
// bodyStringColor != null
|
||||
// ? Color(int.parse(bodyStringColor))
|
||||
// : Colors.white;
|
||||
});
|
||||
secondColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(secondString!))
|
||||
: Colors.orange;
|
||||
|
||||
thridColor =
|
||||
layoutString != null
|
||||
? Color(int.parse(thridString!))
|
||||
: Colors.orangeAccent;
|
||||
// bodyColor =
|
||||
// bodyStringColor != null
|
||||
// ? Color(int.parse(bodyStringColor))
|
||||
// : Colors.white;
|
||||
});
|
||||
} else {
|
||||
apiService.logout(context);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@ -743,9 +743,11 @@ class ApiService {
|
||||
|
||||
Future<Map<String, dynamic>> getViewPlan(
|
||||
String planId,
|
||||
userId,
|
||||
BuildContext context,
|
||||
) 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';
|
||||
print("API URL: $apiUrldata");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user