dashboard mobile

This commit is contained in:
venba-Inspriron-3558 2025-07-17 12:02:27 +05:30
parent 35229fa755
commit 0ec324bf03
5 changed files with 647 additions and 339 deletions

View File

@ -30,6 +30,7 @@ class StatusDashboardState extends State<StatusDashboard> {
Map<String, dynamic>? apiData; Map<String, dynamic>? apiData;
String? organizationId; String? organizationId;
late bool _dialogShown = false; late bool _dialogShown = false;
bool isLoading = false;
late StreamSubscription<html.PopStateEvent> _popStateListener; late StreamSubscription<html.PopStateEvent> _popStateListener;
String selectedView = 'Today'; String selectedView = 'Today';
String AccessKeyFlag = "Both"; String AccessKeyFlag = "Both";
@ -148,6 +149,10 @@ class StatusDashboardState extends State<StatusDashboard> {
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
checkbackbutton(); checkbackbutton();
}); });
setState(() {
isLoading = true;
});
// If token exists, load the dashboard data // If token exists, load the dashboard data
loadDashboardData(); loadDashboardData();
} }
@ -157,6 +162,7 @@ class StatusDashboardState extends State<StatusDashboard> {
final data = await fetchStatusDashboard(); final data = await fetchStatusDashboard();
setState(() { setState(() {
apiData = data; apiData = data;
isLoading = false;
}); });
} catch (e) { } catch (e) {
print("Error loading dashboard: $e"); print("Error loading dashboard: $e");
@ -484,37 +490,35 @@ class StatusDashboardState extends State<StatusDashboard> {
); );
} }
Widget statusCard(String label, int count) { Widget statusCard(String label, int count, bool isDesktop) {
return Column( return Container(
children: [ width: isDesktop ? 120 : double.infinity,
Container( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15),
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 15), decoration: BoxDecoration(
decoration: BoxDecoration( color: const Color(0xFFEAF3FB),
color: const Color(0xFFEAF3FB), borderRadius: BorderRadius.circular(8),
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( const SizedBox(height: 5),
children: [ Text(
Text( label,
count.toString(), textAlign: TextAlign.center,
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
fontSize: 18, fontSize: isDesktop ? 12 : 11,
color: Colors.black87, color: Colors.black87,
fontWeight: FontWeight.bold, ),
),
),
const SizedBox(height: 5),
Text(
label,
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black87,
),
),
],
), ),
), ],
], ),
); );
} }
@ -725,152 +729,256 @@ class StatusDashboardState extends State<StatusDashboard> {
appBar: CustomAppBar(isDesktop: isDesktop), appBar: CustomAppBar(isDesktop: isDesktop),
drawer: CustomDrawer(isDesktop: false), drawer: CustomDrawer(isDesktop: false),
body: Padding( body: Padding(
padding: padding: isDesktop
isDesktop ? const EdgeInsets.symmetric(vertical: 5)
? EdgeInsets.symmetric( : EdgeInsets.zero,
horizontal: child: Center(
MediaQuery.of(context).size.width * child: ConstrainedBox(
0.1, // 30% of screen width as horizontal padding constraints: BoxConstraints(
vertical: 10, // 5% of screen height as vertical padding maxWidth: 1200,
) ),
: EdgeInsets.all(0), child: SingleChildScrollView(
child: LayoutBuilder( child: Padding(
builder: (context, constraints) { padding: const EdgeInsets.symmetric(horizontal: 15.0), // Scroll content padding
return SingleChildScrollView( child: Column(
// child: ConstrainedBox( crossAxisAlignment: CrossAxisAlignment.start,
// constraints: BoxConstraints( children: [
// minHeight: constraints.maxHeight, isLoading ? Center(child: CircularProgressIndicator()) :
// ), LayoutBuilder(
// ), builder: (context, constraints) {
child: Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, 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(
children: [ children: [
toggleChip("Today"), // First Row: Toggle Buttons Row
toggleChip("This Week"), Row(
], mainAxisAlignment: MainAxisAlignment.end,
),
),
],
),
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(
children: [ children: [
...typeData.map((item) { Container(
return Expanded( height: 36,
child: Column( decoration: BoxDecoration(
children: [ color: const Color(0xFFEAEAEA),
buildTopCard( borderRadius: BorderRadius.circular(20),
// icon: item['value'] == "Domestic" ),
// ? Icons.home child: Row(
// : Icons.travel_explore, children: [
color: item['value'] == "Domestic" toggleChip("Today"),
? Color(0xFF0DB04B) toggleChip("This Week"),
: Color(0xFF004A8E), ],
label: item['value'], ),
count: item['count'], ),
bgColor: item['value'] == "Domestic" ],
? const Color(0xFFD6FBE4) ),
: const Color(0xFFD9E8FF), 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),
), ),
], ],
), ),
); padding: const EdgeInsets.all(15),
}).toList(), 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 const SizedBox(height: 20),
Row(
crossAxisAlignment: CrossAxisAlignment.start, // Third Row: Flight, Accommodation, Forex
children: [ isDesktop
Expanded(child: buildCategoryCard("Flight", Icons.flight,statusLabels,flightData)), ? Row(
const SizedBox(width: 10), crossAxisAlignment: CrossAxisAlignment.start,
Expanded(child: buildCategoryCard("Accomodation", Icons.hotel_outlined,statusLabels,accommodationData)), children: [
const SizedBox(width: 10), Expanded(child: buildCategoryCard("Flight", Icons.flight, statusLabels, flightData)),
Expanded(child: buildCategoryCard("Forex", Icons.attach_money,statusLabels,forexData)), 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),
],
),
],
);
},
) ,
],
),
), ),
); ),
}, ),
), ),
), ),
), ),

