dashboard mobile
This commit is contained in:
parent
35229fa755
commit
0ec324bf03
@ -30,6 +30,7 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
Map<String, dynamic>? apiData;
|
||||
String? organizationId;
|
||||
late bool _dialogShown = false;
|
||||
bool isLoading = false;
|
||||
late StreamSubscription<html.PopStateEvent> _popStateListener;
|
||||
String selectedView = 'Today';
|
||||
String AccessKeyFlag = "Both";
|
||||
@ -148,6 +149,10 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
checkbackbutton();
|
||||
});
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
|
||||
});
|
||||
// If token exists, load the dashboard data
|
||||
loadDashboardData();
|
||||
}
|
||||
@ -157,6 +162,7 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
final data = await fetchStatusDashboard();
|
||||
setState(() {
|
||||
apiData = data;
|
||||
isLoading = false;
|
||||
});
|
||||
} catch (e) {
|
||||
print("Error loading dashboard: $e");
|
||||
@ -484,37 +490,35 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget statusCard(String label, int count) {
|
||||
return Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEAF3FB),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
Widget statusCard(String label, int count, bool isDesktop) {
|
||||
return Container(
|
||||
width: isDesktop ? 120 : double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEAF3FB),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
count.toString(),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 18 : 16,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
count.toString(),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 18,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
label,
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 12 : 11,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -725,152 +729,256 @@ class StatusDashboardState extends State<StatusDashboard> {
|
||||
appBar: CustomAppBar(isDesktop: isDesktop),
|
||||
drawer: CustomDrawer(isDesktop: false),
|
||||
body: Padding(
|
||||
padding:
|
||||
isDesktop
|
||||
? EdgeInsets.symmetric(
|
||||
horizontal:
|
||||
MediaQuery.of(context).size.width *
|
||||
0.1, // 30% of screen width as horizontal padding
|
||||
vertical: 10, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(0),
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return SingleChildScrollView(
|
||||
// child: ConstrainedBox(
|
||||
// constraints: BoxConstraints(
|
||||
// minHeight: constraints.maxHeight,
|
||||
// ),
|
||||
// ),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// First Row: Toggle Buttons Row
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Container(
|
||||
height: 36,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEAEAEA),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
padding: isDesktop
|
||||
? const EdgeInsets.symmetric(vertical: 5)
|
||||
: EdgeInsets.zero,
|
||||
child: Center(
|
||||
child: ConstrainedBox(
|
||||
constraints: BoxConstraints(
|
||||
maxWidth: 1200,
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15.0), // ✅ Scroll content padding
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
isLoading ? Center(child: CircularProgressIndicator()) :
|
||||
LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
toggleChip("Today"),
|
||||
toggleChip("This Week"),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Second Row: Domestic & International and Status
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// LEFT SIDE
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.blueGrey,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Row(
|
||||
// First Row: Toggle Buttons Row
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
...typeData.map((item) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
buildTopCard(
|
||||
// icon: item['value'] == "Domestic"
|
||||
// ? Icons.home
|
||||
// : Icons.travel_explore,
|
||||
color: item['value'] == "Domestic"
|
||||
? Color(0xFF0DB04B)
|
||||
: Color(0xFF004A8E),
|
||||
label: item['value'],
|
||||
count: item['count'],
|
||||
bgColor: item['value'] == "Domestic"
|
||||
? const Color(0xFFD6FBE4)
|
||||
: const Color(0xFFD9E8FF),
|
||||
Container(
|
||||
height: 36,
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFEAEAEA),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
toggleChip("Today"),
|
||||
toggleChip("This Week"),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Second Row: Domestic & International and Status
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.blueGrey,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Row(
|
||||
children: [
|
||||
...typeData.map((item) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
buildTopCard(
|
||||
color: item['value'] == "Domestic"
|
||||
? Color(0xFF0DB04B)
|
||||
: Color(0xFF004A8E),
|
||||
label: item['value'],
|
||||
count: item['count'],
|
||||
bgColor: item['value'] == "Domestic"
|
||||
? const Color(0xFFD6FBE4)
|
||||
: const Color(0xFFD9E8FF),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.blueGrey,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Status",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 19,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
...statusData.map((item) => statusCard(item['value'], item['count'], isDesktop)).toList(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.blueGrey,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Row(
|
||||
children: [
|
||||
...typeData.map((item) {
|
||||
return Expanded(
|
||||
child: Column(
|
||||
children: [
|
||||
buildTopCard(
|
||||
color: item['value'] == "Domestic"
|
||||
? const Color(0xFF0DB04B)
|
||||
: const Color(0xFF004A8E),
|
||||
label: item['value'],
|
||||
count: item['count'],
|
||||
bgColor: item['value'] == "Domestic"
|
||||
? const Color(0xFFD6FBE4)
|
||||
: const Color(0xFFD9E8FF),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.blueGrey,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Status",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 19,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 23),
|
||||
Wrap(
|
||||
spacing: 10,
|
||||
runSpacing: 10,
|
||||
children: [
|
||||
...statusData.map((item) => statusCard(item['value'], item['count'], isDesktop)).toList(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 20),
|
||||
// RIGHT SIDE
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.blueGrey,
|
||||
blurRadius: 5,
|
||||
offset: Offset(0, 2),
|
||||
),
|
||||
],
|
||||
),
|
||||
padding: const EdgeInsets.all(15),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Status",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 19,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 23),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
...statusData.map((item) => statusCard(item['value'], item['count'])).toList(),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Third Row: Flight, Accommodation, Forex
|
||||
Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(child: buildCategoryCard("Flight", Icons.flight,statusLabels,flightData)),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(child: buildCategoryCard("Accomodation", Icons.hotel_outlined,statusLabels,accommodationData)),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(child: buildCategoryCard("Forex", Icons.attach_money,statusLabels,forexData)),
|
||||
],
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 20),
|
||||
|
||||
// Third Row: Flight, Accommodation, Forex
|
||||
isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Expanded(child: buildCategoryCard("Flight", Icons.flight, statusLabels, flightData)),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(child: buildCategoryCard("Accomodation", Icons.hotel_outlined, statusLabels, accommodationData)),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(child: buildCategoryCard("Forex", Icons.attach_money, statusLabels, forexData)),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: buildCategoryCard("Flight", Icons.flight, statusLabels, flightData)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: buildCategoryCard("Accomodation", Icons.hotel_outlined, statusLabels, accommodationData)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: buildCategoryCard("Forex", Icons.attach_money, statusLabels, forexData)),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
) ,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -11,6 +11,7 @@ import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:frontend/Screens/userManagement/create_user/personal_details.dart';
|
||||
import 'package:frontend/Screens/userManagement/create_user/traveller_details.dart';
|
||||
import 'package:frontend/Screens/userManagement/create_user/office_details.dart';
|
||||
import 'package:frontend/utils/auth_utils.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
@ -30,7 +31,6 @@ import '../../../widgets/custom_text_field.dart';
|
||||
import '../../../widgets/custom_text_forex.dart';
|
||||
import '../../../widgets/custom_user_form.dart';
|
||||
import '../../../widgets/saving_loader.dart';
|
||||
import 'office_details.dart';
|
||||
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
|
||||
@ -46,6 +46,8 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
GlobalKey<PersonalDetailsState>();
|
||||
final GlobalKey<TravellerDetailsState> travellerDetailsKey =
|
||||
GlobalKey<TravellerDetailsState>();
|
||||
final GlobalKey<OfficeDetailsState> officeDetailsKey =
|
||||
GlobalKey<OfficeDetailsState>();
|
||||
|
||||
// late List<Map<String, dynamic>?> travelDetailsData;
|
||||
Map<String, dynamic>? travelDetailsData;
|
||||
@ -60,6 +62,9 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
bool isCheckingToken = false;
|
||||
bool isDisable = false;
|
||||
|
||||
final FocusNode submitButtonFocusNode = FocusNode();
|
||||
|
||||
|
||||
String? token;
|
||||
|
||||
late bool isapiselectedUser = false;
|
||||
@ -1448,7 +1453,6 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
selectedRole = role;
|
||||
});
|
||||
},
|
||||
|
||||
onServiceIdsChanged: (List<Map<String, dynamic>> updatedList) {
|
||||
setState(() {
|
||||
selectedServiceIds = updatedList;
|
||||
@ -1755,26 +1759,29 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
isViewMode
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor:
|
||||
isViewMode ? layoutColor : layoutColor, // Keep original color
|
||||
foregroundColor:
|
||||
isViewMode
|
||||
? Colors.white
|
||||
: Colors.white, // Keep original color
|
||||
disabledBackgroundColor:
|
||||
layoutColor, // Ensure color remains when disabled
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: layoutColor, width: 2),
|
||||
child: Focus( // 👈 Wrap with Focus here
|
||||
focusNode: submitButtonFocusNode,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor:
|
||||
isViewMode ? layoutColor : layoutColor, // Keep original color
|
||||
foregroundColor:
|
||||
isViewMode
|
||||
? Colors.white
|
||||
: Colors.white, // Keep original color
|
||||
disabledBackgroundColor:
|
||||
layoutColor, // Ensure color remains when disabled
|
||||
disabledForegroundColor: Colors.white,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
side: BorderSide(color: layoutColor, width: 2),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
onPressed:
|
||||
isViewMode ? null : handleSubmit, // Disable when in view mode
|
||||
child: Text("Submit"),
|
||||
),
|
||||
onPressed:
|
||||
isViewMode ? null : handleSubmit, // Disable when in view mode
|
||||
child: Text("Submit"),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
@ -58,10 +58,10 @@ class OfficeDetails extends StatefulWidget {
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_OfficeDetailsState createState() => _OfficeDetailsState();
|
||||
OfficeDetailsState createState() => OfficeDetailsState();
|
||||
}
|
||||
|
||||
class _OfficeDetailsState extends State<OfficeDetails> {
|
||||
class OfficeDetailsState extends State<OfficeDetails> {
|
||||
final ApiService apiService = ApiService();
|
||||
|
||||
late Map<String, String> countryMap; // Mapping country_code -> country_name
|
||||
@ -169,6 +169,7 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
loadInitialData();
|
||||
_employeeCodeFocusNode.requestFocus();
|
||||
});
|
||||
apiCountryData = null;
|
||||
apiUserData = null;
|
||||
@ -702,8 +703,8 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_departmentFocus ?? false)
|
||||
? (layoutColor ?? Colors.white)
|
||||
(_departmentFocus)
|
||||
? (layoutColor)
|
||||
: Colors.white,
|
||||
width: 0.5,
|
||||
),
|
||||
@ -711,8 +712,8 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(_departmentFocus ?? false)
|
||||
? (layoutColor ?? Colors.white)
|
||||
(_departmentFocus)
|
||||
? (layoutColor)
|
||||
: Colors.white,
|
||||
width: 0.5,
|
||||
// const Color(0xFFD6D5E6),
|
||||
@ -1868,39 +1869,83 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
// onTap: () async{
|
||||
// _selectCheckOutDate(context);
|
||||
//
|
||||
// },
|
||||
onTap: () async {
|
||||
_startDateFocusNode?.requestFocus();
|
||||
await _selectCheckOutDate(context);
|
||||
child:Focus(
|
||||
focusNode: _startDateFocusNode,
|
||||
onKeyEvent: (FocusNode node, KeyEvent event) {
|
||||
// Only act on KeyDown and when Enter is pressed
|
||||
if (event is KeyDownEvent &&
|
||||
(event.logicalKey == LogicalKeyboardKey.enter ||
|
||||
event.logicalKey == LogicalKeyboardKey.numpadEnter)) {
|
||||
_startDateFocusNode?.requestFocus();
|
||||
_selectCheckOutDate(context);
|
||||
return KeyEventResult.handled; // Stop default behavior
|
||||
}
|
||||
return KeyEventResult.ignored; // Allow normal handling
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: _startDateFocusNode,
|
||||
controller: widget.controllers["delegationStartDate"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTapDown: (details) {
|
||||
_startDateFocusNode?.requestFocus();
|
||||
_selectCheckOutDate(context);
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
controller: widget.controllers["delegationStartDate"],
|
||||
readOnly: true,
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Color(0xFF8B8FB2),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// child: GestureDetector(
|
||||
// // onTap: () async{
|
||||
// // _selectCheckOutDate(context);
|
||||
// //
|
||||
// // },
|
||||
// onTap: () async {
|
||||
// _startDateFocusNode?.requestFocus();
|
||||
// await _selectCheckOutDate(context);
|
||||
// },
|
||||
// child: AbsorbPointer(
|
||||
// child: TextField(
|
||||
// focusNode: _startDateFocusNode,
|
||||
// controller: widget.controllers["delegationStartDate"],
|
||||
// readOnly: true,
|
||||
// style: const TextStyle(fontSize: 12),
|
||||
// decoration: InputDecoration(
|
||||
// labelText: "Select Date",
|
||||
// labelStyle: const TextStyle(
|
||||
// fontSize: 12,
|
||||
// color: Colors.grey,
|
||||
// ),
|
||||
// floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
// border: InputBorder.none,
|
||||
// contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||
// suffixIcon: const Icon(
|
||||
// Icons.calendar_today,
|
||||
// size: 16,
|
||||
// color: Colors.grey,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
),
|
||||
// if (errorMessages["start_date"] != null) ...[
|
||||
@ -1975,39 +2020,89 @@ class _OfficeDetailsState extends State<OfficeDetails> {
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
// onTap: () async{
|
||||
// _selectCheckOutDate(context);
|
||||
//
|
||||
// },
|
||||
onTap: () async {
|
||||
_endDateFocusNode?.requestFocus();
|
||||
await _selectForexEndDate(context);
|
||||
child:Focus(
|
||||
focusNode: _endDateFocusNode,
|
||||
onKeyEvent: (FocusNode node, KeyEvent event) {
|
||||
// Only act on KeyDown and when Enter is pressed
|
||||
if (event is KeyDownEvent &&
|
||||
(event.logicalKey == LogicalKeyboardKey.enter ||
|
||||
event.logicalKey == LogicalKeyboardKey.numpadEnter)) {
|
||||
if (!widget.isViewMode) {
|
||||
_selectForexEndDate(context).then((_) {
|
||||
_endDateFocusNode?.requestFocus();
|
||||
});
|
||||
}
|
||||
return KeyEventResult.handled; // Stop default behavior
|
||||
}
|
||||
return KeyEventResult.ignored; // Allow normal handling
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
focusNode: _endDateFocusNode,
|
||||
controller: widget.controllers["delegationEndDate"],
|
||||
readOnly: true,
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: const TextStyle(
|
||||
fontSize: 12,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: const Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Colors.grey,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTapDown: (details) {
|
||||
if (!widget.isViewMode) {
|
||||
_selectForexEndDate(context).then((_) {
|
||||
_endDateFocusNode?.requestFocus();
|
||||
});
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
controller: widget.controllers["delegationEndDate"],
|
||||
readOnly: true,
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Color(0xFF8B8FB2),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// child: GestureDetector(
|
||||
// // onTap: () async{
|
||||
// // _selectCheckOutDate(context);
|
||||
// //
|
||||
// // },
|
||||
// onTap: () async {
|
||||
// _endDateFocusNode?.requestFocus();
|
||||
// await _selectForexEndDate(context);
|
||||
// },
|
||||
// child: AbsorbPointer(
|
||||
// child: TextField(
|
||||
// focusNode: _endDateFocusNode,
|
||||
// controller: widget.controllers["delegationEndDate"],
|
||||
// readOnly: true,
|
||||
// style: const TextStyle(fontSize: 12),
|
||||
// decoration: InputDecoration(
|
||||
// labelText: "Select Date",
|
||||
// labelStyle: const TextStyle(
|
||||
// fontSize: 12,
|
||||
// color: Colors.grey,
|
||||
// ),
|
||||
// floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
// border: InputBorder.none,
|
||||
// contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||
// suffixIcon: const Icon(
|
||||
// Icons.calendar_today,
|
||||
// size: 16,
|
||||
// color: Colors.grey,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
),
|
||||
|
||||
|
||||
@ -35,6 +35,7 @@ class PersonalDetails extends StatefulWidget {
|
||||
final String? selectedCountry;
|
||||
final String? selectedRole;
|
||||
final String? userIdApi;
|
||||
final dynamic focusNodes;
|
||||
|
||||
// const PersonalDetails(this.isDesktop, this.isViewMode, {super.key},);
|
||||
const PersonalDetails({
|
||||
@ -50,6 +51,7 @@ class PersonalDetails extends StatefulWidget {
|
||||
required this.isDesktop,
|
||||
required this.isViewMode,
|
||||
required this.apiselectedUser,
|
||||
this.focusNodes,
|
||||
this.onGenderChanged,
|
||||
this.onCountryChanged,
|
||||
this.onRoleChanged,
|
||||
@ -75,8 +77,32 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
String? get selectedGenderValue => selectedGender;
|
||||
String? get selectedCountryValue => selectedCountry;
|
||||
String? get selectedRoleValue => selectedRole;
|
||||
Map<String, FocusNode> focusNodes = {};
|
||||
Map<String, bool> focusStates = {};
|
||||
|
||||
final FocusNode _fnameFocusNode = FocusNode();
|
||||
final FocusNode _lnameFocusNode = FocusNode();
|
||||
final FocusNode _emailFocusNode = FocusNode();
|
||||
final FocusNode _passwordFocusNode = FocusNode();
|
||||
final FocusNode _dobFocusNode = FocusNode();
|
||||
final FocusNode _genderFocusNode = FocusNode();
|
||||
final FocusNode _mobileNumberFocusNode = FocusNode();
|
||||
final FocusNode _alternateMobileFocusNode = FocusNode();
|
||||
final FocusNode _addressFocusNode = FocusNode();
|
||||
final FocusNode _countryFocusNode = FocusNode();
|
||||
final FocusNode _postalCodeFocusNode = FocusNode();
|
||||
final FocusNode _roleIdFocusNode = FocusNode();
|
||||
bool _fnameFocus = false;
|
||||
bool _lnameFocus = false;
|
||||
bool _emailFocus = false;
|
||||
bool _passwordFocus = false;
|
||||
bool _dobFocus = false;
|
||||
bool _genderFocus = false;
|
||||
bool _mobileNumberFocus = false;
|
||||
bool _alternateMobileFocus = false;
|
||||
bool _addressFocus = false;
|
||||
bool _countryFocus = false;
|
||||
bool _postalCodeFocus = false;
|
||||
bool _roleIdFocus = false;
|
||||
|
||||
|
||||
late bool isTravelAgent = false;
|
||||
|
||||
@ -154,23 +180,26 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
|
||||
print("selectedServiceIdsAPI - $selectedServiceIds");
|
||||
|
||||
for (var field in dataHeader) {
|
||||
focusNodes["${field}FocusNode"] = FocusNode();
|
||||
focusStates["${field}Focused"] = false;
|
||||
}
|
||||
|
||||
for (var key in focusNodes.keys) {
|
||||
_addFocusListener(focusNodes[key]!, (focus) {
|
||||
setState(() {
|
||||
focusStates[key.replaceFirst("FocusNode", "Focused")] = focus;
|
||||
});
|
||||
});
|
||||
}
|
||||
_addFocusListener(_fnameFocusNode, (focus) => _fnameFocus = focus);
|
||||
_addFocusListener(_lnameFocusNode, (focus) => _lnameFocus = focus);
|
||||
_addFocusListener(_emailFocusNode, (focus) => _emailFocus = focus);
|
||||
_addFocusListener(_passwordFocusNode, (focus) => _passwordFocus = focus);
|
||||
_addFocusListener(_dobFocusNode, (focus) => _dobFocus = focus);
|
||||
_addFocusListener(_genderFocusNode, (focus) => _genderFocus = focus);
|
||||
_addFocusListener(_mobileNumberFocusNode, (focus) => _mobileNumberFocus = focus);
|
||||
_addFocusListener(_alternateMobileFocusNode, (focus) => _alternateMobileFocus = focus);
|
||||
_addFocusListener(_addressFocusNode, (focus) => _addressFocus = focus);
|
||||
_addFocusListener(_countryFocusNode, (focus) => _countryFocus = focus);
|
||||
_addFocusListener(_postalCodeFocusNode, (focus) => _postalCodeFocus = focus);
|
||||
_addFocusListener(_roleIdFocusNode, (focus) => _roleIdFocus = focus);
|
||||
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
loadAllServices();
|
||||
getOrganizationData();
|
||||
loadInitialData();
|
||||
_fnameFocusNode.requestFocus();
|
||||
});
|
||||
}
|
||||
|
||||
@ -802,13 +831,14 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: focusStates["FnameFocused"] ?? false,
|
||||
isFocused: _fnameFocus,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["FnameFocusNode"],
|
||||
// focusNode: focusNodes["FnameFocusNode"],
|
||||
focusNode: _fnameFocusNode, // 👈 Use it here
|
||||
controller: widget.controllers["Fname"],
|
||||
autofocus: true,
|
||||
enabled: !widget.isViewMode,
|
||||
@ -854,13 +884,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: focusStates["LnameFocused"] ?? false,
|
||||
isFocused: _lnameFocus,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["LnameFocusNode"],
|
||||
focusNode: _lnameFocusNode,
|
||||
autofocus: true,
|
||||
controller: widget.controllers["Lname"],
|
||||
enabled: !widget.isViewMode,
|
||||
@ -1006,21 +1036,21 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.12
|
||||
: null,
|
||||
isFocused: focusStates["genderFocused"] ?? false,
|
||||
isFocused: _genderFocus,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 0),
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: Focus(
|
||||
focusNode: focusNodes["genderFocusNode"],
|
||||
focusNode: _genderFocusNode,
|
||||
onFocusChange: (hasFocus) {
|
||||
setState(() {
|
||||
focusStates["genderFocused"] = hasFocus;
|
||||
_genderFocus = hasFocus;
|
||||
});
|
||||
},
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
focusNodes["genderFocusNode"]?.requestFocus();
|
||||
_genderFocusNode?.requestFocus();
|
||||
},
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem: selectedGender,
|
||||
@ -1051,7 +1081,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(focusStates["genderFocused"] ?? false)
|
||||
(_genderFocus)
|
||||
? (layoutColor ?? Colors.blue)
|
||||
: Colors.white,
|
||||
width: 0.5,
|
||||
@ -1060,7 +1090,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(focusStates["genderFocused"] ?? false)
|
||||
(_genderFocus)
|
||||
? (layoutColor ?? Colors.blue)
|
||||
: Colors.white,
|
||||
// : const Color(0xFFD6D5E6),
|
||||
@ -1069,7 +1099,8 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color : (layoutColor ?? Colors.grey), width: 0.5),
|
||||
borderSide: BorderSide(
|
||||
color : (layoutColor ?? Colors.grey), width: 0.5),
|
||||
),
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
@ -1152,51 +1183,110 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.12
|
||||
: null,
|
||||
isFocused: focusStates["dobFocused"] ?? false,
|
||||
isFocused: _dobFocus,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap:
|
||||
widget.isViewMode
|
||||
? null
|
||||
: () async {
|
||||
await _selectCheckDateOfBirth(context);
|
||||
if (widget.controllers["dob"]!.text.isNotEmpty) {
|
||||
setState(() {
|
||||
// errorMessages.remove("start_date");
|
||||
});
|
||||
// Delay re-focusing the DOB field slightly
|
||||
Future.delayed(Duration(milliseconds: 100), () {
|
||||
focusNodes["dobFocusNode"]?.requestFocus();
|
||||
});
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
controller: widget.controllers["dob"],
|
||||
focusNode: focusNodes["dobFocusNode"],
|
||||
readOnly: true,
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Color(0xFF8B8FB2),
|
||||
child:
|
||||
Focus(
|
||||
focusNode: _dobFocusNode,
|
||||
onKeyEvent: (FocusNode node, KeyEvent event) {
|
||||
// Only act on KeyDown and when Enter is pressed
|
||||
if (event is KeyDownEvent &&
|
||||
(event.logicalKey == LogicalKeyboardKey.enter ||
|
||||
event.logicalKey == LogicalKeyboardKey.numpadEnter)) {
|
||||
if (!widget.isViewMode) {
|
||||
_selectCheckDateOfBirth(context).then((_) {
|
||||
if (widget.controllers["dob"]!.text.isNotEmpty) {
|
||||
Future.delayed(Duration(milliseconds: 100), () {
|
||||
_dobFocusNode?.requestFocus();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
return KeyEventResult.handled; // Stop default behavior
|
||||
}
|
||||
return KeyEventResult.ignored; // Allow normal handling
|
||||
},
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTapDown: (details) {
|
||||
if (!widget.isViewMode) {
|
||||
_selectCheckDateOfBirth(context).then((_) {
|
||||
if (widget.controllers["dob"]!.text.isNotEmpty) {
|
||||
Future.delayed(Duration(milliseconds: 100), () {
|
||||
_dobFocusNode?.requestFocus();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
controller: widget.controllers["dob"],
|
||||
readOnly: true,
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.grey,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: Icon(
|
||||
Icons.calendar_today,
|
||||
size: 16,
|
||||
color: Color(0xFF8B8FB2),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// GestureDetector(
|
||||
// onTap:
|
||||
// widget.isViewMode
|
||||
// ? null
|
||||
// : () async {
|
||||
// await _selectCheckDateOfBirth(context);
|
||||
// if (widget.controllers["dob"]!.text.isNotEmpty) {
|
||||
// setState(() {
|
||||
// // errorMessages.remove("start_date");
|
||||
// });
|
||||
// // Delay re-focusing the DOB field slightly
|
||||
// Future.delayed(Duration(milliseconds: 100), () {
|
||||
// _dobFocusNode?.requestFocus();
|
||||
// });
|
||||
// }
|
||||
// },
|
||||
// child: AbsorbPointer(
|
||||
// child: TextField(
|
||||
// controller: widget.controllers["dob"],
|
||||
// focusNode:_dobFocusNode,
|
||||
// readOnly: true,
|
||||
// style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
// decoration: InputDecoration(
|
||||
// labelText: "Select Date",
|
||||
// labelStyle: GoogleFonts.poppins(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w400,
|
||||
// color: Colors.grey,
|
||||
// ),
|
||||
// floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
// border: InputBorder.none,
|
||||
// contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
// suffixIcon: Icon(
|
||||
// Icons.calendar_today,
|
||||
// size: 16,
|
||||
// color: Color(0xFF8B8FB2),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -1217,13 +1307,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: focusStates["emailFocused"] ?? false,
|
||||
isFocused: _emailFocus,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["emailFocusNode"],
|
||||
focusNode: _emailFocusNode,
|
||||
autofocus: true,
|
||||
controller: widget.controllers["email"],
|
||||
onChanged: (value) {
|
||||
@ -1269,13 +1359,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: focusStates["mobileNumberFocused"] ?? false,
|
||||
isFocused: _mobileNumberFocus,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["mobileNumberFocusNode"],
|
||||
focusNode: _mobileNumberFocusNode,
|
||||
autofocus: true,
|
||||
controller: widget.controllers["mobileNumber"],
|
||||
enabled: !widget.isViewMode,
|
||||
@ -1332,13 +1422,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: focusStates["alternateMobileFocused"] ?? false,
|
||||
isFocused: _alternateMobileFocus,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["alternateMobileFocusNode"],
|
||||
focusNode: _alternateMobileFocusNode,
|
||||
autofocus: true,
|
||||
controller: widget.controllers["alternateMobile"],
|
||||
enabled: !widget.isViewMode,
|
||||
@ -1408,23 +1498,23 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: focusStates["countryFocused"] ?? false,
|
||||
isFocused: _countryFocus,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 0),
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
child: Focus(
|
||||
focusNode: focusNodes["countryFocusNode"],
|
||||
focusNode: _countryFocusNode,
|
||||
onFocusChange: (hasFocus) {
|
||||
setState(() {
|
||||
focusStates["countryFocused"] = hasFocus;
|
||||
_countryFocus = hasFocus;
|
||||
});
|
||||
},
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
// Request focus when user taps
|
||||
focusNodes["countryFocusNode"]?.requestFocus();
|
||||
_countryFocusNode?.requestFocus();
|
||||
},
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem: countryMap[selectedCountry],
|
||||
@ -1461,7 +1551,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(focusStates["countryFocused"] ?? false)
|
||||
(_countryFocus)
|
||||
? (layoutColor ?? Colors.blue)
|
||||
: Colors.white,
|
||||
width: 0.5,
|
||||
@ -1470,7 +1560,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(focusStates["countryFocused"] ?? false)
|
||||
(_countryFocus)
|
||||
? (layoutColor ?? Colors.blue)
|
||||
: Colors.white,
|
||||
width: 0.5,
|
||||
@ -1552,14 +1642,14 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: focusStates["postalCodeFocused"] ?? false,
|
||||
isFocused: _postalCodeFocus,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
autofocus: true,
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["postalCodeFocusNode"],
|
||||
focusNode: _postalCodeFocusNode,
|
||||
controller: widget.controllers["postalCode"],
|
||||
enabled: !widget.isViewMode,
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
@ -1673,22 +1763,22 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
// isFocused: false,
|
||||
isFocused: focusStates["roleIdFocusNode"] ?? false,
|
||||
isFocused: _roleIdFocus,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 0),
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: Focus(
|
||||
focusNode: focusNodes["roleIdFocusNode"],
|
||||
focusNode: _roleIdFocusNode,
|
||||
onFocusChange: (hasFocus) {
|
||||
setState(() {
|
||||
focusStates["roleIdFocused"] = hasFocus;
|
||||
_roleIdFocus = hasFocus;
|
||||
});
|
||||
},
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
// Request focus when user taps
|
||||
focusNodes["roleIdFocusNode"]?.requestFocus();
|
||||
_roleIdFocusNode?.requestFocus();
|
||||
},
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem: selectedRole != null ? roleMap[selectedRole] : null,
|
||||
@ -1726,7 +1816,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(focusStates["roleIdFocused"] ?? false)
|
||||
(_roleIdFocus)
|
||||
? (layoutColor ?? Colors.blue)
|
||||
: Colors.white,
|
||||
width: 0.5,
|
||||
@ -1735,7 +1825,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color:
|
||||
(focusStates["roleIdFocused"] ?? false)
|
||||
(_roleIdFocus)
|
||||
? (layoutColor ?? Colors.blue)
|
||||
: Colors.white,
|
||||
// : const Color(0xFFD6D5E6),
|
||||
@ -1810,14 +1900,14 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: focusStates["addressFocused"] ?? false,
|
||||
isFocused: _addressFocus,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 80,
|
||||
child: TextField(
|
||||
autofocus: true,
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["addressFocusNode"],
|
||||
focusNode: _addressFocusNode,
|
||||
controller: widget.controllers["address"],
|
||||
enabled: !widget.isViewMode,
|
||||
maxLines: 2,
|
||||
@ -1854,13 +1944,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: focusStates["passwordFocused"] ?? false,
|
||||
isFocused: _passwordFocus,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
focusNode: focusNodes["passwordFocusNode"],
|
||||
focusNode: _passwordFocusNode,
|
||||
autofocus: true,
|
||||
controller: widget.controllers["password"],
|
||||
enabled: !widget.isViewMode,
|
||||
|
||||
@ -169,6 +169,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
fetchApiData();
|
||||
// Delay adding the row until after the first frame
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// focusNodes["FnameFocusNode"]?.requestFocus();
|
||||
setState(() {
|
||||
addHotelLoyaltyEntry();
|
||||
addFrequentFlierEntry();
|
||||
@ -176,6 +177,13 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
loadInitialData();
|
||||
});
|
||||
updateTravel();
|
||||
print("Trying to focus Fname...");
|
||||
|
||||
final node = focusNodes["FnameFocusNode"];
|
||||
if (node != null) {
|
||||
print("Node exists, requesting focus");
|
||||
node.requestFocus();
|
||||
}
|
||||
});
|
||||
|
||||
_addFocusListener(_iSeatPrefFocusNode, (focus) => _iSeatPrefFocus = focus);
|
||||
@ -1200,8 +1208,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
"First Name",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -1244,8 +1252,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
"Middle Name",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -1287,8 +1295,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
"Last Name",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -1339,8 +1347,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
"Nationality",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user