dashboard mobile
This commit is contained in:
parent
35229fa755
commit
0ec324bf03
@ -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,10 +490,9 @@ 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),
|
||||||
@ -498,7 +503,7 @@ class StatusDashboardState extends State<StatusDashboard> {
|
|||||||
Text(
|
Text(
|
||||||
count.toString(),
|
count.toString(),
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 18,
|
fontSize: isDesktop ? 18 : 16,
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
@ -506,15 +511,14 @@ class StatusDashboardState extends State<StatusDashboard> {
|
|||||||
const SizedBox(height: 5),
|
const SizedBox(height: 5),
|
||||||
Text(
|
Text(
|
||||||
label,
|
label,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: isDesktop ? 12 : 11,
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,24 +729,24 @@ 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: ConstrainedBox(
|
|
||||||
// constraints: BoxConstraints(
|
|
||||||
// minHeight: constraints.maxHeight,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
isLoading ? Center(child: CircularProgressIndicator()) :
|
||||||
|
LayoutBuilder(
|
||||||
|
builder: (context, constraints) {
|
||||||
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
// First Row: Toggle Buttons Row
|
// First Row: Toggle Buttons Row
|
||||||
@ -767,11 +771,11 @@ class StatusDashboardState extends State<StatusDashboard> {
|
|||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
// Second Row: Domestic & International and Status
|
// Second Row: Domestic & International and Status
|
||||||
Row(
|
isDesktop
|
||||||
|
? Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
// LEFT SIDE
|
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 2,
|
flex: 2,
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -794,9 +798,6 @@ class StatusDashboardState extends State<StatusDashboard> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
buildTopCard(
|
buildTopCard(
|
||||||
// icon: item['value'] == "Domestic"
|
|
||||||
// ? Icons.home
|
|
||||||
// : Icons.travel_explore,
|
|
||||||
color: item['value'] == "Domestic"
|
color: item['value'] == "Domestic"
|
||||||
? Color(0xFF0DB04B)
|
? Color(0xFF0DB04B)
|
||||||
: Color(0xFF004A8E),
|
: Color(0xFF004A8E),
|
||||||
@ -815,7 +816,6 @@ class StatusDashboardState extends State<StatusDashboard> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(width: 20),
|
const SizedBox(width: 20),
|
||||||
// RIGHT SIDE
|
|
||||||
Expanded(
|
Expanded(
|
||||||
flex: 3,
|
flex: 3,
|
||||||
child: Container(
|
child: Container(
|
||||||
@ -834,7 +834,85 @@ class StatusDashboardState extends State<StatusDashboard> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Text("Status",
|
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(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 19,
|
fontSize: 19,
|
||||||
color: Colors.black87,
|
color: Colors.black87,
|
||||||
@ -842,22 +920,24 @@ class StatusDashboardState extends State<StatusDashboard> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 23),
|
const SizedBox(height: 23),
|
||||||
Row(
|
Wrap(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
spacing: 10,
|
||||||
|
runSpacing: 10,
|
||||||
children: [
|
children: [
|
||||||
...statusData.map((item) => statusCard(item['value'], item['count'])).toList(),
|
...statusData.map((item) => statusCard(item['value'], item['count'], isDesktop)).toList(),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 20),
|
||||||
|
|
||||||
// Third Row: Flight, Accommodation, Forex
|
// Third Row: Flight, Accommodation, Forex
|
||||||
Row(
|
isDesktop
|
||||||
|
? Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Expanded(child: buildCategoryCard("Flight", Icons.flight, statusLabels, flightData)),
|
Expanded(child: buildCategoryCard("Flight", Icons.flight, statusLabels, flightData)),
|
||||||
@ -866,11 +946,39 @@ class StatusDashboardState extends State<StatusDashboard> {
|
|||||||
const SizedBox(width: 10),
|
const SizedBox(width: 10),
|
||||||
Expanded(child: buildCategoryCard("Forex", Icons.attach_money, statusLabels, forexData)),
|
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: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,6 +1759,8 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
isViewMode
|
isViewMode
|
||||||
? SystemMouseCursors.forbidden
|
? SystemMouseCursors.forbidden
|
||||||
: SystemMouseCursors.click,
|
: SystemMouseCursors.click,
|
||||||
|
child: Focus( // 👈 Wrap with Focus here
|
||||||
|
focusNode: submitButtonFocusNode,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
@ -1777,6 +1783,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
child: Text("Submit"),
|
child: Text("Submit"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,40 +1869,84 @@ 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 ||
|
||||||
|
event.logicalKey == LogicalKeyboardKey.numpadEnter)) {
|
||||||
_startDateFocusNode?.requestFocus();
|
_startDateFocusNode?.requestFocus();
|
||||||
await _selectCheckOutDate(context);
|
_selectCheckOutDate(context);
|
||||||
|
return KeyEventResult.handled; // Stop default behavior
|
||||||
|
}
|
||||||
|
return KeyEventResult.ignored; // Allow normal handling
|
||||||
|
},
|
||||||
|
child: GestureDetector(
|
||||||
|
behavior: HitTestBehavior.opaque,
|
||||||
|
onTapDown: (details) {
|
||||||
|
_startDateFocusNode?.requestFocus();
|
||||||
|
_selectCheckOutDate(context);
|
||||||
},
|
},
|
||||||
child: AbsorbPointer(
|
child: AbsorbPointer(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
focusNode: _startDateFocusNode,
|
|
||||||
controller: widget.controllers["delegationStartDate"],
|
controller: widget.controllers["delegationStartDate"],
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
style: const TextStyle(fontSize: 12),
|
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: "Select Date",
|
labelText: "Select Date",
|
||||||
labelStyle: const TextStyle(
|
labelStyle: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
suffixIcon: const Icon(
|
suffixIcon: Icon(
|
||||||
Icons.calendar_today,
|
Icons.calendar_today,
|
||||||
size: 16,
|
size: 16,
|
||||||
color: Colors.grey,
|
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) ...[
|
||||||
// SizedBox(height: 5), // Space before error message
|
// SizedBox(height: 5), // Space before error message
|
||||||
@ -1975,40 +2020,90 @@ 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 ||
|
||||||
|
event.logicalKey == LogicalKeyboardKey.numpadEnter)) {
|
||||||
|
if (!widget.isViewMode) {
|
||||||
|
_selectForexEndDate(context).then((_) {
|
||||||
_endDateFocusNode?.requestFocus();
|
_endDateFocusNode?.requestFocus();
|
||||||
await _selectForexEndDate(context);
|
});
|
||||||
|
}
|
||||||
|
return KeyEventResult.handled; // Stop default behavior
|
||||||
|
}
|
||||||
|
return KeyEventResult.ignored; // Allow normal handling
|
||||||
|
},
|
||||||
|
child: GestureDetector(
|
||||||
|
behavior: HitTestBehavior.opaque,
|
||||||
|
onTapDown: (details) {
|
||||||
|
if (!widget.isViewMode) {
|
||||||
|
_selectForexEndDate(context).then((_) {
|
||||||
|
_endDateFocusNode?.requestFocus();
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: AbsorbPointer(
|
child: AbsorbPointer(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
focusNode: _endDateFocusNode,
|
|
||||||
controller: widget.controllers["delegationEndDate"],
|
controller: widget.controllers["delegationEndDate"],
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
style: const TextStyle(fontSize: 12),
|
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: "Select Date",
|
labelText: "Select Date",
|
||||||
labelStyle: const TextStyle(
|
labelStyle: GoogleFonts.poppins(
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
color: Colors.grey,
|
color: Colors.grey,
|
||||||
),
|
),
|
||||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding: const EdgeInsets.symmetric(vertical: 16),
|
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||||
suffixIcon: const Icon(
|
suffixIcon: Icon(
|
||||||
Icons.calendar_today,
|
Icons.calendar_today,
|
||||||
size: 16,
|
size: 16,
|
||||||
color: Colors.grey,
|
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,
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
// if (widget.errorMessages["employeeCode"] != null) ...[
|
// if (widget.errorMessages["employeeCode"] != null) ...[
|
||||||
|
|||||||
@ -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,30 +1183,47 @@ 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 &&
|
||||||
|
(event.logicalKey == LogicalKeyboardKey.enter ||
|
||||||
|
event.logicalKey == LogicalKeyboardKey.numpadEnter)) {
|
||||||
|
if (!widget.isViewMode) {
|
||||||
|
_selectCheckDateOfBirth(context).then((_) {
|
||||||
if (widget.controllers["dob"]!.text.isNotEmpty) {
|
if (widget.controllers["dob"]!.text.isNotEmpty) {
|
||||||
setState(() {
|
|
||||||
// errorMessages.remove("start_date");
|
|
||||||
});
|
|
||||||
// Delay re-focusing the DOB field slightly
|
|
||||||
Future.delayed(Duration(milliseconds: 100), () {
|
Future.delayed(Duration(milliseconds: 100), () {
|
||||||
focusNodes["dobFocusNode"]?.requestFocus();
|
_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: AbsorbPointer(
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: widget.controllers["dob"],
|
controller: widget.controllers["dob"],
|
||||||
focusNode: focusNodes["dobFocusNode"],
|
|
||||||
readOnly: true,
|
readOnly: true,
|
||||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
@ -1198,6 +1246,48 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
// 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,
|
||||||
|
|||||||
@ -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),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user