View File

@ -11,6 +11,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:frontend/Screens/userManagement/create_user/personal_details.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/traveller_details.dart';
import 'package:frontend/Screens/userManagement/create_user/office_details.dart';
import 'package:frontend/utils/auth_utils.dart'; import 'package:frontend/utils/auth_utils.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
@ -30,7 +31,6 @@ import '../../../widgets/custom_text_field.dart';
import '../../../widgets/custom_text_forex.dart'; import '../../../widgets/custom_text_forex.dart';
import '../../../widgets/custom_user_form.dart'; import '../../../widgets/custom_user_form.dart';
import '../../../widgets/saving_loader.dart'; import '../../../widgets/saving_loader.dart';
import 'office_details.dart';
import 'package:universal_html/html.dart' as html; import 'package:universal_html/html.dart' as html;
@ -46,6 +46,8 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
GlobalKey<PersonalDetailsState>(); GlobalKey<PersonalDetailsState>();
final GlobalKey<TravellerDetailsState> travellerDetailsKey = final GlobalKey<TravellerDetailsState> travellerDetailsKey =
GlobalKey<TravellerDetailsState>(); GlobalKey<TravellerDetailsState>();
final GlobalKey<OfficeDetailsState> officeDetailsKey =
GlobalKey<OfficeDetailsState>();
// late List<Map<String, dynamic>?> travelDetailsData; // late List<Map<String, dynamic>?> travelDetailsData;
Map<String, dynamic>? travelDetailsData; Map<String, dynamic>? travelDetailsData;
@ -60,6 +62,9 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
bool isCheckingToken = false; bool isCheckingToken = false;
bool isDisable = false; bool isDisable = false;
final FocusNode submitButtonFocusNode = FocusNode();
String? token; String? token;
late bool isapiselectedUser = false; late bool isapiselectedUser = false;
@ -1448,7 +1453,6 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
selectedRole = role; selectedRole = role;
}); });
}, },
onServiceIdsChanged: (List<Map<String, dynamic>> updatedList) { onServiceIdsChanged: (List<Map<String, dynamic>> updatedList) {
setState(() { setState(() {
selectedServiceIds = updatedList; selectedServiceIds = updatedList;
@ -1755,26 +1759,29 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
isViewMode isViewMode
? SystemMouseCursors.forbidden ? SystemMouseCursors.forbidden
: SystemMouseCursors.click, : SystemMouseCursors.click,
child: ElevatedButton( child: Focus( // 👈 Wrap with Focus here
style: ElevatedButton.styleFrom( focusNode: submitButtonFocusNode,
backgroundColor: child: ElevatedButton(
isViewMode ? layoutColor : layoutColor, // Keep original color style: ElevatedButton.styleFrom(
foregroundColor: backgroundColor:
isViewMode isViewMode ? layoutColor : layoutColor, // Keep original color
? Colors.white foregroundColor:
: Colors.white, // Keep original color isViewMode
disabledBackgroundColor: ? Colors.white
layoutColor, // Ensure color remains when disabled : Colors.white, // Keep original color
disabledForegroundColor: Colors.white, disabledBackgroundColor:
shape: RoundedRectangleBorder( layoutColor, // Ensure color remains when disabled
borderRadius: BorderRadius.circular(8), disabledForegroundColor: Colors.white,
side: BorderSide(color: layoutColor, width: 2), 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"),
), ),
), ),
]; ];

View File

@ -58,10 +58,10 @@ class OfficeDetails extends StatefulWidget {
}) : super(key: key); }) : super(key: key);
@override @override
_OfficeDetailsState createState() => _OfficeDetailsState(); OfficeDetailsState createState() => OfficeDetailsState();
} }
class _OfficeDetailsState extends State<OfficeDetails> { class OfficeDetailsState extends State<OfficeDetails> {
final ApiService apiService = ApiService(); final ApiService apiService = ApiService();
late Map<String, String> countryMap; // Mapping country_code -> country_name late Map<String, String> countryMap; // Mapping country_code -> country_name
@ -169,6 +169,7 @@ class _OfficeDetailsState extends State<OfficeDetails> {
super.initState(); super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
loadInitialData(); loadInitialData();
_employeeCodeFocusNode.requestFocus();
}); });
apiCountryData = null; apiCountryData = null;
apiUserData = null; apiUserData = null;
@ -702,8 +703,8 @@ class _OfficeDetailsState extends State<OfficeDetails> {
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
borderSide: BorderSide( borderSide: BorderSide(
color: color:
(_departmentFocus ?? false) (_departmentFocus)
? (layoutColor ?? Colors.white) ? (layoutColor)
: Colors.white, : Colors.white,
width: 0.5, width: 0.5,
), ),
@ -711,8 +712,8 @@ class _OfficeDetailsState extends State<OfficeDetails> {
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: color:
(_departmentFocus ?? false) (_departmentFocus)
? (layoutColor ?? Colors.white) ? (layoutColor)
: Colors.white, : Colors.white,
width: 0.5, width: 0.5,
// const Color(0xFFD6D5E6), // const Color(0xFFD6D5E6),
@ -1868,39 +1869,83 @@ class _OfficeDetailsState extends State<OfficeDetails> {
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: GestureDetector( child:Focus(
// onTap: () async{ focusNode: _startDateFocusNode,
// _selectCheckOutDate(context); onKeyEvent: (FocusNode node, KeyEvent event) {
// // Only act on KeyDown and when Enter is pressed
// }, if (event is KeyDownEvent &&
onTap: () async { (event.logicalKey == LogicalKeyboardKey.enter ||
_startDateFocusNode?.requestFocus(); event.logicalKey == LogicalKeyboardKey.numpadEnter)) {
await _selectCheckOutDate(context); _startDateFocusNode?.requestFocus();
_selectCheckOutDate(context);
return KeyEventResult.handled; // Stop default behavior
}
return KeyEventResult.ignored; // Allow normal handling
}, },
child: AbsorbPointer( child: GestureDetector(
child: TextField( behavior: HitTestBehavior.opaque,
focusNode: _startDateFocusNode, onTapDown: (details) {
controller: widget.controllers["delegationStartDate"], _startDateFocusNode?.requestFocus();
readOnly: true, _selectCheckOutDate(context);
style: const TextStyle(fontSize: 12), },
decoration: InputDecoration( child: AbsorbPointer(
labelText: "Select Date", child: TextField(
labelStyle: const TextStyle( controller: widget.controllers["delegationStartDate"],
fontSize: 12, readOnly: true,
color: Colors.grey, style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
), decoration: InputDecoration(
floatingLabelBehavior: FloatingLabelBehavior.never, labelText: "Select Date",
border: InputBorder.none, labelStyle: GoogleFonts.poppins(
contentPadding: const EdgeInsets.symmetric(vertical: 16), fontSize: 12,
suffixIcon: const Icon( fontWeight: FontWeight.w400,
Icons.calendar_today, color: Colors.grey,
size: 16, ),
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) ...[ // if (errorMessages["start_date"] != null) ...[
@ -1975,39 +2020,89 @@ class _OfficeDetailsState extends State<OfficeDetails> {
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: GestureDetector( child:Focus(
// onTap: () async{ focusNode: _endDateFocusNode,
// _selectCheckOutDate(context); onKeyEvent: (FocusNode node, KeyEvent event) {
// // Only act on KeyDown and when Enter is pressed
// }, if (event is KeyDownEvent &&
onTap: () async { (event.logicalKey == LogicalKeyboardKey.enter ||
_endDateFocusNode?.requestFocus(); event.logicalKey == LogicalKeyboardKey.numpadEnter)) {
await _selectForexEndDate(context); if (!widget.isViewMode) {
_selectForexEndDate(context).then((_) {
_endDateFocusNode?.requestFocus();
});
}
return KeyEventResult.handled; // Stop default behavior
}
return KeyEventResult.ignored; // Allow normal handling
}, },
child: AbsorbPointer( child: GestureDetector(
child: TextField( behavior: HitTestBehavior.opaque,
focusNode: _endDateFocusNode, onTapDown: (details) {
controller: widget.controllers["delegationEndDate"], if (!widget.isViewMode) {
readOnly: true, _selectForexEndDate(context).then((_) {
style: const TextStyle(fontSize: 12), _endDateFocusNode?.requestFocus();
decoration: InputDecoration( });
labelText: "Select Date", }
labelStyle: const TextStyle( },
fontSize: 12, child: AbsorbPointer(
color: Colors.grey, child: TextField(
), controller: widget.controllers["delegationEndDate"],
floatingLabelBehavior: FloatingLabelBehavior.never, readOnly: true,
border: InputBorder.none, style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
contentPadding: const EdgeInsets.symmetric(vertical: 16), decoration: InputDecoration(
suffixIcon: const Icon( labelText: "Select Date",
Icons.calendar_today, labelStyle: GoogleFonts.poppins(
size: 16, fontSize: 12,
color: Colors.grey, 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,
// ),
// ),
// ),
// ),
// ),
), ),
), ),

View File

@ -35,6 +35,7 @@ class PersonalDetails extends StatefulWidget {
final String? selectedCountry; final String? selectedCountry;
final String? selectedRole; final String? selectedRole;
final String? userIdApi; final String? userIdApi;
final dynamic focusNodes;
// const PersonalDetails(this.isDesktop, this.isViewMode, {super.key},); // const PersonalDetails(this.isDesktop, this.isViewMode, {super.key},);
const PersonalDetails({ const PersonalDetails({
@ -50,6 +51,7 @@ class PersonalDetails extends StatefulWidget {
required this.isDesktop, required this.isDesktop,
required this.isViewMode, required this.isViewMode,
required this.apiselectedUser, required this.apiselectedUser,
this.focusNodes,
this.onGenderChanged, this.onGenderChanged,
this.onCountryChanged, this.onCountryChanged,
this.onRoleChanged, this.onRoleChanged,
@ -75,8 +77,32 @@ class PersonalDetailsState extends State<PersonalDetails> {
String? get selectedGenderValue => selectedGender; String? get selectedGenderValue => selectedGender;
String? get selectedCountryValue => selectedCountry; String? get selectedCountryValue => selectedCountry;
String? get selectedRoleValue => selectedRole; 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; late bool isTravelAgent = false;
@ -154,23 +180,26 @@ class PersonalDetailsState extends State<PersonalDetails> {
print("selectedServiceIdsAPI - $selectedServiceIds"); print("selectedServiceIdsAPI - $selectedServiceIds");
for (var field in dataHeader) {
focusNodes["${field}FocusNode"] = FocusNode();
focusStates["${field}Focused"] = false;
}
for (var key in focusNodes.keys) { _addFocusListener(_fnameFocusNode, (focus) => _fnameFocus = focus);
_addFocusListener(focusNodes[key]!, (focus) { _addFocusListener(_lnameFocusNode, (focus) => _lnameFocus = focus);
setState(() { _addFocusListener(_emailFocusNode, (focus) => _emailFocus = focus);
focusStates[key.replaceFirst("FocusNode", "Focused")] = 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((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
loadAllServices(); loadAllServices();
getOrganizationData(); getOrganizationData();
loadInitialData(); loadInitialData();
_fnameFocusNode.requestFocus();
}); });
} }
@ -802,13 +831,14 @@ class PersonalDetailsState extends State<PersonalDetails> {
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldUserWrapper( CustomTextFieldUserWrapper(
isFocused: focusStates["FnameFocused"] ?? false, isFocused: _fnameFocus,
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["FnameFocusNode"], // focusNode: focusNodes["FnameFocusNode"],
focusNode: _fnameFocusNode, // 👈 Use it here
controller: widget.controllers["Fname"], controller: widget.controllers["Fname"],
autofocus: true, autofocus: true,
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
@ -854,13 +884,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldUserWrapper( CustomTextFieldUserWrapper(
isFocused: focusStates["LnameFocused"] ?? false, isFocused: _lnameFocus,
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
style: TextStyle(fontSize: 12, color: Colors.black), style: TextStyle(fontSize: 12, color: Colors.black),
focusNode: focusNodes["LnameFocusNode"], focusNode: _lnameFocusNode,
autofocus: true, autofocus: true,
controller: widget.controllers["Lname"], controller: widget.controllers["Lname"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
@ -1006,21 +1036,21 @@ class PersonalDetailsState extends State<PersonalDetails> {
widget.isDesktop widget.isDesktop
? MediaQuery.of(context).size.width * 0.12 ? MediaQuery.of(context).size.width * 0.12
: null, : null,
isFocused: focusStates["genderFocused"] ?? false, isFocused: _genderFocus,
padding: const EdgeInsets.symmetric(horizontal: 0), padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: Focus( child: Focus(
focusNode: focusNodes["genderFocusNode"], focusNode: _genderFocusNode,
onFocusChange: (hasFocus) { onFocusChange: (hasFocus) {
setState(() { setState(() {
focusStates["genderFocused"] = hasFocus; _genderFocus = hasFocus;
}); });
}, },
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
focusNodes["genderFocusNode"]?.requestFocus(); _genderFocusNode?.requestFocus();
}, },
child: DropdownSearch<String>( child: DropdownSearch<String>(
selectedItem: selectedGender, selectedItem: selectedGender,
@ -1051,7 +1081,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
borderSide: BorderSide( borderSide: BorderSide(
color: color:
(focusStates["genderFocused"] ?? false) (_genderFocus)
? (layoutColor ?? Colors.blue) ? (layoutColor ?? Colors.blue)
: Colors.white, : Colors.white,
width: 0.5, width: 0.5,
@ -1060,7 +1090,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: color:
(focusStates["genderFocused"] ?? false) (_genderFocus)
? (layoutColor ?? Colors.blue) ? (layoutColor ?? Colors.blue)
: Colors.white, : Colors.white,
// : const Color(0xFFD6D5E6), // : const Color(0xFFD6D5E6),
@ -1069,7 +1099,8 @@ class PersonalDetailsState extends State<PersonalDetails> {
), ),
), ),
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color : (layoutColor ?? Colors.grey), width: 0.5), borderSide: BorderSide(
color : (layoutColor ?? Colors.grey), width: 0.5),
), ),
contentPadding: EdgeInsets.symmetric( contentPadding: EdgeInsets.symmetric(
horizontal: 10, horizontal: 10,
@ -1152,51 +1183,110 @@ class PersonalDetailsState extends State<PersonalDetails> {
widget.isDesktop widget.isDesktop
? MediaQuery.of(context).size.width * 0.12 ? MediaQuery.of(context).size.width * 0.12
: null, : null,
isFocused: focusStates["dobFocused"] ?? false, isFocused: _dobFocus,
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: GestureDetector( child:
onTap: Focus(
widget.isViewMode focusNode: _dobFocusNode,
? null onKeyEvent: (FocusNode node, KeyEvent event) {
: () async { // Only act on KeyDown and when Enter is pressed
await _selectCheckDateOfBirth(context); if (event is KeyDownEvent &&
if (widget.controllers["dob"]!.text.isNotEmpty) { (event.logicalKey == LogicalKeyboardKey.enter ||
setState(() { event.logicalKey == LogicalKeyboardKey.numpadEnter)) {
// errorMessages.remove("start_date"); if (!widget.isViewMode) {
}); _selectCheckDateOfBirth(context).then((_) {
// Delay re-focusing the DOB field slightly if (widget.controllers["dob"]!.text.isNotEmpty) {
Future.delayed(Duration(milliseconds: 100), () { Future.delayed(Duration(milliseconds: 100), () {
focusNodes["dobFocusNode"]?.requestFocus(); _dobFocusNode?.requestFocus();
}); });
} }
}, });
child: AbsorbPointer( }
child: TextField( return KeyEventResult.handled; // Stop default behavior
controller: widget.controllers["dob"], }
focusNode: focusNodes["dobFocusNode"], return KeyEventResult.ignored; // Allow normal handling
readOnly: true, },
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), child: GestureDetector(
decoration: InputDecoration( behavior: HitTestBehavior.opaque,
labelText: "Select Date", onTapDown: (details) {
labelStyle: GoogleFonts.poppins( if (!widget.isViewMode) {
fontSize: 12, _selectCheckDateOfBirth(context).then((_) {
fontWeight: FontWeight.w400, if (widget.controllers["dob"]!.text.isNotEmpty) {
color: Colors.grey, Future.delayed(Duration(milliseconds: 100), () {
), _dobFocusNode?.requestFocus();
floatingLabelBehavior: FloatingLabelBehavior.never, });
border: InputBorder.none, }
contentPadding: EdgeInsets.symmetric(vertical: 16), });
suffixIcon: Icon( }
Icons.calendar_today, },
size: 16, child: AbsorbPointer(
color: Color(0xFF8B8FB2), 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), SizedBox(height: 5),
CustomTextFieldUserWrapper( CustomTextFieldUserWrapper(
isFocused: focusStates["emailFocused"] ?? false, isFocused: _emailFocus,
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["emailFocusNode"], focusNode: _emailFocusNode,
autofocus: true, autofocus: true,
controller: widget.controllers["email"], controller: widget.controllers["email"],
onChanged: (value) { onChanged: (value) {
@ -1269,13 +1359,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldUserWrapper( CustomTextFieldUserWrapper(
isFocused: focusStates["mobileNumberFocused"] ?? false, isFocused: _mobileNumberFocus,
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["mobileNumberFocusNode"], focusNode: _mobileNumberFocusNode,
autofocus: true, autofocus: true,
controller: widget.controllers["mobileNumber"], controller: widget.controllers["mobileNumber"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
@ -1332,13 +1422,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldUserWrapper( CustomTextFieldUserWrapper(
isFocused: focusStates["alternateMobileFocused"] ?? false, isFocused: _alternateMobileFocus,
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["alternateMobileFocusNode"], focusNode: _alternateMobileFocusNode,
autofocus: true, autofocus: true,
controller: widget.controllers["alternateMobile"], controller: widget.controllers["alternateMobile"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
@ -1408,23 +1498,23 @@ class PersonalDetailsState extends State<PersonalDetails> {
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldUserWrapper( CustomTextFieldUserWrapper(
isFocused: focusStates["countryFocused"] ?? false, isFocused: _countryFocus,
padding: const EdgeInsets.symmetric(horizontal: 0), padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
width: double.infinity, width: double.infinity,
child: Focus( child: Focus(
focusNode: focusNodes["countryFocusNode"], focusNode: _countryFocusNode,
onFocusChange: (hasFocus) { onFocusChange: (hasFocus) {
setState(() { setState(() {
focusStates["countryFocused"] = hasFocus; _countryFocus = hasFocus;
}); });
}, },
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
// Request focus when user taps // Request focus when user taps
focusNodes["countryFocusNode"]?.requestFocus(); _countryFocusNode?.requestFocus();
}, },
child: DropdownSearch<String>( child: DropdownSearch<String>(
selectedItem: countryMap[selectedCountry], selectedItem: countryMap[selectedCountry],
@ -1461,7 +1551,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
borderSide: BorderSide( borderSide: BorderSide(
color: color:
(focusStates["countryFocused"] ?? false) (_countryFocus)
? (layoutColor ?? Colors.blue) ? (layoutColor ?? Colors.blue)
: Colors.white, : Colors.white,
width: 0.5, width: 0.5,
@ -1470,7 +1560,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: color:
(focusStates["countryFocused"] ?? false) (_countryFocus)
? (layoutColor ?? Colors.blue) ? (layoutColor ?? Colors.blue)
: Colors.white, : Colors.white,
width: 0.5, width: 0.5,
@ -1552,14 +1642,14 @@ class PersonalDetailsState extends State<PersonalDetails> {
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldUserWrapper( CustomTextFieldUserWrapper(
isFocused: focusStates["postalCodeFocused"] ?? false, isFocused: _postalCodeFocus,
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
autofocus: true, autofocus: true,
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["postalCodeFocusNode"], focusNode: _postalCodeFocusNode,
controller: widget.controllers["postalCode"], controller: widget.controllers["postalCode"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
keyboardType: TextInputType.numberWithOptions(decimal: true), keyboardType: TextInputType.numberWithOptions(decimal: true),
@ -1673,22 +1763,22 @@ class PersonalDetailsState extends State<PersonalDetails> {
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldUserWrapper( CustomTextFieldUserWrapper(
// isFocused: false, // isFocused: false,
isFocused: focusStates["roleIdFocusNode"] ?? false, isFocused: _roleIdFocus,
padding: const EdgeInsets.symmetric(horizontal: 0), padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: Focus( child: Focus(
focusNode: focusNodes["roleIdFocusNode"], focusNode: _roleIdFocusNode,
onFocusChange: (hasFocus) { onFocusChange: (hasFocus) {
setState(() { setState(() {
focusStates["roleIdFocused"] = hasFocus; _roleIdFocus = hasFocus;
}); });
}, },
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
// Request focus when user taps // Request focus when user taps
focusNodes["roleIdFocusNode"]?.requestFocus(); _roleIdFocusNode?.requestFocus();
}, },
child: DropdownSearch<String>( child: DropdownSearch<String>(
selectedItem: selectedRole != null ? roleMap[selectedRole] : null, selectedItem: selectedRole != null ? roleMap[selectedRole] : null,
@ -1726,7 +1816,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
borderRadius: BorderRadius.circular(5), borderRadius: BorderRadius.circular(5),
borderSide: BorderSide( borderSide: BorderSide(
color: color:
(focusStates["roleIdFocused"] ?? false) (_roleIdFocus)
? (layoutColor ?? Colors.blue) ? (layoutColor ?? Colors.blue)
: Colors.white, : Colors.white,
width: 0.5, width: 0.5,
@ -1735,7 +1825,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
enabledBorder: OutlineInputBorder( enabledBorder: OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: color:
(focusStates["roleIdFocused"] ?? false) (_roleIdFocus)
? (layoutColor ?? Colors.blue) ? (layoutColor ?? Colors.blue)
: Colors.white, : Colors.white,
// : const Color(0xFFD6D5E6), // : const Color(0xFFD6D5E6),
@ -1810,14 +1900,14 @@ class PersonalDetailsState extends State<PersonalDetails> {
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldUserWrapper( CustomTextFieldUserWrapper(
isFocused: focusStates["addressFocused"] ?? false, isFocused: _addressFocus,
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 80, height: 80,
child: TextField( child: TextField(
autofocus: true, autofocus: true,
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["addressFocusNode"], focusNode: _addressFocusNode,
controller: widget.controllers["address"], controller: widget.controllers["address"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
maxLines: 2, maxLines: 2,
@ -1854,13 +1944,13 @@ class PersonalDetailsState extends State<PersonalDetails> {
), ),
SizedBox(height: 5), SizedBox(height: 5),
CustomTextFieldUserWrapper( CustomTextFieldUserWrapper(
isFocused: focusStates["passwordFocused"] ?? false, isFocused: _passwordFocus,
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: TextField( child: TextField(
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
focusNode: focusNodes["passwordFocusNode"], focusNode: _passwordFocusNode,
autofocus: true, autofocus: true,
controller: widget.controllers["password"], controller: widget.controllers["password"],
enabled: !widget.isViewMode, enabled: !widget.isViewMode,

View File

@ -169,6 +169,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
fetchApiData(); fetchApiData();
// Delay adding the row until after the first frame // Delay adding the row until after the first frame
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
// focusNodes["FnameFocusNode"]?.requestFocus();
setState(() { setState(() {
addHotelLoyaltyEntry(); addHotelLoyaltyEntry();
addFrequentFlierEntry(); addFrequentFlierEntry();
@ -176,6 +177,13 @@ class TravellerDetailsState extends State<TravellerDetails> {
loadInitialData(); loadInitialData();
}); });
updateTravel(); 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); _addFocusListener(_iSeatPrefFocusNode, (focus) => _iSeatPrefFocus = focus);
@ -1200,8 +1208,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
"First Name", "First Name",
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w600,
color: Colors.black, color: Color(0xFF575A74),
), ),
), ),
SizedBox(height: 5), SizedBox(height: 5),
@ -1244,8 +1252,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
"Middle Name", "Middle Name",
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w600,
color: Colors.black, color: Color(0xFF575A74),
), ),
), ),
SizedBox(height: 5), SizedBox(height: 5),
@ -1287,8 +1295,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
"Last Name", "Last Name",
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w600,
color: Colors.black, color: Color(0xFF575A74),
), ),
), ),
SizedBox(height: 5), SizedBox(height: 5),
@ -1339,8 +1347,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
"Nationality", "Nationality",
style: GoogleFonts.poppins( style: GoogleFonts.poppins(
fontSize: 12, fontSize: 12,
fontWeight: FontWeight.w400, fontWeight: FontWeight.w600,
color: Colors.black, color: Color(0xFF575A74),
), ),
), ),
SizedBox(height: 5), SizedBox(height: 5),