user management
This commit is contained in:
parent
12310625ef
commit
4435eeadd3
BIN
assets/images/login/logoNew.jpg
Normal file
BIN
assets/images/login/logoNew.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.1 KiB |
@ -383,9 +383,8 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -510,9 +509,8 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -531,30 +529,37 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: const [
|
||||
Icon(Icons.error_outline,
|
||||
children: [
|
||||
const Icon(Icons.error_outline,
|
||||
color: Colors.redAccent, size: 60),
|
||||
SizedBox(height: 1),
|
||||
Text("Oops!",
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.redAccent)),
|
||||
SizedBox(height: 15),
|
||||
Text("No Trips",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black54)),
|
||||
SizedBox(height: 10),
|
||||
Text("Please Create Trip",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontFamily: "Inter",
|
||||
fontSize: 12,
|
||||
color: Colors.grey)),
|
||||
const SizedBox(height: 1),
|
||||
Text(
|
||||
"Oops!",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.redAccent),
|
||||
// style: TextStyle(
|
||||
// fontSize: 22,
|
||||
// fontWeight: FontWeight.bold,
|
||||
// color: Colors.redAccent)
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Text(
|
||||
"No Trips",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black54),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
"Please Create Trip",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12, color: Colors.grey),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -586,58 +591,55 @@ class _ListAllPlansState extends State<ListAllPlans> {
|
||||
horizontalInside: BorderSide(
|
||||
width: 0.5, color: Colors.grey.shade200),
|
||||
),
|
||||
columns: const [
|
||||
columns: [
|
||||
DataColumn(
|
||||
label: Text('Trip Id',
|
||||
style: TextStyle(
|
||||
// color: Colors.grey,
|
||||
// color: Color(0xFF9E9DBD),
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip ID',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Trip Name',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip Name',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Employee Code',
|
||||
style: TextStyle(
|
||||
// color: Color(0xFF9E9DBD),
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Emp Code',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Traveller',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Traveller',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Trip Type',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip Type',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Created On',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Created On',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Status',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Status',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Actions',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Actions',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
],
|
||||
rows: paginatedPlans.map((plan) {
|
||||
return DataRow(cells: [
|
||||
|
||||
@ -435,9 +435,8 @@ class _TravelAgentListPlansState extends State<TravelAgentListPlans> {
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -468,7 +467,7 @@ class _TravelAgentListPlansState extends State<TravelAgentListPlans> {
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.redAccent)),
|
||||
SizedBox(height: 20),
|
||||
Text("No Approvals",
|
||||
Text("No Trips Pending For Your Approvals",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
@ -514,58 +513,55 @@ class _TravelAgentListPlansState extends State<TravelAgentListPlans> {
|
||||
horizontalInside: BorderSide(
|
||||
width: 0.5, color: Colors.grey.shade200),
|
||||
),
|
||||
columns: const [
|
||||
columns: [
|
||||
DataColumn(
|
||||
label: Text('Trip Id',
|
||||
style: TextStyle(
|
||||
// color: Colors.grey,
|
||||
// color: Color(0xFF9E9DBD),
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip ID',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Trip Name',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip Name',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Employee Code',
|
||||
style: TextStyle(
|
||||
// color: Color(0xFF9E9DBD),
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Emp Code',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Traveller',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Traveller',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Trip Type',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip Type',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Created On',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Created On',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Status',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Status',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Actions',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Actions',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
],
|
||||
rows: paginatedPlans.map((plan) {
|
||||
return DataRow(cells: [
|
||||
|
||||
@ -434,9 +434,8 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -482,9 +481,8 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -516,7 +514,7 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.redAccent)),
|
||||
SizedBox(height: 15),
|
||||
Text("No Approvals",
|
||||
Text("No Trips Pending For Your Approvals",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
@ -554,57 +552,55 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
horizontalInside: BorderSide(
|
||||
width: 0.5, color: Colors.grey.shade200),
|
||||
),
|
||||
columns: const [
|
||||
columns: [
|
||||
DataColumn(
|
||||
label: Text('Trip Id',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip ID',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Trip Name',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip Name',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Employee Code',
|
||||
style: TextStyle(
|
||||
// color: Color(0xFF9E9DBD),
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Emp Code',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Traveller',
|
||||
style: TextStyle(
|
||||
// color: Color(0xFF9E9DBD),
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Traveller',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Trip Type',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip Type',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Created On',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Created On',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Status',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Status',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Actions',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Actions',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
],
|
||||
rows: paginatedPlans.map((plan) {
|
||||
return DataRow(cells: [
|
||||
|
||||
@ -260,11 +260,11 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 30),
|
||||
padding: const EdgeInsets.only(left: 0),
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Image.asset(
|
||||
'assets/images/login/TravelSpendsLogo1.png',
|
||||
'assets/images/login/logoNew.jpg',
|
||||
width: 200, // Optional: control size
|
||||
height: 100,
|
||||
fit: BoxFit.contain,
|
||||
@ -676,36 +676,76 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
const SizedBox(height: 20),
|
||||
if (!_isForgotPassword && !_showOtpResetFields)
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/images/login/microsoft.png',
|
||||
width: 30, // Optional: control size
|
||||
height: 30,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Container(
|
||||
width: 30, // Adjust size
|
||||
height: 30,
|
||||
decoration: BoxDecoration(
|
||||
// Background color
|
||||
shape: BoxShape.rectangle,
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
border: Border.all(
|
||||
color: Color(0xFF9E9DBD), width: 1), // Grey outline
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () => (),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.white, // Button color
|
||||
foregroundColor: Colors.black, // Text color
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 24, vertical: 5),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
side: BorderSide(
|
||||
color: Colors.black, // Border color
|
||||
width: 0.5, // Border width
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 24, vertical: 5),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
"Sign In With Microsoft",
|
||||
style: TextStyle(
|
||||
fontFamily: "Nunito",
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 15),
|
||||
),
|
||||
SizedBox(
|
||||
width: 3,
|
||||
),
|
||||
Image.asset(
|
||||
'assets/images/login/microsoft.png',
|
||||
width: 30, // Optional: control size
|
||||
height: 30,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
child: Center(
|
||||
child: Image.asset(
|
||||
'assets/images/login/VectorG.png',
|
||||
width: 20, // Optional: control size
|
||||
height: 20,
|
||||
fit: BoxFit.contain,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: [
|
||||
// Container(
|
||||
// width: 30, // Adjust size
|
||||
// height: 30,
|
||||
// decoration: BoxDecoration(
|
||||
// // Background color
|
||||
// shape: BoxShape.rectangle,
|
||||
// borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
// border: Border.all(
|
||||
// color: Color(0xFF9E9DBD), width: 1), // Grey outline
|
||||
// ),
|
||||
//
|
||||
// child: Center(
|
||||
// child: Image.asset(
|
||||
// 'assets/images/login/VectorG.png',
|
||||
// width: 20, // Optional: control size
|
||||
// height: 20,
|
||||
// fit: BoxFit.contain,
|
||||
// )),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@ -323,7 +323,8 @@ class _groupState extends State<Group> {
|
||||
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
// backgroundColor: Colors.white,
|
||||
backgroundColor: Color(0xFFf5f5f5),
|
||||
appBar: CustomAppBar(isDesktop: isDesktop),
|
||||
drawer: CustomDrawer(isDesktop: false),
|
||||
body: Padding(
|
||||
@ -348,15 +349,11 @@ class _groupState extends State<Group> {
|
||||
|
||||
Widget buildData(bool isDesktop, context) {
|
||||
return Container(
|
||||
// margin: const EdgeInsets.only(left: 10.0, right: 15.0, top: 10.0, bottom: 10.0),
|
||||
// decoration: BoxDecoration(
|
||||
// // color: Colors.amber,
|
||||
// // color: bodyColor,
|
||||
// color: Color(0xFFE1F5FE),
|
||||
// border: Border.all(
|
||||
// color: Colors.white,
|
||||
// // color: Color(0xFFF7F7FB),
|
||||
// width: 3.5)),
|
||||
margin: isDesktop ? const EdgeInsets.only(top: 10.0, bottom: 10.0) : null,
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: isDesktop ? Colors.white : Color(0xFFFCFCFC),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
|
||||
@ -131,7 +131,8 @@ class _GroupListState extends State<GroupList> {
|
||||
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
// backgroundColor: Colors.white,
|
||||
backgroundColor: Color(0xFFf5f5f5),
|
||||
appBar: CustomAppBar(isDesktop: isDesktop),
|
||||
drawer: CustomDrawer(isDesktop: false),
|
||||
body: Padding(
|
||||
@ -156,6 +157,11 @@ class _GroupListState extends State<GroupList> {
|
||||
|
||||
Widget buildGroupListLayout(bool isDesktop) {
|
||||
return Container(
|
||||
margin: isDesktop ? const EdgeInsets.only(top: 10.0, bottom: 10.0) : null,
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: isDesktop ? Colors.white : Color(0xFFFCFCFC),
|
||||
),
|
||||
// decoration: BoxDecoration(
|
||||
// // color: Colors.amber,
|
||||
// // color: bodyColor,
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
@ -419,7 +420,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Destination",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -467,7 +468,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Hotel Name",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -671,7 +672,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Check-in*",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -723,7 +724,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Time (Check-in)",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -775,7 +776,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Check-out*",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -827,7 +828,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Time (Check-out)",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -878,7 +879,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Comments",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -939,7 +940,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Close",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 14),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10), // Space between buttons
|
||||
@ -958,7 +959,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Save Changes",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 14),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
@ -273,9 +274,9 @@ class _BusScreenState extends State<BusScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Trip Type",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -401,9 +402,9 @@ class _BusScreenState extends State<BusScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"From",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -446,9 +447,9 @@ class _BusScreenState extends State<BusScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"To",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -491,9 +492,9 @@ class _BusScreenState extends State<BusScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Date",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -543,9 +544,9 @@ class _BusScreenState extends State<BusScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Time",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -594,9 +595,9 @@ class _BusScreenState extends State<BusScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Comments",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -650,7 +651,7 @@ class _BusScreenState extends State<BusScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Close",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10), // Space between buttons
|
||||
@ -669,7 +670,7 @@ class _BusScreenState extends State<BusScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Save Changes",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frontend/services/apiService.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
@ -731,7 +732,7 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Trip Type",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1122,68 +1123,12 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
// selectedCountry ??= null;
|
||||
|
||||
return [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
selectedTripType == "Oneway" ? "Class *" : "Class $index *",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: focusStates["_class${index}Focused"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
// width: isDesktop
|
||||
// ? MediaQuery.of(context).size.width * 0.34
|
||||
// : MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: isCountryLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: DropdownButtonFormField<String>(
|
||||
focusNode: focusNodes["_class${index}FocusNode"],
|
||||
// focusNode: _tripTypeFocusNode, // Assign the correct focus node
|
||||
// controller: _hotelNameController,
|
||||
value: selectedClasses[index],
|
||||
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 10), // Proper padding
|
||||
),
|
||||
onChanged: purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedClasses[index] = newValue;
|
||||
});
|
||||
|
||||
print(selectedClasses[index]);
|
||||
}
|
||||
: null,
|
||||
items: dropdownItems,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
SizedBox(
|
||||
width: 20,
|
||||
)
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"From",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1284,7 +1229,9 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
SizedBox(
|
||||
width: 20,
|
||||
)
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
@ -1294,7 +1241,7 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"To",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1370,6 +1317,60 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
],
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Class *",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: focusStates["_class${index}Focused"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
// width: isDesktop
|
||||
// ? MediaQuery.of(context).size.width * 0.34
|
||||
// : MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: isCountryLoading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: DropdownButtonFormField<String>(
|
||||
focusNode: focusNodes["_class${index}FocusNode"],
|
||||
// focusNode: _tripTypeFocusNode, // Assign the correct focus node
|
||||
// controller: _hotelNameController,
|
||||
value: selectedClasses[index],
|
||||
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 10), // Proper padding
|
||||
),
|
||||
onChanged: purposeList.isNotEmpty
|
||||
? (newValue) {
|
||||
setState(() {
|
||||
selectedClasses[index] = newValue;
|
||||
});
|
||||
|
||||
print(selectedClasses[index]);
|
||||
}
|
||||
: null,
|
||||
items: dropdownItems,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
else
|
||||
@ -1381,7 +1382,7 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Date",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1435,7 +1436,7 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Time",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1526,7 +1527,7 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Visa Required",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1583,7 +1584,7 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Comments",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1721,7 +1722,7 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Close",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10), // Space between buttons
|
||||
@ -1740,7 +1741,7 @@ class _FlightScreenState extends State<FlightScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Save Changes",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
@ -3,6 +3,7 @@ import 'dart:convert';
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@ -412,13 +413,50 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
(data["end_date"]?.isNotEmpty ?? false);
|
||||
}
|
||||
|
||||
// Check if all required fields have data
|
||||
bool _isForexDataDurationComplete() {
|
||||
final data = getForexData;
|
||||
return (data["start_date"]?.isNotEmpty ?? false) &&
|
||||
(data["end_date"]?.isNotEmpty ?? false);
|
||||
}
|
||||
|
||||
// Handle field changes
|
||||
void _onFieldChanged() {
|
||||
if (_isForexDataDurationComplete()) {
|
||||
CalculateDuration();
|
||||
}
|
||||
|
||||
if (_isForexDataComplete()) {
|
||||
postgetForexData(getForexData);
|
||||
}
|
||||
}
|
||||
|
||||
void CalculateDuration() {
|
||||
final data = getForexData;
|
||||
final startDateString = data["start_date"];
|
||||
final endDateString = data["end_date"];
|
||||
|
||||
if (startDateString == null || endDateString == null) return;
|
||||
|
||||
try {
|
||||
// Parse the dates from string
|
||||
final startDate = DateFormat('d/M/yyyy').parse(startDateString);
|
||||
final endDate = DateFormat('d/M/yyyy').parse(endDateString);
|
||||
|
||||
// Calculate difference
|
||||
final durationInDays =
|
||||
endDate.difference(startDate).inDays + 1; // +1 to include both days
|
||||
|
||||
// You can now use durationInDays however you want:
|
||||
print("Duration: $durationInDays days");
|
||||
|
||||
// Optionally, you might want to update some data:
|
||||
selectedDuration = durationInDays as String?;
|
||||
} catch (e) {
|
||||
print('Error parsing dates: $e');
|
||||
}
|
||||
}
|
||||
|
||||
// Handle dropdown change
|
||||
void _onCountryChanged(String? newCountry) {
|
||||
setState(() {
|
||||
@ -498,6 +536,12 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
|
||||
int? enteredAmount = int.tryParse(value);
|
||||
|
||||
int? quotedAmount = int.tryParse(selectedQuotedAmount!);
|
||||
int? difference = quotedAmount! - enteredAmount!;
|
||||
|
||||
print("Difference - $difference");
|
||||
textControllers["_card"]?.text = difference.toString();
|
||||
|
||||
if (enteredAmount == null || enteredAmount > fifteenPercent) {
|
||||
errorMessages["deposit_on_cash"] = "Amount cannot exceed $fifteenPercent";
|
||||
} else {
|
||||
@ -583,43 +627,37 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
// _buildSecondRow(isDesktop)
|
||||
// ];
|
||||
|
||||
List<Widget> rowBuilders = [
|
||||
..._builClassType(isDesktop), // Spread the List<Widget>
|
||||
Divider(),
|
||||
..._buildSecondRow(isDesktop), // Spread the List<Widget>
|
||||
];
|
||||
|
||||
return [
|
||||
...buildResponsiveRow(_buildFirstRow(isDesktop)),
|
||||
SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
"Forex Details",
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
),
|
||||
// Align(
|
||||
// alignment: Alignment.centerLeft,
|
||||
// child: Text(
|
||||
// "Forex Details",
|
||||
// style: TextStyle(
|
||||
// fontSize: 13,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Color(0xFF575A74)),
|
||||
// ),
|
||||
// ),
|
||||
// SizedBox(
|
||||
// height: 8,
|
||||
// ),
|
||||
Divider(
|
||||
thickness: 0.3,
|
||||
),
|
||||
SizedBox(
|
||||
height: 3,
|
||||
),
|
||||
// Divider(
|
||||
// thickness: 0.3,
|
||||
// ),
|
||||
// SizedBox(
|
||||
// height: 3,
|
||||
// ),
|
||||
...buildResponsiveRow(_builClassType(isDesktop)),
|
||||
SizedBox(
|
||||
height: 3,
|
||||
),
|
||||
Divider(
|
||||
thickness: 0.3,
|
||||
),
|
||||
// SizedBox(
|
||||
// height: 3,
|
||||
// ),
|
||||
// Divider(
|
||||
// thickness: 0.3,
|
||||
// ),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
@ -646,6 +684,8 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
initialDate = DateTime.parse(flightFirstTripDateNotifier.value!);
|
||||
textControllers["_forexStartDate"]?.text =
|
||||
DateFormat('yyyy-MM-dd').format(initialDate);
|
||||
textControllers["_forexStartDate"]?.text =
|
||||
DateFormat('dd-MM-yyyy').format(initialDate);
|
||||
} catch (e) {
|
||||
initialDate = today;
|
||||
}
|
||||
@ -731,40 +771,19 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
_selectedEndDate = pickedDate;
|
||||
textControllers["_forexEndDate"]?.text =
|
||||
DateFormat('yyyy-MM-dd').format(pickedDate);
|
||||
// textControllers["_forexEndDate"]?.text =
|
||||
// DateFormat('dd-MM-yyyy').format(initialDate);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
late Map<String, String> countryMap; // Mapping country_code -> country_name
|
||||
late List<String> countryCodes; // List of country codes
|
||||
|
||||
countryList = widget.apiCountryData ?? [];
|
||||
|
||||
// Map country codes to country names
|
||||
countryMap = {
|
||||
for (var item in countryList)
|
||||
item['country_code'] as String: item['country_name'] as String
|
||||
};
|
||||
|
||||
// Extract only country codes for processing
|
||||
countryCodes = countryMap.keys.toList();
|
||||
|
||||
selectedCountry ??= null;
|
||||
|
||||
// // Set default selected value
|
||||
// if (selectedCountry == null && countryCodes.isNotEmpty) {
|
||||
// selectedCountry = countryCodes.first;
|
||||
// }
|
||||
|
||||
// -------------------------- End Selected Country Dropdown --------------------------------------
|
||||
|
||||
return [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Start Date",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -843,7 +862,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"End Date",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -919,92 +938,19 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Countries",
|
||||
style: TextStyle(
|
||||
"Durartion",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: focusStates["_countries"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem: countryMap[selectedCountry],
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true, // Enables search functionality
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Country...",
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
items: countryMap.values.toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) => Align(
|
||||
// Center-align selected item
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select Country",
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
// Find the country_code based on selected country_name
|
||||
selectedCountry = countryMap.entries
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
_onCountryChanged(selectedCountry);
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["country_code"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
"Select Country",
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
List<Widget> _builClassType(bool isDesktop) {
|
||||
return [
|
||||
// if (isDesktop) Spacer() else SizedBox(
|
||||
// height: 8,
|
||||
// ),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Durartion",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: focusStates["_durationFocused"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
color: Colors.transparent,
|
||||
child: SizedBox(
|
||||
height: 30,
|
||||
height: 40,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
@ -1028,11 +974,114 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
List<Widget> _builClassType(bool isDesktop) {
|
||||
late Map<String, String> countryMap; // Mapping country_code -> country_name
|
||||
late List<String> countryCodes; // List of country codes
|
||||
|
||||
countryList = widget.apiCountryData ?? [];
|
||||
|
||||
// Map country codes to country names
|
||||
countryMap = {
|
||||
for (var item in countryList)
|
||||
item['country_code'] as String: item['country_name'] as String
|
||||
};
|
||||
|
||||
// Extract only country codes for processing
|
||||
countryCodes = countryMap.keys.toList();
|
||||
|
||||
selectedCountry ??= null;
|
||||
|
||||
// // Set default selected value
|
||||
// if (selectedCountry == null && countryCodes.isNotEmpty) {
|
||||
// selectedCountry = countryCodes.first;
|
||||
// }
|
||||
|
||||
// -------------------------- End Selected Country Dropdown --------------------------------------
|
||||
|
||||
return [
|
||||
// if (isDesktop) Spacer() else SizedBox(
|
||||
// height: 8,
|
||||
// ),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Country",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: focusStates["_countries"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem: countryMap[selectedCountry],
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true, // Enables search functionality
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Country...",
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
items: countryMap.values.toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) => Align(
|
||||
// Center-align selected item
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select Country",
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
onChanged: (String? newValue) {
|
||||
setState(() {
|
||||
// Find the country_code based on selected country_name
|
||||
selectedCountry = countryMap.entries
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
_onCountryChanged(selectedCountry);
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
if (errorMessages["country_code"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
"Select Country",
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
// if (isDesktop)SizedBox(width: 8,) else SizedBox(
|
||||
// height: 8,
|
||||
// ),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.048,
|
||||
)
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
@ -1042,21 +1091,21 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Currency *",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: focusStates["_currencyFocused"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
color: Colors.transparent,
|
||||
width: isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.330
|
||||
: MediaQuery.of(context).size.width * 0.66,
|
||||
// width: isDesktop
|
||||
// ? MediaQuery.of(context).size.width * 0.330
|
||||
// : MediaQuery.of(context).size.width * 0.66,
|
||||
child: SizedBox(
|
||||
height: 30,
|
||||
height: 40,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Center(
|
||||
@ -1088,18 +1137,18 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Perdiem Amount",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: focusStates["_perdiemAmount"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
color: Colors.transparent,
|
||||
child: SizedBox(
|
||||
height: 30,
|
||||
height: 35,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
@ -1136,46 +1185,74 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
|
||||
List<Widget> _buildSecondRow(bool isDesktop) {
|
||||
return [
|
||||
if (isDesktop) Spacer(),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Transport",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: focusStates["_transport"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_transport"],
|
||||
controller: textControllers["_transport"],
|
||||
onChanged: (value) => _onFieldChangedForOthers(),
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(
|
||||
r'^\d*\.?\d*$')), // Allow only positive numbers with optional decimal
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Transport",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
color: Colors.yellow.shade50,
|
||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.07 : null,
|
||||
height: 30,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_transport"],
|
||||
controller: textControllers["_transport"],
|
||||
onChanged: (value) => _onFieldChangedForOthers(),
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(
|
||||
r'^\d*\.?\d*$')), // Allow only positive numbers with optional decimal
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "0",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.black),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
// CustomTextFieldItnerarySubWrapper(
|
||||
// width: isDesktop ? MediaQuery.of(context).size.width * 0.07 : null,
|
||||
// isFocused: focusStates["_transport"] ?? false,
|
||||
// isDesktop: isDesktop,
|
||||
// child: SizedBox(
|
||||
// height: 40,
|
||||
// child: TextField(
|
||||
// focusNode: focusNodes["_transport"],
|
||||
// controller: textControllers["_transport"],
|
||||
// onChanged: (value) => _onFieldChangedForOthers(),
|
||||
// keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
// inputFormatters: [
|
||||
// FilteringTextInputFormatter.allow(RegExp(
|
||||
// r'^\d*\.?\d*$')), // Allow only positive numbers with optional decimal
|
||||
// ],
|
||||
// style: const TextStyle(fontSize: 12),
|
||||
// decoration: const InputDecoration(
|
||||
// labelText: "Transport",
|
||||
// labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
// floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
// border: InputBorder.none,
|
||||
// contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
SizedBox(
|
||||
width: 10,
|
||||
)
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
@ -1185,41 +1262,68 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Accomodation",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: focusStates["_accomodation"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_accomodation"],
|
||||
controller: textControllers["_accomodation"],
|
||||
onChanged: (value) => _onFieldChangedForOthers(),
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(
|
||||
r'^\d*\.?\d*$')), // Allow only positive numbers with optional decimal
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Accomodation",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
color: Colors.yellow.shade50,
|
||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.07 : null,
|
||||
height: 30,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_accomodation"],
|
||||
controller: textControllers["_accomodation"],
|
||||
onChanged: (value) => _onFieldChangedForOthers(),
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(
|
||||
r'^\d*\.?\d*$')), // Allow only positive numbers with optional decimal
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "0",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.black),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
// CustomTextFieldItnerarySubWrapper(
|
||||
// width: isDesktop ? MediaQuery.of(context).size.width * 0.07 : null,
|
||||
// isFocused: focusStates["_accomodation"] ?? false,
|
||||
// isDesktop: isDesktop,
|
||||
// child: SizedBox(
|
||||
// height: 40,
|
||||
// child: TextField(
|
||||
// focusNode: focusNodes["_accomodation"],
|
||||
// controller: textControllers["_accomodation"],
|
||||
// onChanged: (value) => _onFieldChangedForOthers(),
|
||||
// keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
// inputFormatters: [
|
||||
// FilteringTextInputFormatter.allow(RegExp(
|
||||
// r'^\d*\.?\d*$')), // Allow only positive numbers with optional decimal
|
||||
// ],
|
||||
// style: const TextStyle(fontSize: 12),
|
||||
// decoration: const InputDecoration(
|
||||
// labelText: "Accomodation",
|
||||
// labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
// floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
// border: InputBorder.none,
|
||||
// contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
SizedBox(
|
||||
width: 10,
|
||||
)
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
@ -1229,17 +1333,18 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Telephone",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
isFocused: focusStates["_telephone"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
Container(
|
||||
color: Colors.yellow.shade50,
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
width:
|
||||
isDesktop ? MediaQuery.of(context).size.width * 0.06 : null,
|
||||
height: 30,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_telephone"],
|
||||
controller: textControllers["_telephone"],
|
||||
@ -1251,19 +1356,45 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
],
|
||||
style: const TextStyle(fontSize: 12),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Telephone",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
labelText: "0",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.black),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
))
|
||||
// CustomTextFieldItnerarySubWrapper(
|
||||
// width: isDesktop ? MediaQuery.of(context).size.width * 0.07 : null,
|
||||
// isFocused: focusStates["_telephone"] ?? false,
|
||||
// isDesktop: isDesktop,
|
||||
// child: SizedBox(
|
||||
// height: 40,
|
||||
// child: TextField(
|
||||
// focusNode: focusNodes["_telephone"],
|
||||
// controller: textControllers["_telephone"],
|
||||
// onChanged: (value) => _onFieldChangedForOthers(),
|
||||
// keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
// inputFormatters: [
|
||||
// FilteringTextInputFormatter.allow(RegExp(
|
||||
// r'^\d*\.?\d*$')), // Allow only positive numbers with optional decimal
|
||||
// ],
|
||||
// style: const TextStyle(fontSize: 12),
|
||||
// decoration: const InputDecoration(
|
||||
// labelText: "Telephone",
|
||||
// labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
// floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
// border: InputBorder.none,
|
||||
// contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Spacer()
|
||||
SizedBox(
|
||||
width: 40,
|
||||
)
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
@ -1273,18 +1404,18 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Other Expenses",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: isDesktop,
|
||||
color: Colors.transparent,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
height: 35,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
@ -1340,17 +1471,17 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Cash*",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: focusStates["_cash"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
height: 35,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_cash"],
|
||||
controller: textControllers["_cash"],
|
||||
@ -1382,9 +1513,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
|
||||
if (isDesktop)
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.035,
|
||||
)
|
||||
Spacer()
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
@ -1395,17 +1524,17 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Card*",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: focusStates["_card"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
height: 35,
|
||||
child: TextField(
|
||||
focusNode: focusNodes["_card"],
|
||||
controller: textControllers["_card"],
|
||||
@ -1436,9 +1565,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
|
||||
if (isDesktop)
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.035,
|
||||
)
|
||||
Spacer()
|
||||
else
|
||||
SizedBox(
|
||||
height: 8,
|
||||
@ -1449,18 +1576,18 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Total Amount",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: focusStates["_perdiemAmount"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
color: Colors.transparent,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
height: 35,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
@ -1468,16 +1595,83 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
selectedQuotedAmount ?? "0",
|
||||
// selectedPerdiemAmount?.isNotEmpty == true ? selectedPerdiemAmount! : "Amount",
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Container(
|
||||
// width: isDesktop ? MediaQuery.of(context).size.width * 0.15 : null,
|
||||
// // width: MediaQuery.of(context).size.width * 0.035,
|
||||
// height:
|
||||
// isDesktop ? MediaQuery.of(context).size.height * 0.09 : null,
|
||||
// child: Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.end,
|
||||
// mainAxisAlignment: MainAxisAlignment.end,
|
||||
// children: [
|
||||
// Text(
|
||||
// "Total Amount",
|
||||
// style: TextStyle(
|
||||
// fontSize: 13,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Color(0xFF575A74)),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
|
||||
// if (isDesktop)
|
||||
// SizedBox(
|
||||
// width: 35,
|
||||
// )
|
||||
// else
|
||||
// SizedBox(
|
||||
// height: 8,
|
||||
// ),
|
||||
//
|
||||
// Column(
|
||||
// // crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// // SizedBox(height: 5),
|
||||
// Container(
|
||||
// // width: MediaQuery.of(context).size.width * 0.15,
|
||||
// height:
|
||||
// isDesktop ? MediaQuery.of(context).size.height * 0.09 : null,
|
||||
// padding: isDesktop ? const EdgeInsets.only(left: 12.0) : null,
|
||||
// child: Row(
|
||||
// crossAxisAlignment: CrossAxisAlignment.end,
|
||||
// mainAxisAlignment: MainAxisAlignment.start,
|
||||
// children: [
|
||||
// Text(
|
||||
// // "amo",
|
||||
// selectedQuotedAmount ?? "0",
|
||||
// // selectedPerdiemAmount?.isNotEmpty == true ? selectedPerdiemAmount! : "Amount",
|
||||
// style: const TextStyle(
|
||||
// fontSize: 13,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Color(0xFF575A74)),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// // CustomTextFieldItnerarySubWrapper(
|
||||
// // isFocused: focusStates["_perdiemAmount"] ?? false,
|
||||
// // isDesktop: isDesktop,
|
||||
// // color: Colors.transparent,
|
||||
// // child: SizedBox(
|
||||
// // height: 40,
|
||||
// // child: Padding(
|
||||
// // padding: const EdgeInsets.all(8.0),
|
||||
// // child:
|
||||
// // ),
|
||||
// // ),
|
||||
// // ),
|
||||
// ],
|
||||
// ),
|
||||
// Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
@ -1528,7 +1722,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Comments",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1538,7 +1732,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
isFocused:
|
||||
focusStates["_comments"] ?? false, // Dropdown doesn't use focus
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.34 : null,
|
||||
width: isDesktop ? MediaQuery.of(context).size.width * 0.45 : null,
|
||||
child: SizedBox(
|
||||
height: 35,
|
||||
child: TextField(
|
||||
@ -1581,17 +1775,17 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Card Number",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldItnerarySubWrapper(
|
||||
CustomTextFieldForexWrapper(
|
||||
isFocused: focusStates["_cardNumber"] ?? false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
height: 35,
|
||||
child: TextField(
|
||||
enabled: !isChecked,
|
||||
focusNode: focusNodes["_cardNumber"],
|
||||
@ -1621,7 +1815,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Delivery Location",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1632,7 +1826,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
false, // Dropdown doesn't use focus
|
||||
isDesktop: isDesktop,
|
||||
width: isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.34
|
||||
? MediaQuery.of(context).size.width * 0.45
|
||||
: null,
|
||||
child: SizedBox(
|
||||
height: 35,
|
||||
@ -1661,7 +1855,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
if (isDesktop)
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.035,
|
||||
width: MediaQuery.of(context).size.width * 0.04,
|
||||
)
|
||||
else
|
||||
SizedBox(
|
||||
@ -1698,8 +1892,8 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
),
|
||||
Text(
|
||||
"Check If You Don't Have a forex Account",
|
||||
style: TextStyle(
|
||||
"Check If You Don't Have a Forex Account",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1727,7 +1921,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Close",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10), // Space between buttons
|
||||
@ -1746,7 +1940,7 @@ class _ForexScreenState extends State<ForexScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Save Changes",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
@ -304,9 +305,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Insurance Type",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -522,9 +523,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Insurance Type",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -573,9 +574,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Start Date",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -634,9 +635,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"End Date",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -713,9 +714,9 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Comments",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -774,7 +775,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Close",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10), // Space between buttons
|
||||
@ -793,7 +794,7 @@ class _InsuranceScreenState extends State<InsuranceScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Save Changes",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
@ -191,9 +192,9 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Special Type",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -279,9 +280,9 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Comments",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -344,7 +345,7 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Close",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10), // Space between buttons
|
||||
@ -363,7 +364,7 @@ class _MiscellaneousScreenState extends State<MiscellaneousScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Save Changes",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
@ -279,9 +280,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Taxi Required For",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -301,9 +302,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Number of Passenger",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -351,9 +352,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Car Type",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -507,9 +508,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"City",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -552,9 +553,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Location of Pickup",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -597,9 +598,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Date",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -649,9 +650,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Time",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -700,9 +701,9 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Comments",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -762,7 +763,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Close",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10), // Space between buttons
|
||||
@ -781,7 +782,7 @@ class _TaxiScreenState extends State<TaxiScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Save Changes",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
@ -363,9 +364,9 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Train Number",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -519,9 +520,9 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Class *",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -574,9 +575,9 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"From",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -679,9 +680,9 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"To",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -751,9 +752,9 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Date",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -804,9 +805,9 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Time",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -856,9 +857,9 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Comments",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -917,7 +918,7 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Close",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10), // Space between buttons
|
||||
@ -936,7 +937,7 @@ class _TrainScreenState extends State<TrainScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Save Changes",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
@ -440,9 +441,9 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Type of Visa",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -497,9 +498,9 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Country",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -572,9 +573,9 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Start Date",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -631,9 +632,9 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Comments",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
@ -692,7 +693,7 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Close",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10), // Space between buttons
|
||||
@ -711,7 +712,7 @@ class _VisaScreenState extends State<VisaScreen> {
|
||||
),
|
||||
child: Text(
|
||||
"Save Changes",
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
style: GoogleFonts.poppins(color: Colors.white, fontSize: 12),
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class AccomodationListWidget extends StatelessWidget {
|
||||
@ -200,10 +201,10 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
item["hotel_name"]!,
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
fontFamily: "Archivo"),
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
@ -230,29 +231,33 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" DestinationCity",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Check (in) ",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Check (out) ",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
@ -262,31 +267,35 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(item["destination_city"],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
child: Text(
|
||||
item["destination_city"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["checkin_date"]!)} ${formatTime(item["checkin_time"]!)}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
"${formatDate(item["checkin_date"]!)} ${formatTime(item["checkin_time"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["checkout_date"]!)} ${formatTime(item["checkout_time"]!)}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
"${formatDate(item["checkout_date"]!)} ${formatTime(item["checkout_time"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
@ -354,18 +363,18 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(value.substring(0, limit) + "...",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -393,8 +402,7 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
@ -430,16 +438,18 @@ class AccomodationListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"$date, $time",
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@ -201,22 +202,25 @@ class BusListWidget extends StatelessWidget {
|
||||
flex: 3,
|
||||
child: Text(
|
||||
" Planned Trips",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
" Date",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
@ -227,21 +231,24 @@ class BusListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text("${item["from"]} - ${item["to"]} ",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
child: Text(
|
||||
"${item["from"]} - ${item["to"]} ",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
"${formatDate(item["date"]!)} ${formatTime(item["time"]!)}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
"${formatDate(item["date"]!)} ${formatTime(item["time"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
@ -306,18 +313,18 @@ class BusListWidget extends StatelessWidget {
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(value.substring(0, limit) + "...",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -345,9 +352,9 @@ class BusListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
@ -369,7 +376,9 @@ class BusListWidget extends StatelessWidget {
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -382,16 +391,18 @@ class BusListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"$date, $time",
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../services/apiService.dart';
|
||||
@ -245,10 +246,10 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
children: [
|
||||
Text(
|
||||
item["trip_type"]?.toString() ?? "N/A",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
@ -268,34 +269,43 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
color: Colors.blueGrey.shade50,
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Class",
|
||||
style: TextStyle(fontSize: 11, fontFamily: "Archivo"),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Sector",
|
||||
style: TextStyle(fontSize: 11, fontFamily: "Archivo"),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Date",
|
||||
style: TextStyle(fontSize: 11, fontFamily: "Archivo"),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Time",
|
||||
style: TextStyle(fontSize: 11, fontFamily: "Archivo"),
|
||||
)),
|
||||
],
|
||||
),
|
||||
if (isDesktop)
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Class",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Text(
|
||||
"Sector",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Date",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Time",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 4),
|
||||
// Trip Rows
|
||||
|
||||
@ -318,38 +328,42 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
child: Text(
|
||||
getRequestForClass(trip["class"].toString()) ??
|
||||
"N/A",
|
||||
style: TextStyle(
|
||||
fontSize: 12, fontWeight: FontWeight.bold),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
flex: 4,
|
||||
child: Text(
|
||||
"$fromPlaceCountry (from) - (to) $toPlaceCountry",
|
||||
// "${trip["from_place"]?.toString()} - ${trip["to_place"]?.toString()}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
formatDate(trip["date"] ?? ""),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(formatTime(trip["time"] ?? ""),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: "Archivo")),
|
||||
child: Text(
|
||||
formatTime(trip["time"] ?? ""),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -376,7 +390,7 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
"Class",
|
||||
getRequestForClass(trip["class"].toString()) ??
|
||||
"N/A"),
|
||||
_buildKeyValueRow("From - To",
|
||||
_buildKeyValueRow("Sector",
|
||||
"${trip["from_place"] ?? "N/A"} - ${trip["to_place"] ?? "N/A"}"),
|
||||
_buildKeyValueRow(
|
||||
"Date", formatDate(trip["date"] ?? "")),
|
||||
@ -405,13 +419,18 @@ class _FlightListWidgetState extends State<FlightListWidget> {
|
||||
width: 80, // adjust width as needed
|
||||
child: Text(
|
||||
"$key:",
|
||||
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
value,
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'dart:convert';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
@ -209,10 +210,10 @@ class ForexListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
getRequestForCountry(item["country_code"]!.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w700,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
@ -239,22 +240,25 @@ class ForexListWidget extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Currency",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Duration",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Time Period ",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
@ -267,8 +271,9 @@ class ForexListWidget extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
@ -280,10 +285,10 @@ class ForexListWidget extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["currency"],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
@ -291,10 +296,10 @@ class ForexListWidget extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item["duration"],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
@ -302,10 +307,10 @@ class ForexListWidget extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["start_date"]!)} - ${formatDate(item["end_date"]!)}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
@ -386,18 +391,18 @@ class ForexListWidget extends StatelessWidget {
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(value.substring(0, limit) + "...",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -425,9 +430,9 @@ class ForexListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
@ -444,12 +449,16 @@ class ForexListWidget extends StatelessWidget {
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(value.substring(0, limit) + "...",
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'dart:js_interop';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class InsuranceListWidget extends StatelessWidget {
|
||||
@ -208,22 +209,25 @@ class InsuranceListWidget extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" InsuranceType",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Time Period ",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
@ -234,22 +238,24 @@ class InsuranceListWidget extends StatelessWidget {
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
getRequestForInsuranceType(
|
||||
item["type_of_insurance"]!.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
getRequestForInsuranceType(
|
||||
item["type_of_insurance"]!.toString()),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["start_date"]!)} - ${formatDate(item["end_date"]!)}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
"${formatDate(item["start_date"]!)} - ${formatDate(item["end_date"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
@ -314,18 +320,18 @@ class InsuranceListWidget extends StatelessWidget {
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(value.substring(0, limit) + "...",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -353,7 +359,10 @@ class InsuranceListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
@ -370,13 +379,17 @@ class InsuranceListWidget extends StatelessWidget {
|
||||
preferBelow: false,
|
||||
child: Text(
|
||||
value.substring(0, limit) + "...",
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
class MiscellaneousListWidget extends StatelessWidget {
|
||||
final List<Map<String, dynamic>> miscellaneousList;
|
||||
@ -175,15 +176,17 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Special Request",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
@ -196,19 +199,21 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
child: Text(
|
||||
getRequestValue(
|
||||
item["special_request"]?.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(item["comments"],
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
child: Text(
|
||||
item["comments"],
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
@ -262,18 +267,18 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(value.substring(0, limit) + "...",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -301,7 +306,10 @@ class MiscellaneousListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class TaxiListWidget extends StatelessWidget {
|
||||
@ -201,12 +202,11 @@ class TaxiListWidget extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
Text(
|
||||
"${getRequestForTaxiClass(item["car_type"]!.toString())} For ${item["no_of_passengers"]!} Passenger",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
"${getRequestForTaxiClass(item["car_type"]!.toString())} For ${item["no_of_passengers"]!} Passenger",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w800,
|
||||
fontFamily: "Archivo"),
|
||||
),
|
||||
)),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
onTap: () => onOpen(true, item, "Taxi"),
|
||||
@ -232,29 +232,33 @@ class TaxiListWidget extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"City",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Location",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Date",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Comments",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
@ -265,30 +269,35 @@ class TaxiListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text("${item["destination_city"]}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text("${item["location_of_pickup"]}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
child: Text(
|
||||
"${item["destination_city"]}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["date"]!)} ${formatTime(item["time"]!)}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
"${item["location_of_pickup"]}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["date"]!)} ${formatTime(item["time"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
@ -354,18 +363,18 @@ class TaxiListWidget extends StatelessWidget {
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(value.substring(0, limit) + "...",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -417,7 +426,9 @@ class TaxiListWidget extends StatelessWidget {
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -430,16 +441,18 @@ class TaxiListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"$date, $time",
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../services/apiService.dart';
|
||||
@ -288,10 +289,10 @@ class _TrainListWidgetState extends State<TrainListWidget> {
|
||||
children: [
|
||||
Text(
|
||||
item["train_no"]?.toString() ?? "N/A",
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
Spacer(),
|
||||
GestureDetector(
|
||||
@ -318,29 +319,33 @@ class _TrainListWidgetState extends State<TrainListWidget> {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Class",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Planned Trips",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Date",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
@ -350,33 +355,36 @@ class _TrainListWidgetState extends State<TrainListWidget> {
|
||||
? Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${getRequestForTrainClass(item["class"]!.toString())} ",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
)),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text("$fromPlaceCountry - $toPlaceCountry",
|
||||
child: Text(
|
||||
"$fromPlaceCountry - $toPlaceCountry",
|
||||
|
||||
// "${item["from_station"]!} - ${(item["to_station"])}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"))),
|
||||
// "${item["from_station"]!} - ${(item["to_station"])}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
)),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"${formatDate(item["date"]!)} ${formatTime(item["time"]!)}",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo")),
|
||||
"${formatDate(item["date"]!)} ${formatTime(item["time"]!)}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
Expanded(
|
||||
@ -482,9 +490,9 @@ class _TrainListWidgetState extends State<TrainListWidget> {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
@ -501,12 +509,16 @@ class _TrainListWidgetState extends State<TrainListWidget> {
|
||||
padding: EdgeInsets.all(8),
|
||||
preferBelow: false,
|
||||
child: Text(value.substring(0, limit) + "...",
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis),
|
||||
)
|
||||
: Text(
|
||||
value,
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class VisaListWidget extends StatelessWidget {
|
||||
@ -279,29 +280,33 @@ class VisaListWidget extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Visa Type",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Country",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Date",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
" Comments",
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
),
|
||||
)),
|
||||
],
|
||||
)
|
||||
@ -314,10 +319,10 @@ class VisaListWidget extends StatelessWidget {
|
||||
child: Text(
|
||||
getRequestForVisa(
|
||||
item["type_of_visa"]!.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
@ -326,10 +331,10 @@ class VisaListWidget extends StatelessWidget {
|
||||
child: Text(
|
||||
getRequestForCountry(
|
||||
item["country_code"]!.toString()),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
@ -337,10 +342,10 @@ class VisaListWidget extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
formatDate(item["start_date"]!),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontFamily: "Archivo"),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 10),
|
||||
@ -448,7 +453,10 @@ class VisaListWidget extends StatelessWidget {
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: TextStyle(fontWeight: FontWeight.w600, fontSize: 12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8),
|
||||
Expanded(
|
||||
|
||||
@ -330,7 +330,8 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
// backgroundColor: Colors.white,
|
||||
backgroundColor: Color(0xFFf5f5f5),
|
||||
appBar: CustomAppBar(isDesktop: isDesktop),
|
||||
drawer: CustomDrawer(isDesktop: false),
|
||||
body: Padding(
|
||||
@ -341,7 +342,7 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
vertical: MediaQuery.of(context).size.height *
|
||||
0, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(8),
|
||||
: EdgeInsets.all(0),
|
||||
child: Row(
|
||||
children: [
|
||||
// if (isDesktop) CustomDrawer(isDesktop: true),
|
||||
@ -355,6 +356,11 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
|
||||
Widget buildOrganizationLayout(isDesktop) {
|
||||
return Container(
|
||||
margin: isDesktop ? const EdgeInsets.only(top: 10.0, bottom: 10.0) : null,
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: isDesktop ? Colors.white : Color(0xFFFCFCFC),
|
||||
),
|
||||
// decoration: BoxDecoration(
|
||||
// // color: Colors.amber,
|
||||
// color: bodyColor,
|
||||
@ -368,12 +374,12 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
Expanded(
|
||||
child: Container(
|
||||
// color: Colors.redAccent,
|
||||
color: bodyColor,
|
||||
// color: bodyColor,
|
||||
child: buildOrgLayout(isDesktop),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8),
|
||||
padding: const EdgeInsets.all(5),
|
||||
color: Colors.white,
|
||||
child: isDesktop
|
||||
? Row(
|
||||
|
||||
@ -1237,10 +1237,10 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
fontFamily: "Archivo",
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 11),
|
||||
decoration: const InputDecoration(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Please enter remarks...",
|
||||
hintStyle: TextStyle(
|
||||
color: Colors.grey, fontSize: 15),
|
||||
hintStyle: GoogleFonts.poppins(
|
||||
fontSize: 13, color: Colors.grey),
|
||||
border: InputBorder.none,
|
||||
isDense: true,
|
||||
),
|
||||
@ -1263,8 +1263,8 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
),
|
||||
|
||||
Text(
|
||||
"Planning This Trip *", // Your label
|
||||
style: TextStyle(
|
||||
"Planning This Trip For*", // Your label
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1281,13 +1281,15 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
children: _buildPlanTrip(isMobile),
|
||||
),
|
||||
SizedBox(height: 7),
|
||||
Text(otherUserName ?? userName ?? " ", // Your label
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: widget.layoutColor,
|
||||
)),
|
||||
Text(
|
||||
otherUserName ?? userName ?? " ", // Your label
|
||||
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: widget.layoutColor,
|
||||
),
|
||||
)
|
||||
// Text.rich(
|
||||
// TextSpan(
|
||||
// text: "Trip Planned For : ", // Static text
|
||||
@ -1393,7 +1395,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
children: [
|
||||
Text(
|
||||
validationErrors["services"]!,
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
color: Colors.red,
|
||||
fontSize: 10,
|
||||
fontWeight: FontWeight.bold),
|
||||
@ -1463,7 +1465,8 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
children: [
|
||||
Text(
|
||||
"Trip Type *", // Your label
|
||||
style: TextStyle(
|
||||
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -1488,7 +1491,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
horizontal: 10, vertical: 8),
|
||||
child: Text(
|
||||
item['dropdown_value'] ?? '',
|
||||
style: const TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12, // 👈 Smaller font size
|
||||
color: Colors.black,
|
||||
),
|
||||
@ -1505,14 +1508,16 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) {
|
||||
if (selectedItem == null || selectedItem.isEmpty) {
|
||||
return const Text(
|
||||
return Text(
|
||||
"Select Trip Type",
|
||||
style: TextStyle(color: Colors.grey, fontSize: 13),
|
||||
style:
|
||||
GoogleFonts.poppins(color: Colors.grey, fontSize: 13),
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
selectedItem['dropdown_value'] ?? '',
|
||||
style: const TextStyle(fontSize: 12, color: Colors.black),
|
||||
style:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
);
|
||||
},
|
||||
selectedItem: tripTypeList.firstWhere(
|
||||
@ -1558,7 +1563,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
padding: EdgeInsets.only(top: 4),
|
||||
child: Text(
|
||||
validationErrors["trip_type"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 10),
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -1573,13 +1578,11 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
// height: 5,
|
||||
// ),
|
||||
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
|
||||
Text(
|
||||
"Is Billable ", // Your label
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
Text("Is Billable ", // Your label
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74))),
|
||||
SizedBox(height: 5),
|
||||
|
||||
CustomTextFieldWrapper(
|
||||
@ -1601,13 +1604,11 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
return Padding(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
|
||||
child: Text(
|
||||
item['dropdown_value'] ?? '',
|
||||
style: const TextStyle(
|
||||
fontSize: 12, // 👈 Smaller font size
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
child: Text(item['dropdown_value'] ?? '',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
)),
|
||||
);
|
||||
},
|
||||
),
|
||||
@ -1629,18 +1630,13 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
// items: purposeList.cast<Map<String, dynamic>>(),
|
||||
dropdownBuilder: (context, selectedItem) {
|
||||
if (selectedItem == null || selectedItem.isEmpty) {
|
||||
return const Text(
|
||||
"Select Billable", // fallback text
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
);
|
||||
return Text("Select Billable", // fallback text
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12, color: Colors.grey));
|
||||
}
|
||||
return Text(
|
||||
selectedItem['dropdown_value'] ?? '',
|
||||
style: const TextStyle(
|
||||
fontSize: 12, // 👈 Small font size for selected item
|
||||
color: Colors.black,
|
||||
),
|
||||
);
|
||||
return Text(selectedItem['dropdown_value'] ?? '',
|
||||
style:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.black));
|
||||
},
|
||||
|
||||
items: purposeList.map<Map<String, dynamic>>((item) {
|
||||
@ -1751,7 +1747,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
// value: null,
|
||||
value: "1",
|
||||
child: Text("No options available",
|
||||
style: TextStyle(color: Colors.grey)),
|
||||
style: GoogleFonts.poppins(color: Colors.grey)),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -1802,13 +1798,12 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Cost Center *", // Your label
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
Text("Cost Center *", // Your label
|
||||
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74))),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: false, // Dropdown doesn't use focus
|
||||
@ -1831,14 +1826,16 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
fit: FlexFit.loose,
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Cost Center...",
|
||||
hintStyle:
|
||||
TextStyle(fontSize: 13, color: Colors.grey),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
style: TextStyle(fontSize: 13)),
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Cost Center...",
|
||||
// hintStyle: TextStyle(fontSize: 13, color: Colors.grey),
|
||||
hintStyle: GoogleFonts.poppins(
|
||||
fontSize: 13, color: Colors.grey),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
style: GoogleFonts.poppins(fontSize: 13),
|
||||
),
|
||||
menuProps: MenuProps(
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
@ -1847,9 +1844,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
horizontal: 8.0, vertical: 6.0),
|
||||
child: Text(
|
||||
item,
|
||||
style: TextStyle(
|
||||
fontSize:
|
||||
13), // 👈 Set your desired text size here
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
), // 👈 Set your desired text size here
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -1866,16 +1863,16 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
|
||||
dropdownBuilder: (context, selectedItem) {
|
||||
if (selectedItem == null || selectedItem.isEmpty) {
|
||||
return const Text(
|
||||
return Text(
|
||||
"Select Purpose", // fallback text
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12, color: Colors.grey),
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
selectedItem ?? '',
|
||||
style: const TextStyle(
|
||||
fontSize:
|
||||
12, // 👈 Small font size for selected item
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black,
|
||||
),
|
||||
);
|
||||
@ -1932,13 +1929,12 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Purpose of Trip *", // Your label
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
Text("Purpose of Trip *", // Your label
|
||||
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74))),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldWrapper(
|
||||
width: isDesktop
|
||||
@ -1967,14 +1963,17 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
fit: FlexFit.loose,
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Purpose...",
|
||||
hintStyle:
|
||||
TextStyle(fontSize: 13, color: Colors.grey),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
style: TextStyle(fontSize: 13)),
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Purpose...",
|
||||
hintStyle: GoogleFonts.poppins(
|
||||
fontSize: 13, color: Colors.grey),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
menuProps: MenuProps(
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
@ -1983,9 +1982,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
horizontal: 8.0, vertical: 6.0),
|
||||
child: Text(
|
||||
item['dropdown_value'],
|
||||
style: TextStyle(
|
||||
fontSize:
|
||||
13), // 👈 Set your desired text size here
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
), // 👈 Set your desired text size here
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -2008,14 +2007,15 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
|
||||
dropdownBuilder: (context, selectedItem) {
|
||||
if (selectedItem == null || selectedItem.isEmpty) {
|
||||
return const Text(
|
||||
return Text(
|
||||
"Select Purpose", // fallback text
|
||||
style: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, color: Colors.grey),
|
||||
);
|
||||
}
|
||||
return Text(
|
||||
selectedItem['dropdown_value'] ?? '',
|
||||
style: const TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
12, // 👈 Small font size for selected item
|
||||
color: Colors.black,
|
||||
@ -2076,7 +2076,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
children: [
|
||||
Text(
|
||||
"Functional Department", // Your label
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -2111,12 +2111,15 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search department...",
|
||||
hintStyle:
|
||||
TextStyle(fontSize: 13, color: Colors.grey),
|
||||
hintStyle: GoogleFonts.poppins(
|
||||
fontSize: 13, color: Colors.grey),
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
style: TextStyle(fontSize: 13)),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
13, // 👈 Small font size for selected item
|
||||
)),
|
||||
menuProps: MenuProps(
|
||||
backgroundColor: Colors.white,
|
||||
),
|
||||
@ -2125,9 +2128,10 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
horizontal: 8.0, vertical: 6.0),
|
||||
child: Text(
|
||||
item['dropdown_value'],
|
||||
style: TextStyle(
|
||||
fontSize:
|
||||
13), // 👈 Set your desired text size here
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
13, // 👈 Small font size for selected item
|
||||
), // 👈 Set your desired text size here
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -2157,7 +2161,7 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
}
|
||||
return Text(
|
||||
selectedItem['dropdown_value'] ?? '',
|
||||
style: const TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize:
|
||||
12, // 👈 Small font size for selected item
|
||||
color: Colors.black,
|
||||
@ -2451,51 +2455,25 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
children: [
|
||||
Text(
|
||||
"Description", // Your label
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: false,
|
||||
// isFocused: _isdescriptionFocused,
|
||||
isDesktop: widget.isDesktop,
|
||||
width: isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.74
|
||||
: MediaQuery.of(context).size.width * 0.85,
|
||||
child: SizedBox(
|
||||
height: 35,
|
||||
child: TextField(
|
||||
// focusNode: _descriptionFocusNode,
|
||||
controller: _descriptionController,
|
||||
style: TextStyle(fontSize: 12),
|
||||
enabled: !widget.isViewMode,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Description",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// CustomTextFieldWrapper(
|
||||
// isFocused: _isdescriptionFocused,
|
||||
// isFocused: false,
|
||||
// // isFocused: _isdescriptionFocused,
|
||||
// isDesktop: widget.isDesktop,
|
||||
// width: isDesktop
|
||||
// ? MediaQuery.of(context).size.width * 0.4
|
||||
// : MediaQuery.of(context).size.width * 0.85,
|
||||
// isDesktop: widget.isDesktop,
|
||||
// child: SizedBox(
|
||||
// height: 35,
|
||||
// child:
|
||||
// TextField(
|
||||
// focusNode: _descriptionFocusNode,
|
||||
// child: TextField(
|
||||
// // focusNode: _descriptionFocusNode,
|
||||
// controller: _descriptionController,
|
||||
// // maxLines: 1,
|
||||
// // keyboardType: TextInputType.multiline,
|
||||
// style: TextStyle(fontSize: 12),
|
||||
// enabled: !widget.isViewMode,
|
||||
// decoration: InputDecoration(
|
||||
@ -2503,11 +2481,38 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
// labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
// floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
// border: InputBorder.none,
|
||||
// contentPadding: EdgeInsets.symmetric(vertical: 1),
|
||||
// contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
CustomTextFieldWrapper(
|
||||
isFocused: _isdescriptionFocused,
|
||||
// width: isDesktop
|
||||
// ? MediaQuery.of(context).size.width * 0.38
|
||||
// : MediaQuery.of(context).size.width * 0.85,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 55,
|
||||
child: TextField(
|
||||
focusNode: _descriptionFocusNode,
|
||||
controller: _descriptionController,
|
||||
maxLines: 2,
|
||||
keyboardType: TextInputType.multiline,
|
||||
style: TextStyle(fontSize: 12),
|
||||
enabled: !widget.isViewMode,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Description",
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12, color: Colors.grey),
|
||||
// labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 1),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
@ -2582,8 +2587,9 @@ class CreateNewPlansState extends State<CreateNewPlan> {
|
||||
),
|
||||
enabled: !widget.isViewMode,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Trip Name",
|
||||
labelStyle: TextStyle(fontSize: 14, color: Colors.grey),
|
||||
labelText: "Trip Name *",
|
||||
|
||||
labelStyle: GoogleFonts.poppins(fontSize: 14, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
|
||||
@ -7,6 +7,7 @@ import 'package:frontend/Screens/itnerary_list/bus_list.dart';
|
||||
import 'package:frontend/Screens/itnerary_list/flight_list.dart';
|
||||
import 'package:frontend/Screens/itnerary_list/taxi_list.dart';
|
||||
import 'package:frontend/Screens/itnerary_list/train_list.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
import '../../services/apiService.dart';
|
||||
@ -931,12 +932,17 @@ class DynamicItineraryState extends State<DynamicItinerary> {
|
||||
children: [
|
||||
Text(
|
||||
name,
|
||||
|
||||
// style: GoogleFonts.poppins( fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: Color(0xFF575A74))
|
||||
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: isOptionSelected
|
||||
? Color(0xFF114D8B)
|
||||
: Color(0xFF475569),
|
||||
fontFamily: "Archivo",
|
||||
fontFamily: "Inter",
|
||||
fontWeight:
|
||||
isOptionSelected ? FontWeight.bold : FontWeight.w500,
|
||||
),
|
||||
|
||||
@ -408,9 +408,8 @@ class _ListPlansState extends State<ListPlans> {
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -486,10 +485,10 @@ class _ListPlansState extends State<ListPlans> {
|
||||
mainAxisSize:
|
||||
MainAxisSize.min, // Ensures content fits nicely
|
||||
children: [
|
||||
Text(
|
||||
"Add New Trip",
|
||||
style: TextStyle(fontSize: isDesktop ? 13 : 11),
|
||||
),
|
||||
Text("Add New Trip",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
)),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(
|
||||
Icons.add_circle_outline_rounded,
|
||||
@ -534,9 +533,8 @@ class _ListPlansState extends State<ListPlans> {
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -613,58 +611,55 @@ class _ListPlansState extends State<ListPlans> {
|
||||
horizontalInside: BorderSide(
|
||||
width: 0.5, color: Colors.grey.shade200),
|
||||
),
|
||||
columns: const [
|
||||
columns: [
|
||||
DataColumn(
|
||||
label: Text('Trip Id',
|
||||
style: TextStyle(
|
||||
// color: Colors.grey,
|
||||
// color: Color(0xFF9E9DBD),
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip ID',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Trip Name',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip Name',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Employee Code',
|
||||
style: TextStyle(
|
||||
// color: Color(0xFF9E9DBD),
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Emp Code',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Traveller',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Traveller',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Trip Type',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Trip Type',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Created On',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Created On',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Status',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Status',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Actions',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Actions',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13, fontWeight: FontWeight.w600),
|
||||
)),
|
||||
],
|
||||
rows: paginatedPlans.map((plan) {
|
||||
return DataRow(cells: [
|
||||
|
||||
@ -383,7 +383,7 @@ class _PolicyState extends State<Policy> {
|
||||
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: Color(0xFFf5f5f5),
|
||||
appBar: CustomAppBar(isDesktop: isDesktop),
|
||||
drawer: CustomDrawer(isDesktop: false),
|
||||
body: Padding(
|
||||
@ -453,6 +453,11 @@ class _PolicyState extends State<Policy> {
|
||||
|
||||
Widget buildData(bool isDesktop, context) {
|
||||
return Container(
|
||||
margin: isDesktop ? const EdgeInsets.only(top: 10.0, bottom: 10.0) : null,
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: isDesktop ? Colors.white : Color(0xFFFCFCFC),
|
||||
),
|
||||
// margin: const EdgeInsets.only(left: 10.0, right: 15.0, top: 10.0, bottom: 10.0),
|
||||
// decoration: BoxDecoration(
|
||||
// color: Color(0xFFE1F5FE),
|
||||
|
||||
@ -147,7 +147,7 @@ class _PolicyListState extends State<PolicyList> {
|
||||
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white54,
|
||||
backgroundColor: Color(0xFFf5f5f5),
|
||||
appBar: CustomAppBar(isDesktop: isDesktop),
|
||||
drawer: CustomDrawer(isDesktop: false),
|
||||
body: Padding(
|
||||
@ -158,7 +158,7 @@ class _PolicyListState extends State<PolicyList> {
|
||||
vertical: MediaQuery.of(context).size.height *
|
||||
0, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(8),
|
||||
: EdgeInsets.all(0),
|
||||
child: Row(
|
||||
children: [
|
||||
// if (isDesktop) CustomDrawer(isDesktop: true),
|
||||
@ -172,6 +172,11 @@ class _PolicyListState extends State<PolicyList> {
|
||||
|
||||
Widget buildGroupList(bool isDesktop) {
|
||||
return Container(
|
||||
margin: isDesktop ? const EdgeInsets.only(top: 10.0, bottom: 10.0) : null,
|
||||
padding: const EdgeInsets.only(left: 10, right: 10, top: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: isDesktop ? Colors.white : Color(0xFFFCFCFC),
|
||||
),
|
||||
// decoration: BoxDecoration(
|
||||
// // color: Colors.amber,
|
||||
// color: Color(0xFFE1F5FE),
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
2954
lib/Screens/userManagement/create_user/create_user1.dart
Normal file
2954
lib/Screens/userManagement/create_user/create_user1.dart
Normal file
File diff suppressed because it is too large
Load Diff
822
lib/Screens/userManagement/create_user/office_details.dart
Normal file
822
lib/Screens/userManagement/create_user/office_details.dart
Normal file
@ -0,0 +1,822 @@
|
||||
import 'dart:io' as html;
|
||||
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../../services/apiService.dart';
|
||||
import '../../../widgets/custom_user_form.dart';
|
||||
|
||||
class OfficeDetails extends StatefulWidget {
|
||||
final Map<String, TextEditingController> controllers;
|
||||
final Map<String, String> errorMessages;
|
||||
final bool isDesktop;
|
||||
final bool isViewMode;
|
||||
|
||||
final ValueChanged<String?>? onLevelChanged;
|
||||
final ValueChanged<String?>? onDepartmentChanged;
|
||||
final ValueChanged<String?>? onFirstApproverChanged;
|
||||
final ValueChanged<String?>? onSecondApproverChanged;
|
||||
final ValueChanged<String?>? onThirdApproverChanged;
|
||||
|
||||
final String? selectedLevel;
|
||||
final String? selectedDepartment;
|
||||
final String? selectedFirstApprover;
|
||||
final String? selectedSecondApprover;
|
||||
final String? selectedThirdApprover;
|
||||
|
||||
const OfficeDetails({
|
||||
Key? key,
|
||||
this.selectedLevel,
|
||||
this.selectedDepartment,
|
||||
this.selectedFirstApprover,
|
||||
this.selectedSecondApprover,
|
||||
this.selectedThirdApprover,
|
||||
required this.controllers,
|
||||
required this.errorMessages,
|
||||
required this.isDesktop,
|
||||
required this.isViewMode,
|
||||
this.onLevelChanged,
|
||||
this.onDepartmentChanged,
|
||||
this.onFirstApproverChanged,
|
||||
this.onSecondApproverChanged,
|
||||
this.onThirdApproverChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_OfficeDetailsState createState() => _OfficeDetailsState();
|
||||
}
|
||||
|
||||
class _OfficeDetailsState extends State<OfficeDetails> {
|
||||
final ApiService apiService = ApiService();
|
||||
|
||||
late Map<String, String> countryMap; // Mapping country_code -> country_name
|
||||
late List<String> countryCodes; // List of country codes
|
||||
late List<dynamic>? apiCountryData;
|
||||
|
||||
late List<dynamic>? apiCostData;
|
||||
late List<dynamic>? apiRoleData;
|
||||
late List<dynamic>? apiUserData;
|
||||
late List<dynamic>? apiAllGroups;
|
||||
Map<String, dynamic>? apiselectedUser;
|
||||
|
||||
late List<dynamic> userList;
|
||||
late List<dynamic> groupList;
|
||||
late Future<List<dynamic>> futureUsers;
|
||||
|
||||
List<dynamic>? resolvedUserData;
|
||||
late List<String> userIdsApi;
|
||||
late List<String> groupIdsApi;
|
||||
late Map<String, String> userMap;
|
||||
late Map<String, String> groupMap;
|
||||
|
||||
String? selectedTab;
|
||||
|
||||
String? selectedCountry;
|
||||
String? selectedGender;
|
||||
String? selectedUserType;
|
||||
String? selectedRole;
|
||||
String? selectedLevel;
|
||||
String? selectedDepartment;
|
||||
String? selectedFirstApprover;
|
||||
String? selectedSecondApprover;
|
||||
String? selectedThirdApprover;
|
||||
|
||||
String? selectedFileNames;
|
||||
Uint8List? passportDocumentBytes;
|
||||
String? passportFileUrlFromApi;
|
||||
String? base64PDF;
|
||||
|
||||
html.File? passportFile;
|
||||
|
||||
List<String> dataHeader = [
|
||||
"Fname",
|
||||
"Lname",
|
||||
"email",
|
||||
"password",
|
||||
"dob",
|
||||
"gender",
|
||||
"mobileNumber",
|
||||
"alternateMobile",
|
||||
"address",
|
||||
"postalCode",
|
||||
"country",
|
||||
"passportNumber",
|
||||
"placeOfIssue",
|
||||
"passportDoc",
|
||||
"userType",
|
||||
"roleId",
|
||||
"deptId",
|
||||
"levelId",
|
||||
"firstApproval",
|
||||
"secondApproval",
|
||||
"thirdApproval",
|
||||
"employeeCode",
|
||||
"dateOfIssue",
|
||||
"dateOfExpiry",
|
||||
"changePassword"
|
||||
];
|
||||
|
||||
Color? layoutColor;
|
||||
Color? bodyColor;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
apiCountryData = null;
|
||||
apiUserData = null;
|
||||
apiCostData = null;
|
||||
apiRoleData = null;
|
||||
apiAllGroups = null;
|
||||
|
||||
apiCountryData = null;
|
||||
|
||||
selectedLevel = widget.selectedLevel;
|
||||
selectedDepartment = widget.selectedDepartment;
|
||||
selectedFirstApprover = widget.selectedFirstApprover;
|
||||
selectedSecondApprover = widget.selectedSecondApprover;
|
||||
selectedThirdApprover = widget.selectedThirdApprover;
|
||||
|
||||
fetchDepartment();
|
||||
fetchUsers();
|
||||
fetchFindGroup();
|
||||
}
|
||||
|
||||
void _clearError(String field) {
|
||||
setState(() {
|
||||
widget.errorMessages.remove(field);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> fetchUsers() async {
|
||||
try {
|
||||
List<dynamic> users = await apiService.fetchUsers();
|
||||
setState(() {
|
||||
// apiUserData = users;
|
||||
|
||||
apiUserData = users.where((user) => user["role_id"] == "4").toList();
|
||||
|
||||
print("APIUSerDATa - $apiUserData");
|
||||
|
||||
userList = apiUserData ?? [];
|
||||
userMap = {
|
||||
for (var user in userList)
|
||||
user['user_id'].toString():
|
||||
"${user['first_name']} ${user['last_name']}"
|
||||
};
|
||||
userIdsApi = userMap.keys.toList();
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error fetching country list: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchDepartment() async {
|
||||
try {
|
||||
List<dynamic> department = await apiService.fetchCostCenter();
|
||||
setState(() {
|
||||
apiCostData = department;
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error fetching department list: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchFindGroup() async {
|
||||
try {
|
||||
final result = await apiService.fetchAllGroup();
|
||||
setState(() {
|
||||
apiAllGroups = result;
|
||||
|
||||
groupList = apiAllGroups ?? [];
|
||||
// groupMap = {
|
||||
// for (var group in groupList)
|
||||
// group['group_id'].toString(): "${group['name']}"
|
||||
// };
|
||||
|
||||
groupMap = {
|
||||
for (var group in groupList)
|
||||
group['group_id'].toString(): group['name'].toString().trim()
|
||||
};
|
||||
|
||||
userIdsApi = groupMap.keys.toList();
|
||||
});
|
||||
print("Fetched Groupss: $apiAllGroups");
|
||||
} catch (e) {
|
||||
print('Error fetching role list: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Colors.blueGrey.shade300, // Set your desired color
|
||||
width: 0.09, // Set border thickness
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
_buildFirstRow(widget.isDesktop),
|
||||
if (widget.isDesktop)
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
_buildSecondRow(widget.isDesktop),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFirstRow(bool isDesktop) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: widget.isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildEmpCodeField(),
|
||||
Spacer(),
|
||||
buildDepartmentField(),
|
||||
Spacer(), // Space after Last Name
|
||||
buildGroupField(),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildEmpCodeField(),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
buildDepartmentField(),
|
||||
SizedBox(height: 8),
|
||||
buildGroupField(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSecondRow(bool isDesktop) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: widget.isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildApprover1(isDesktop),
|
||||
Spacer(),
|
||||
buildApprover2(isDesktop),
|
||||
Spacer(), // Space after Last Name
|
||||
buildApprover3(isDesktop),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildApprover1(isDesktop),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
buildApprover2(isDesktop),
|
||||
SizedBox(height: 8),
|
||||
buildApprover3(isDesktop),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildEmpCodeField() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Employee Code",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
controller: widget.controllers["employeeCode"],
|
||||
enabled: !widget.isViewMode,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Employee Code",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildDepartmentField() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Department",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false, // Dropdown doesn't use focus
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 45, // Set appropriate height
|
||||
child: DropdownButtonFormField<String>(
|
||||
value: widget.isViewMode ? null : selectedDepartment,
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 10), // Proper padding
|
||||
),
|
||||
onChanged: widget.isViewMode
|
||||
? null
|
||||
: (newValue) {
|
||||
setState(() {
|
||||
selectedDepartment = newValue;
|
||||
});
|
||||
widget.onDepartmentChanged?.call(newValue);
|
||||
},
|
||||
items: apiCostData?.map<DropdownMenuItem<String>>((item) {
|
||||
return DropdownMenuItem(
|
||||
value: item['department_id'], // ID as value
|
||||
child: Text(item['name'] ?? "Unknown"),
|
||||
);
|
||||
}).toList(),
|
||||
hint: Text("Select"),
|
||||
disabledHint: Text(
|
||||
selectedDepartment ?? "Select Department",
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildGroupField() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Group",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
// CustomTextFieldUserWrapper(
|
||||
// isFocused: false,
|
||||
// isDesktop: widget.isDesktop,
|
||||
// child: SizedBox(
|
||||
// height: 40,
|
||||
// child: DropdownSearch<String>(
|
||||
// selectedItem: selectedLevel,
|
||||
// enabled: !widget.isViewMode,
|
||||
// popupProps: PopupProps.menu(
|
||||
// // showSearchBox: true,
|
||||
// fit: FlexFit.loose, // Allows flexible height
|
||||
// constraints: BoxConstraints(maxHeight: 250),
|
||||
// ),
|
||||
// items: ["Level 1", "Level 2", "Level 3"],
|
||||
// dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
// dropdownSearchDecoration: InputDecoration(
|
||||
// border: InputBorder.none,
|
||||
// contentPadding: EdgeInsets.symmetric(
|
||||
// horizontal: 1,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// dropdownBuilder: (context, selectedItem) => Align(
|
||||
// // Center-align selected item
|
||||
// alignment: Alignment.centerLeft,
|
||||
// child: Text(
|
||||
// selectedItem ?? "Select",
|
||||
// style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
// ),
|
||||
// ),
|
||||
// onChanged: (String? newValue) {
|
||||
// setState(() {
|
||||
// // Find the country_code based on selected country_name
|
||||
// selectedLevel = newValue;
|
||||
//
|
||||
// // if (selectedCountry!.isNotEmpty) {
|
||||
// // errorMessages.remove("country_code");
|
||||
// // }
|
||||
// });
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: apiAllGroups == null
|
||||
? Center(
|
||||
child: Transform.scale(
|
||||
scale: 0.5,
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
)
|
||||
: DropdownSearch<String>(
|
||||
selectedItem: groupMap[selectedLevel],
|
||||
enabled: !widget.isViewMode,
|
||||
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true,
|
||||
fit: FlexFit.loose, // Allows flexible height
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Group...",
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
// items: apiAllGroups!.map((group) {
|
||||
// return "${group['name']} ";
|
||||
// }).toList(),
|
||||
|
||||
items: apiAllGroups!.map((group) {
|
||||
return group['name'].toString().trim(); // <-- trim spaces
|
||||
}).toList(),
|
||||
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) => Align(
|
||||
// Center-align selected item
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select",
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
|
||||
onChanged: (String? newValue) {
|
||||
if (newValue == null) return;
|
||||
|
||||
final levelId = groupMap.entries
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
|
||||
setState(() {
|
||||
selectedLevel = levelId;
|
||||
});
|
||||
|
||||
widget.onLevelChanged
|
||||
?.call(levelId); // ✅ pass the ID not the name
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildApprover1(bool isDesktop) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
// child: Expanded(
|
||||
// Allow first column to take available space
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("First Approver",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: apiUserData == null
|
||||
? Center(
|
||||
child: Transform.scale(
|
||||
scale: 0.5,
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
)
|
||||
: DropdownSearch<String>(
|
||||
selectedItem: userMap[selectedFirstApprover],
|
||||
enabled: !widget.isViewMode,
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true,
|
||||
fit: FlexFit.loose, // Allows flexible height
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search User...",
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
items: apiUserData!.map((user) {
|
||||
return "${user['first_name']} ${user['last_name']}";
|
||||
}).toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) => Align(
|
||||
// Center-align selected item
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select",
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
// onChanged: (String? newValue) {
|
||||
// setState(() {
|
||||
// selectedFirstApprover = userMap.entries
|
||||
// .firstWhere(
|
||||
// (entry) => entry.value == newValue)
|
||||
// .key;
|
||||
//
|
||||
// // if (selectedCountry!.isNotEmpty) {
|
||||
// // errorMessages.remove("country_code");
|
||||
// // }
|
||||
// });
|
||||
// widget.onFirstApproverChanged?.call(newValue);
|
||||
// },
|
||||
|
||||
onChanged: (String? newValue) {
|
||||
if (newValue == null) return;
|
||||
|
||||
final approverId = userMap.entries
|
||||
.firstWhere(
|
||||
(entry) => entry.value == newValue)
|
||||
.key;
|
||||
|
||||
setState(() {
|
||||
selectedFirstApprover = approverId;
|
||||
});
|
||||
|
||||
widget.onFirstApproverChanged?.call(
|
||||
approverId); // ✅ not newValue, but approverId
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// ),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildApprover2(bool isDesktop) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
// child: Expanded(
|
||||
// Allow second column to take available space
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Second Approver",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: apiUserData == null
|
||||
? Center(
|
||||
child: Transform.scale(
|
||||
scale: 0.5,
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
)
|
||||
: DropdownSearch<String>(
|
||||
selectedItem: userMap[selectedSecondApprover],
|
||||
enabled: !widget.isViewMode,
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true,
|
||||
fit: FlexFit.loose, // Allows flexible height
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search User...",
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
items: apiUserData!.map((user) {
|
||||
return "${user['first_name']} ${user['last_name']}";
|
||||
}).toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) => Align(
|
||||
// Center-align selected item
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select",
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
|
||||
onChanged: (String? newValue) {
|
||||
if (newValue == null) return;
|
||||
|
||||
final approverId = userMap.entries
|
||||
.firstWhere(
|
||||
(entry) => entry.value == newValue)
|
||||
.key;
|
||||
|
||||
setState(() {
|
||||
selectedSecondApprover = approverId;
|
||||
});
|
||||
|
||||
widget.onSecondApproverChanged?.call(
|
||||
approverId); // ✅ not newValue, but approverId
|
||||
},
|
||||
// onChanged: (String? newValue) {
|
||||
// setState(() {
|
||||
// selectedSecondApprover = userMap.entries
|
||||
// .firstWhere(
|
||||
// (entry) => entry.value == newValue)
|
||||
// .key;
|
||||
//
|
||||
// // if (selectedCountry!.isNotEmpty) {
|
||||
// // errorMessages.remove("country_code");
|
||||
// // }
|
||||
// });
|
||||
// },
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
// ),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildApprover3(bool isDesktop) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
// child: Expanded(
|
||||
// Allow second column to take available space
|
||||
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Third Approver",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: apiUserData == null
|
||||
? Center(
|
||||
child: Transform.scale(
|
||||
scale: 0.5,
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
)
|
||||
: DropdownSearch<String>(
|
||||
selectedItem: userMap[selectedThirdApprover],
|
||||
enabled: !widget.isViewMode,
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true,
|
||||
fit: FlexFit.loose, // Allows flexible height
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search User...",
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
items: apiUserData!.map((user) {
|
||||
return "${user['first_name']} ${user['last_name']}";
|
||||
}).toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) => Align(
|
||||
// Center-align selected item
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select",
|
||||
style: TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
onChanged: (String? newValue) {
|
||||
if (newValue == null) return;
|
||||
|
||||
final approverId = userMap.entries
|
||||
.firstWhere(
|
||||
(entry) => entry.value == newValue)
|
||||
.key;
|
||||
|
||||
setState(() {
|
||||
selectedThirdApprover = approverId;
|
||||
});
|
||||
|
||||
widget.onThirdApproverChanged?.call(
|
||||
approverId); // ✅ not newValue, but approverId
|
||||
},
|
||||
// onChanged: (String? newValue) {
|
||||
// setState(() {
|
||||
// selectedThirdApprover = userMap.entries
|
||||
// .firstWhere(
|
||||
// (entry) => entry.value == newValue)
|
||||
// .key;
|
||||
//
|
||||
// // if (selectedCountry!.isNotEmpty) {
|
||||
// // errorMessages.remove("country_code");
|
||||
// // }
|
||||
// });
|
||||
// },
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// ),
|
||||
);
|
||||
}
|
||||
}
|
||||
977
lib/Screens/userManagement/create_user/personal_details.dart
Normal file
977
lib/Screens/userManagement/create_user/personal_details.dart
Normal file
@ -0,0 +1,977 @@
|
||||
import 'dart:io' as html;
|
||||
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../../../services/apiService.dart';
|
||||
import '../../../widgets/custom_user_form.dart';
|
||||
|
||||
class PersonalDetails extends StatefulWidget {
|
||||
final GlobalKey<PersonalDetailsState> personalDetailsKey;
|
||||
final Map<String, TextEditingController> controllers;
|
||||
final Map<String, String> errorMessages;
|
||||
final bool isDesktop;
|
||||
final bool isViewMode;
|
||||
final bool apiselectedUser;
|
||||
|
||||
final ValueChanged<String?>? onGenderChanged;
|
||||
final ValueChanged<String?>? onCountryChanged;
|
||||
final ValueChanged<String?>? onRoleChanged;
|
||||
|
||||
final String? selectedGender;
|
||||
final String? selectedCountry;
|
||||
final String? selectedRole;
|
||||
|
||||
// const PersonalDetails(this.isDesktop, this.isViewMode, {super.key},);
|
||||
const PersonalDetails({
|
||||
Key? key,
|
||||
this.selectedGender,
|
||||
this.selectedCountry,
|
||||
this.selectedRole,
|
||||
required this.personalDetailsKey,
|
||||
required this.controllers,
|
||||
required this.errorMessages,
|
||||
required this.isDesktop,
|
||||
required this.isViewMode,
|
||||
required this.apiselectedUser,
|
||||
this.onGenderChanged,
|
||||
this.onCountryChanged,
|
||||
this.onRoleChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
PersonalDetailsState createState() => PersonalDetailsState();
|
||||
}
|
||||
|
||||
class PersonalDetailsState extends State<PersonalDetails> {
|
||||
final ApiService apiService = ApiService();
|
||||
|
||||
late Map<String, String> countryMap; // Mapping country_code -> country_name
|
||||
late List<String> countryCodes; // List of country codes
|
||||
late List<dynamic>? apiCountryData;
|
||||
late List<dynamic>? apiRoleData;
|
||||
|
||||
String? get selectedGenderValue => selectedGender;
|
||||
String? get selectedCountryValue => selectedCountry;
|
||||
String? get selectedRoleValue => selectedRole;
|
||||
|
||||
String? selectedTab;
|
||||
|
||||
String? selectedCountry;
|
||||
String? selectedGender;
|
||||
|
||||
String? selectedUserType;
|
||||
String? selectedRole;
|
||||
String? selectedLevel;
|
||||
String? selectedDepartment;
|
||||
String? selectedFirstApprover;
|
||||
String? selectedSecondApprover;
|
||||
String? selectedThirdApprover;
|
||||
|
||||
String? selectedFileNames;
|
||||
Uint8List? passportDocumentBytes;
|
||||
String? passportFileUrlFromApi;
|
||||
String? base64PDF;
|
||||
|
||||
html.File? passportFile;
|
||||
|
||||
List<String> dataHeader = [
|
||||
"Fname",
|
||||
"Lname",
|
||||
"email",
|
||||
"password",
|
||||
"dob",
|
||||
"gender",
|
||||
"mobileNumber",
|
||||
"alternateMobile",
|
||||
"address",
|
||||
"postalCode",
|
||||
"country",
|
||||
"passportNumber",
|
||||
"placeOfIssue",
|
||||
"passportDoc",
|
||||
"userType",
|
||||
"roleId",
|
||||
"deptId",
|
||||
"levelId",
|
||||
"firstApproval",
|
||||
"secondApproval",
|
||||
"thirdApproval",
|
||||
"employeeCode",
|
||||
"dateOfIssue",
|
||||
"dateOfExpiry",
|
||||
"changePassword"
|
||||
];
|
||||
|
||||
Color? layoutColor;
|
||||
Color? bodyColor;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
apiCountryData = null;
|
||||
|
||||
apiRoleData = null;
|
||||
selectedGender = widget.selectedGender;
|
||||
selectedCountry = widget.selectedCountry;
|
||||
selectedRole = widget.selectedRole;
|
||||
fetchRoles();
|
||||
fetchCountries();
|
||||
}
|
||||
|
||||
void _clearError(String field) {
|
||||
setState(() {
|
||||
widget.errorMessages.remove(field);
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> fetchRoles() async {
|
||||
try {
|
||||
final response = await apiService.fetchMasterDropdown();
|
||||
|
||||
if (response is Map<String, dynamic> && response.containsKey("role")) {
|
||||
List<dynamic> roleList = response["role"]; // Extract the list
|
||||
setState(() {
|
||||
apiRoleData = roleList;
|
||||
});
|
||||
print("APIROLEData - $apiRoleData");
|
||||
} else {
|
||||
print("Error: 'role' key not found or response is not a Map.");
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error fetching role list: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> fetchCountries() async {
|
||||
try {
|
||||
List<dynamic> countries = await apiService.fetchCountryList();
|
||||
setState(() {
|
||||
apiCountryData = countries;
|
||||
});
|
||||
} catch (e) {
|
||||
print('Error fetching country list: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Colors.blueGrey.shade300, // Set your desired color
|
||||
width: 0.09, // Set border thickness
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
_buildFirstRow(widget.isDesktop),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
_buildSecondRow(widget.isDesktop),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
_buildThirdRow(widget.isDesktop),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
_buildForthRow(widget.isDesktop),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildFirstRow(bool isDesktop) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: widget.isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFirstNameField(),
|
||||
Spacer(),
|
||||
buildLastNameField(),
|
||||
Spacer(), // Space after Last Name
|
||||
buildGenderField(),
|
||||
SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
buildDobField(),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildFirstNameField(),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
buildLastNameField(),
|
||||
SizedBox(height: 8),
|
||||
buildGenderField(),
|
||||
SizedBox(height: 8),
|
||||
buildDobField(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildSecondRow(bool isDesktop) {
|
||||
List<Widget> fields = [
|
||||
buildEmailField(),
|
||||
buildMobileField(),
|
||||
buildAlternateMobileField(),
|
||||
];
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: widget.isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildEmailField(),
|
||||
Spacer(),
|
||||
buildMobileField(),
|
||||
Spacer(), // Space after Last Name
|
||||
buildAlternateMobileField(),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildEmailField(),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
buildMobileField(),
|
||||
SizedBox(height: 8),
|
||||
buildAlternateMobileField(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildThirdRow(bool isDesktop) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildRole(),
|
||||
SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
if (!widget.apiselectedUser) buildPassword()
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildRole(),
|
||||
SizedBox(height: 8), //
|
||||
if (!widget.apiselectedUser) buildPassword()
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildForthRow(bool isDesktop) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildAddress(),
|
||||
SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
buildCountryField(),
|
||||
SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
buildPostalCodeField(),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildAddress(),
|
||||
SizedBox(height: 8), //
|
||||
buildCountryField(),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
buildPostalCodeField(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildFirstNameField() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("First Name",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
controller: widget.controllers["Fname"],
|
||||
enabled: !widget.isViewMode,
|
||||
onChanged: (value) {
|
||||
_clearError("first_name");
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
labelText: "FirstName",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.errorMessages["first_name"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
widget.errorMessages["first_name"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildLastNameField() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Last Name",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
controller: widget.controllers["Lname"],
|
||||
enabled: !widget.isViewMode,
|
||||
onChanged: (value) {
|
||||
_clearError("last_name");
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
labelText: "LastName",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.errorMessages["last_name"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
widget.errorMessages["last_name"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildGenderField() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Gender",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
width: widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.12
|
||||
: null,
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: DropdownButtonFormField<String>(
|
||||
// value: selectedGender,
|
||||
value: widget.isViewMode ? null : selectedGender,
|
||||
onChanged: widget.isViewMode
|
||||
? null
|
||||
: (String? newValue) {
|
||||
setState(() {
|
||||
selectedGender = newValue;
|
||||
print("selectedGender - $selectedGender");
|
||||
});
|
||||
|
||||
widget.onGenderChanged?.call(newValue);
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
enabled: !widget.isViewMode, // Disables input when in view mode
|
||||
),
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
items: [
|
||||
DropdownMenuItem(value: "Male", child: Text("Male")),
|
||||
DropdownMenuItem(value: "Female", child: Text("Female")),
|
||||
],
|
||||
hint: Text(
|
||||
selectedGender ?? "Select Gender",
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
),
|
||||
disabledHint: Text(
|
||||
selectedGender ?? "Select Gender",
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
),
|
||||
),
|
||||
|
||||
// child: DropdownSearch<String>(
|
||||
// selectedItem: selectedGender,
|
||||
// // key: ValueKey(selectedGender),
|
||||
// popupProps: PopupProps.menu(
|
||||
// fit: FlexFit.loose, // Allows flexible height
|
||||
// constraints: BoxConstraints(maxHeight: 250),
|
||||
//
|
||||
// ),
|
||||
// items: ["Male", "Female", "Others"],
|
||||
// dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
// dropdownSearchDecoration: InputDecoration(
|
||||
// border: InputBorder.none,
|
||||
// contentPadding: EdgeInsets.symmetric(horizontal: 1,),
|
||||
// ),
|
||||
// ),
|
||||
// dropdownBuilder: (context, selectedItem) => Align( // Center-align selected item
|
||||
// alignment: Alignment.centerLeft,
|
||||
// child: Text(
|
||||
// selectedItem ?? "Select",
|
||||
// style: TextStyle(fontSize: 12),
|
||||
// ),
|
||||
// ),
|
||||
// onChanged: isViewMode
|
||||
// ? null
|
||||
// : (String? newValue) {
|
||||
// setState(() {
|
||||
// // Find the country_code based on selected country_name
|
||||
// selectedGender = newValue;
|
||||
// print("selectedGender - $selectedGender");
|
||||
// // if (selectedCountry!.isNotEmpty) {
|
||||
// // errorMessages.remove("country_code");
|
||||
// // }
|
||||
// });
|
||||
// },
|
||||
//
|
||||
//
|
||||
// ),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildDobField() {
|
||||
DateTime? _selectedDateOfBirth;
|
||||
|
||||
Future<void> _selectCheckDateOfBirth(BuildContext context) async {
|
||||
DateTime now = DateTime.now();
|
||||
DateTime today = DateTime(now.year, now.month, now.day);
|
||||
|
||||
DateTime? pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate:
|
||||
_selectedDateOfBirth != null && _selectedDateOfBirth!.isAfter(today)
|
||||
? _selectedDateOfBirth!
|
||||
: today,
|
||||
firstDate: DateTime(1900),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null && pickedDate != _selectedDateOfBirth) {
|
||||
setState(() {
|
||||
_selectedDateOfBirth = pickedDate;
|
||||
widget.controllers["dob"]?.text =
|
||||
DateFormat('yyyy-MM-dd').format(pickedDate);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Date of Birth",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
width: widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.12
|
||||
: null,
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: widget.isViewMode
|
||||
? null
|
||||
: () async {
|
||||
await _selectCheckDateOfBirth(context);
|
||||
if (widget.controllers["dob"]!.text.isNotEmpty) {
|
||||
setState(() {
|
||||
// errorMessages.remove("start_date");
|
||||
});
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
controller: widget.controllers["dob"],
|
||||
style: const TextStyle(fontSize: 12, color: Colors.black),
|
||||
decoration: const InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: Icon(Icons.calendar_today,
|
||||
size: 16, color: Color(0xFF8B8FB2)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildEmailField() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Email",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
controller: widget.controllers["email"],
|
||||
onChanged: (value) {
|
||||
_clearError("email");
|
||||
},
|
||||
enabled: !widget.isViewMode,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Email",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.errorMessages["email"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
widget.errorMessages["email"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildMobileField() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Mobile Number",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
controller: widget.controllers["mobileNumber"],
|
||||
enabled: !widget.isViewMode,
|
||||
onChanged: (value) {
|
||||
_clearError("mobile_no");
|
||||
},
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(
|
||||
r'^\d*\.?\d*$')), // Allow only positive numbers with optional decimal
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
labelText: "Mobile Number",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.errorMessages["mobile_no"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
widget.errorMessages["mobile_no"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildAlternateMobileField() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Alternate Mobile Number",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
controller: widget.controllers["alternateMobile"],
|
||||
enabled: !widget.isViewMode,
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(
|
||||
r'^\d*\.?\d*$')), // Allow only positive numbers with optional decimal
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
labelText: "Alternate Number",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.errorMessages["alternate_mobile_no"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
widget.errorMessages["alternate_mobile_no"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildCountryField() {
|
||||
late Map<String, String> countryMap; // Mapping country_code -> country_name
|
||||
late List<String> countryCodes; // List of country codes
|
||||
List<dynamic> countryList = apiCountryData ?? [];
|
||||
|
||||
countryList = apiCountryData ?? [];
|
||||
|
||||
// Map country codes to country names
|
||||
countryMap = {
|
||||
for (var item in countryList)
|
||||
item['country_code'] as String: item['country_name'] as String
|
||||
};
|
||||
|
||||
// Extract only country codes for processing
|
||||
countryCodes = countryMap.keys.toList();
|
||||
|
||||
selectedCountry ??= null;
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Country",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: DropdownSearch<String>(
|
||||
selectedItem: countryMap[selectedCountry],
|
||||
enabled: !widget.isViewMode,
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true, // Enables search functionality
|
||||
fit: FlexFit.loose, // Allows flexible height
|
||||
constraints: BoxConstraints(maxHeight: 200),
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search Country...",
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
items: countryMap.values.toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) => Align(
|
||||
// Center-align selected item
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Text(
|
||||
selectedItem ?? "Select Country",
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
),
|
||||
),
|
||||
// onChanged: widget.isViewMode
|
||||
// ? null
|
||||
// : (String? newValue) {
|
||||
// setState(() {
|
||||
// // Find the country_code based on selected country_name
|
||||
// selectedCountry = countryMap.entries
|
||||
// .firstWhere((entry) => entry.value == newValue)
|
||||
// .key;
|
||||
//
|
||||
// // if (selectedCountry!.isNotEmpty) {
|
||||
// // errorMessages.remove("country_code");
|
||||
// // }
|
||||
// });
|
||||
// widget.onCountryChanged?.call(newValue);
|
||||
// },
|
||||
|
||||
onChanged: widget.isViewMode
|
||||
? null
|
||||
: (String? newValue) {
|
||||
if (newValue == null) return;
|
||||
|
||||
final countryCode = countryMap.entries
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
|
||||
setState(() {
|
||||
selectedCountry = countryCode;
|
||||
});
|
||||
|
||||
widget.onCountryChanged
|
||||
?.call(countryCode); // ✅ send code not name
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildPostalCodeField() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Postal Code",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
controller: widget.controllers["postalCode"],
|
||||
enabled: !widget.isViewMode,
|
||||
keyboardType: TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(
|
||||
r'^\d*\.?\d*$')), // Allow only positive numbers with optional decimal
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
labelText: "Postal Code",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildRole() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Role ",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false, // Dropdown doesn't use focus
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 45, // Set appropriate height
|
||||
child: DropdownButtonFormField<String>(
|
||||
value: widget.isViewMode ? null : selectedRole,
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding:
|
||||
EdgeInsets.symmetric(horizontal: 10), // Proper padding
|
||||
),
|
||||
onChanged: widget.isViewMode
|
||||
? null
|
||||
: (newValue) {
|
||||
setState(() {
|
||||
selectedRole = newValue;
|
||||
});
|
||||
widget.onRoleChanged?.call(newValue);
|
||||
},
|
||||
items: apiRoleData?.map<DropdownMenuItem<String>>((item) {
|
||||
return DropdownMenuItem(
|
||||
value: item['dropdown_key'], // ID as value
|
||||
child: Text(item['dropdown_value'] ?? "Select"));
|
||||
}).toList(),
|
||||
hint: Text("Select"),
|
||||
disabledHint: Text(
|
||||
selectedRole ?? "Select Role",
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildAddress() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Address",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 80,
|
||||
child: TextField(
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
controller: widget.controllers["address"],
|
||||
enabled: !widget.isViewMode,
|
||||
maxLines: 2,
|
||||
keyboardType: TextInputType.multiline,
|
||||
decoration: InputDecoration(
|
||||
labelText: "Address",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
// contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 4),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildPassword() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Password",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.black)),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: TextStyle(fontSize: 12, color: Colors.black),
|
||||
controller: widget.controllers["password"],
|
||||
enabled: !widget.isViewMode,
|
||||
onChanged: (value) {
|
||||
_clearError("password");
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
labelText: "Password",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.errorMessages["password"] != null) ...[
|
||||
SizedBox(height: 5), // Space before error message
|
||||
Text(
|
||||
widget.errorMessages["password"]!,
|
||||
style: TextStyle(color: Colors.red, fontSize: 12),
|
||||
),
|
||||
],
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// apiselectedUser != null
|
||||
// ? SizedBox()
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class TravellerDetails extends StatefulWidget {
|
||||
@override
|
||||
_TravellerDetailsState createState() => _TravellerDetailsState();
|
||||
}
|
||||
|
||||
class _TravellerDetailsState extends State<TravellerDetails> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border(
|
||||
top: BorderSide(
|
||||
color: Colors.blueGrey.shade300, // Set your desired color
|
||||
width: 0.09, // Set border thickness
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
children: [Text("Traveller ...........")],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:frontend/utils/auth_utils.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@ -9,6 +10,8 @@ import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '../../config/apiUrl.dart';
|
||||
import '../../routes/custom_appBar.dart';
|
||||
import '../../routes/custom_drawer.dart';
|
||||
import '../../utils/pagination.dart';
|
||||
import '../../widgets/custom_popup.dart';
|
||||
|
||||
class UserListScreen extends StatefulWidget {
|
||||
@override
|
||||
@ -29,7 +32,7 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
TextEditingController searchController = TextEditingController();
|
||||
|
||||
int currentPage = 0;
|
||||
int itemsPerPage = 8;
|
||||
int itemsPerPage = 10;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@ -303,7 +306,7 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
bool isDesktop = sizingInfo.deviceScreenType == DeviceScreenType.desktop;
|
||||
|
||||
return Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
backgroundColor: Color(0xFFf5f5f5),
|
||||
// appBar: isDesktop ? null : const CustomAppBar(title: 'User Management'),
|
||||
// drawer: isDesktop ? null : CustomDrawer(isDesktop: false),
|
||||
appBar: CustomAppBar(isDesktop: isDesktop),
|
||||
@ -316,7 +319,7 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
vertical: MediaQuery.of(context).size.height *
|
||||
0, // 5% of screen height as vertical padding
|
||||
)
|
||||
: EdgeInsets.all(8),
|
||||
: EdgeInsets.all(0),
|
||||
child: Row(
|
||||
children: [
|
||||
// if (isDesktop) CustomDrawer(isDesktop: true),
|
||||
@ -331,6 +334,11 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
|
||||
Widget buildGroupList(bool isDesktop) {
|
||||
return Container(
|
||||
margin: isDesktop ? const EdgeInsets.only(top: 10.0, bottom: 10.0) : null,
|
||||
padding: const EdgeInsets.all(1),
|
||||
decoration: BoxDecoration(
|
||||
color: isDesktop ? Colors.white : Color(0xFFFCFCFC),
|
||||
),
|
||||
// decoration: BoxDecoration(
|
||||
// // color: Colors.amber,
|
||||
// // color: bodyColor,
|
||||
@ -370,50 +378,56 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
const Text('User List',
|
||||
style: TextStyle(
|
||||
fontFamily: "Inter",
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF212121))),
|
||||
Text(
|
||||
'Users',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 16 : 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width * 0.2,
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: searchController,
|
||||
onChanged: filterUsers,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search for a User",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 12, color: Color(0xFF9E9DBD)),
|
||||
prefixIcon: Icon(
|
||||
Icons.search,
|
||||
color: Color(0xFF9E9DBD),
|
||||
size: 18,
|
||||
if (isDesktop)
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.28,
|
||||
),
|
||||
|
||||
if (isDesktop)
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width * 0.2,
|
||||
height: 40,
|
||||
child: TextField(
|
||||
controller: searchController,
|
||||
onChanged: filterUsers,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search for a User",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 12, color: Color(0xFF9E9DBD)),
|
||||
prefixIcon: Icon(
|
||||
Icons.search,
|
||||
color: Color(0xFF9E9DBD),
|
||||
size: 18,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade200, width: 0.5),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade200, width: 0.5),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 16),
|
||||
Spacer(),
|
||||
|
||||
@ -443,7 +457,6 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
// 'apiUserData': users,
|
||||
// }
|
||||
);
|
||||
if (!isDesktop) Navigator.pop(context);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
@ -451,7 +464,9 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
children: [
|
||||
Text(
|
||||
"Add New User",
|
||||
style: TextStyle(fontSize: 13),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 13 : 11,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8), // spacing between icon and text
|
||||
Icon(
|
||||
@ -464,6 +479,54 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
if (!isDesktop)
|
||||
SizedBox(
|
||||
height: 5,
|
||||
),
|
||||
isDesktop
|
||||
? SizedBox.shrink()
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
height: 35,
|
||||
child: TextField(
|
||||
controller: searchController,
|
||||
onChanged: filterUsers,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Search for a User",
|
||||
hintStyle: TextStyle(
|
||||
fontSize: 12, color: Color(0xFF9E9DBD)),
|
||||
prefixIcon: Icon(
|
||||
Icons.search,
|
||||
color: Color(0xFF9E9DBD),
|
||||
size: 18,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade200,
|
||||
width: 0.5),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(
|
||||
color: Colors.grey.shade300, width: 1),
|
||||
),
|
||||
),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
),
|
||||
// SizedBox(width: 16),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
FutureBuilder<List<dynamic>>(
|
||||
future: futureUsers,
|
||||
@ -478,28 +541,34 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: const [
|
||||
Icon(Icons.error_outline,
|
||||
children: [
|
||||
const Icon(Icons.error_outline,
|
||||
color: Colors.redAccent, size: 60),
|
||||
SizedBox(height: 16),
|
||||
Text("Oops!",
|
||||
style: TextStyle(
|
||||
fontSize: 22,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.redAccent)),
|
||||
SizedBox(height: 8),
|
||||
Text("No Plans Available For This User",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.grey)),
|
||||
SizedBox(height: 20),
|
||||
Text("Please Create Plan",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16, color: Colors.grey)),
|
||||
SizedBox(height: 20),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
"Oops!",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.redAccent),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
"No Plans Available For This User",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.grey),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
"Please Create Plan",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16, color: Colors.grey),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -536,39 +605,42 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
horizontalInside: BorderSide(
|
||||
width: 0.5, color: Colors.grey.shade200),
|
||||
),
|
||||
columns: const [
|
||||
columns: [
|
||||
DataColumn(
|
||||
label: Text('UserName',
|
||||
style: TextStyle(
|
||||
// color: Color(0xFF9E9DBD),
|
||||
// color: Color(0xFF9E9DBD),
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'UserName',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Email Id',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Email ID',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Role',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Role',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Status',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Status',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
DataColumn(
|
||||
label: Text('Actions',
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w600))),
|
||||
label: Text(
|
||||
'Actions',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w600),
|
||||
)),
|
||||
],
|
||||
rows: paginatedUser.map((user) {
|
||||
String userId =
|
||||
@ -611,40 +683,46 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
fontWeight: FontWeight.w400),
|
||||
))),
|
||||
DataCell(
|
||||
Row(
|
||||
children: [
|
||||
MouseRegion(
|
||||
cursor: user['is_active'] == "0"
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.remove_red_eye,
|
||||
size: 18,
|
||||
color: user['is_active'] == "0"
|
||||
? Colors.grey
|
||||
: Color(0xFF475569)),
|
||||
onPressed: user['is_active'] == "0"
|
||||
? null
|
||||
: () {
|
||||
context.go(
|
||||
"/CreateUserDetails",
|
||||
extra: {
|
||||
"selectedUser": user,
|
||||
"isViewMode": true
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
|
||||
MouseRegion(
|
||||
cursor: user['is_active'] == "0"
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: user['is_active'] == "0"
|
||||
? null
|
||||
: () {
|
||||
PopupMenuButton<int>(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.zero,
|
||||
offset: Offset(0, 30),
|
||||
icon: Icon(
|
||||
Icons.more_vert,
|
||||
color: Color(0xFF475569),
|
||||
size: 14,
|
||||
),
|
||||
itemBuilder: (context) => [
|
||||
CustomPopupMenuEntry(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 8, vertical: 8),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.remove_red_eye,
|
||||
color:
|
||||
Color(0xFF475569),
|
||||
size: 18),
|
||||
onPressed: () {
|
||||
context.go(
|
||||
"/CreateUserDetails",
|
||||
extra: {
|
||||
"selectedUser": user,
|
||||
"isViewMode": true
|
||||
},
|
||||
);
|
||||
}),
|
||||
IconButton(
|
||||
icon: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15),
|
||||
onPressed: () {
|
||||
context.go(
|
||||
"/CreateUserDetails",
|
||||
extra: {
|
||||
@ -653,52 +731,95 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
},
|
||||
);
|
||||
},
|
||||
child: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// MouseRegion(
|
||||
// cursor: user['is_active'] == "0"
|
||||
// ? SystemMouseCursors
|
||||
// .forbidden
|
||||
// : SystemMouseCursors.click,
|
||||
// child: IconButton(
|
||||
// icon: Icon(Icons.edit,
|
||||
// color:
|
||||
// user['is_active'] ==
|
||||
// "0"
|
||||
// ? Colors.grey
|
||||
// : Colors.green),
|
||||
// onPressed:
|
||||
// user['is_active'] == "0"
|
||||
// ? null
|
||||
// : () {
|
||||
// print(
|
||||
// "USER: $user");
|
||||
//
|
||||
// // final userJson = jsonEncode(
|
||||
// // user); // Convert user map to string
|
||||
// // final encodedUser =
|
||||
// // Uri.encodeComponent(
|
||||
// // userJson);
|
||||
//
|
||||
// context.go(
|
||||
// "/CreateUserDetails",
|
||||
// extra: {
|
||||
// "selectedUser":
|
||||
// user,
|
||||
// "isViewMode":
|
||||
// false
|
||||
// },
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
// Row(
|
||||
// children: [
|
||||
// MouseRegion(
|
||||
// cursor: user['is_active'] == "0"
|
||||
// ? SystemMouseCursors.forbidden
|
||||
// : SystemMouseCursors.click,
|
||||
// child: IconButton(
|
||||
// icon: Icon(Icons.remove_red_eye,
|
||||
// size: 18,
|
||||
// color: user['is_active'] == "0"
|
||||
// ? Colors.grey
|
||||
// : Color(0xFF475569)),
|
||||
// onPressed: user['is_active'] == "0"
|
||||
// ? null
|
||||
// : () {
|
||||
// context.go(
|
||||
// "/CreateUserDetails",
|
||||
// extra: {
|
||||
// "selectedUser": user,
|
||||
// "isViewMode": true
|
||||
// },
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
//
|
||||
// MouseRegion(
|
||||
// cursor: user['is_active'] == "0"
|
||||
// ? SystemMouseCursors.forbidden
|
||||
// : SystemMouseCursors.click,
|
||||
// child: GestureDetector(
|
||||
// onTap: user['is_active'] == "0"
|
||||
// ? null
|
||||
// : () {
|
||||
//
|
||||
// },
|
||||
// child: Image.asset(
|
||||
// 'assets/images/IconsImg/edit.png',
|
||||
// width: 20,
|
||||
// height: 15),
|
||||
// ),
|
||||
// ),
|
||||
//
|
||||
// // MouseRegion(
|
||||
// // cursor: user['is_active'] == "0"
|
||||
// // ? SystemMouseCursors
|
||||
// // .forbidden
|
||||
// // : SystemMouseCursors.click,
|
||||
// // child: IconButton(
|
||||
// // icon: Icon(Icons.edit,
|
||||
// // color:
|
||||
// // user['is_active'] ==
|
||||
// // "0"
|
||||
// // ? Colors.grey
|
||||
// // : Colors.green),
|
||||
// // onPressed:
|
||||
// // user['is_active'] == "0"
|
||||
// // ? null
|
||||
// // : () {
|
||||
// // print(
|
||||
// // "USER: $user");
|
||||
// //
|
||||
// // // final userJson = jsonEncode(
|
||||
// // // user); // Convert user map to string
|
||||
// // // final encodedUser =
|
||||
// // // Uri.encodeComponent(
|
||||
// // // userJson);
|
||||
// //
|
||||
// // context.go(
|
||||
// // "/CreateUserDetails",
|
||||
// // extra: {
|
||||
// // "selectedUser":
|
||||
// // user,
|
||||
// // "isViewMode":
|
||||
// // false
|
||||
// // },
|
||||
// // );
|
||||
// // },
|
||||
// // ),
|
||||
// // ),
|
||||
// ],
|
||||
// ),
|
||||
),
|
||||
]);
|
||||
}).toList(),
|
||||
@ -707,65 +828,203 @@ class _UserListScreenState extends State<UserListScreen> {
|
||||
},
|
||||
);
|
||||
|
||||
Widget buildMobileCardView(List<dynamic> paginatedUser) {
|
||||
return ListView.builder(
|
||||
itemCount: paginatedUser.length,
|
||||
itemBuilder: (context, index) {
|
||||
final user = paginatedUser[index];
|
||||
return Card(
|
||||
color: Colors.white,
|
||||
margin: EdgeInsets.symmetric(
|
||||
horizontal: 12, vertical: 6),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
elevation: 3,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Status and Employee Code
|
||||
Row(
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
user['role_value'] ?? 'N/A',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 10,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.w700),
|
||||
),
|
||||
PopupMenuButton<int>(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.zero,
|
||||
offset: Offset(0, 30),
|
||||
icon: Icon(
|
||||
Icons.more_vert,
|
||||
color: Color(0xFF475569),
|
||||
size: 14,
|
||||
),
|
||||
itemBuilder: (context) => [
|
||||
CustomPopupMenuEntry(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 8, vertical: 8),
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize.min,
|
||||
mainAxisAlignment:
|
||||
MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons
|
||||
.remove_red_eye,
|
||||
color: Color(
|
||||
0xFF475569),
|
||||
size: 18),
|
||||
onPressed: () {
|
||||
context.go(
|
||||
"/CreateUserDetails",
|
||||
extra: {
|
||||
"selectedUser":
|
||||
user,
|
||||
"isViewMode": true
|
||||
},
|
||||
);
|
||||
}),
|
||||
IconButton(
|
||||
icon: Image.asset(
|
||||
'assets/images/IconsImg/edit.png',
|
||||
width: 20,
|
||||
height: 15),
|
||||
onPressed: () {
|
||||
context.go(
|
||||
"/CreateUserDetails",
|
||||
extra: {
|
||||
"selectedUser":
|
||||
user,
|
||||
"isViewMode": false
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
SizedBox(height: 2),
|
||||
// Trip Id and Trip Name
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"${user['first_name'] ?? ''} ${user['last_name'] ?? ''}",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: Colors.black87,
|
||||
fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 2),
|
||||
|
||||
// Name
|
||||
Row(
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
user['email'] ?? '',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 10,
|
||||
color: Colors.black87),
|
||||
),
|
||||
],
|
||||
),
|
||||
Spacer(),
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
handleToggleUserStatus(
|
||||
user['user_id'],
|
||||
user['is_active'],
|
||||
user);
|
||||
},
|
||||
child: Text(
|
||||
user['is_active'] == "1"
|
||||
? "Active"
|
||||
: "Inactive",
|
||||
style: TextStyle(
|
||||
color:
|
||||
user['is_active'] ==
|
||||
"1"
|
||||
? Colors.green
|
||||
: Colors.grey,
|
||||
fontFamily: "Inter",
|
||||
fontSize: 11,
|
||||
fontWeight:
|
||||
FontWeight.w400),
|
||||
))
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
// Actions
|
||||
// Actions
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
return Expanded(
|
||||
child: Column(
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
isDesktop
|
||||
? table
|
||||
: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SingleChildScrollView(
|
||||
Expanded(
|
||||
child: isDesktop
|
||||
? SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: table,
|
||||
),
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
// Previous button with arrow icon
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.arrow_back_ios_new,
|
||||
size: 10,
|
||||
),
|
||||
onPressed: currentPage > 0
|
||||
? () {
|
||||
setState(() {
|
||||
currentPage--;
|
||||
});
|
||||
}
|
||||
: null,
|
||||
),
|
||||
SizedBox(width: 2),
|
||||
|
||||
// Page number text
|
||||
Text(
|
||||
'Page ${currentPage + 1}',
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.black87,
|
||||
fontFamily: "Inter",
|
||||
),
|
||||
),
|
||||
SizedBox(width: 2),
|
||||
|
||||
// Next button with arrow icon
|
||||
IconButton(
|
||||
icon: Icon(
|
||||
Icons.arrow_forward_ios,
|
||||
size: 10,
|
||||
),
|
||||
onPressed: (currentPage + 1) * itemsPerPage <
|
||||
users.length
|
||||
? () {
|
||||
setState(() {
|
||||
currentPage++;
|
||||
});
|
||||
}
|
||||
: null,
|
||||
),
|
||||
],
|
||||
child: table, // <-- your existing table
|
||||
)
|
||||
: buildMobileCardView(paginatedUser),
|
||||
),
|
||||
PaginationControls(
|
||||
currentPage: currentPage,
|
||||
itemsPerPage: itemsPerPage,
|
||||
totalItems: users.length,
|
||||
activeColor: layoutColor, // your theme color
|
||||
onPageChanged: (page) {
|
||||
setState(() {
|
||||
currentPage = page;
|
||||
});
|
||||
},
|
||||
onItemsPerPageChanged: (items) {
|
||||
setState(() {
|
||||
itemsPerPage = items;
|
||||
currentPage = 0;
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -205,7 +205,7 @@ class _CustomDrawerState extends State<CustomDrawer> {
|
||||
TextStyle(fontSize: 11, color: Color(0xFF212121)),
|
||||
),
|
||||
Image.asset(
|
||||
'assets/images/login/travelSpend_Logo.png',
|
||||
'assets/images/login/logoNew.jpg',
|
||||
width: 90,
|
||||
height: 25,
|
||||
fit: BoxFit.contain,
|
||||
|
||||
@ -10,7 +10,7 @@ import 'package:frontend/Screens/plans/create_plans.dart';
|
||||
import 'package:frontend/Screens/plans/list_plans.dart';
|
||||
import 'package:frontend/Screens/policy/policy.dart';
|
||||
import 'package:frontend/Screens/policy/policy_list.dart';
|
||||
import 'package:frontend/Screens/userManagement/create_user/create_user.dart';
|
||||
import 'package:frontend/Screens/userManagement/create_user/create_user1.dart';
|
||||
import 'package:frontend/Screens/userManagement/user_List.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
@ -19,6 +19,7 @@ import '../Screens/allTrips/travel_agent_list.dart';
|
||||
import '../Screens/approvals/approval_list.dart';
|
||||
import '../Screens/group/group.dart';
|
||||
import '../Screens/group/groupList.dart';
|
||||
import '../Screens/userManagement/create_user/create_user.dart';
|
||||
|
||||
final GoRouter router = GoRouter(
|
||||
routes: [
|
||||
@ -52,7 +53,7 @@ final GoRouter router = GoRouter(
|
||||
),
|
||||
GoRoute(
|
||||
path: '/CreateUserDetails',
|
||||
builder: (context, state) => CreateUserForm(),
|
||||
builder: (context, state) => CreateUserFormDetials(),
|
||||
// builder: (context, state) {
|
||||
// final userParam = state.uri.queryParameters['user'];
|
||||
//
|
||||
|
||||
@ -234,6 +234,42 @@ class ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<dynamic>> fetchFindGroup() async {
|
||||
String? orgId = await getOrgId();
|
||||
|
||||
final String apiUrldata = '$apiUrl/api/groups/find/$orgId';
|
||||
|
||||
final token = await getToken();
|
||||
|
||||
if (token == null) {
|
||||
throw Exception('Token not found. Please log in.');
|
||||
}
|
||||
|
||||
final response = await http.get(
|
||||
Uri.parse(apiUrldata),
|
||||
headers: {
|
||||
'Authorization': 'Bearer $token',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
try {
|
||||
final data = json.decode(response.body);
|
||||
print(data);
|
||||
if (!data.containsKey('data') || data['data'] is! List) {
|
||||
throw Exception(
|
||||
"Invalid response format: 'data' field is missing or not a List");
|
||||
}
|
||||
return data['data'];
|
||||
} catch (e) {
|
||||
throw Exception('Error parsing response: $e');
|
||||
}
|
||||
} else {
|
||||
throw Exception('Failed to load plans');
|
||||
}
|
||||
}
|
||||
|
||||
Future<List<dynamic>> fetchAllPolicy() async {
|
||||
String? orgId = await getOrgId();
|
||||
|
||||
|
||||
@ -77,12 +77,14 @@ flutter:
|
||||
- assets/images/login/travelSpend_Logo.png
|
||||
- assets/images/login/TravelSpendsLogo1.png
|
||||
- assets/images/login/VectorG.png
|
||||
- assets/images/login/logoNew.jpg
|
||||
- assets/images/login/microsoft.png
|
||||
- assets/images/IconsImg/delete.png
|
||||
- assets/images/IconsImg/edit.png
|
||||
- assets/images/IconsImg/planPdf_icon.png
|
||||
|
||||
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
|
||||
Loading…
Reference in New Issue
Block a user