userManagement changes ,profile highlighter
This commit is contained in:
parent
53f2c4d5b5
commit
b55b908f42
@ -403,7 +403,7 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
),
|
||||
if (isDesktop)
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.19,
|
||||
width: MediaQuery.of(context).size.width * 0.23,
|
||||
),
|
||||
|
||||
if (isDesktop)
|
||||
|
||||
@ -2,6 +2,7 @@ import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:frontend/config/apiUrl.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
@ -258,7 +259,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
return Container(
|
||||
// color: Color(0xFF114D8B),
|
||||
color: Color(0xFFf5f5f5),
|
||||
padding: const EdgeInsets.all(20),
|
||||
|
||||
padding: const EdgeInsets.all(10),
|
||||
child: Row(
|
||||
children: [
|
||||
if (widget.isDesktop)
|
||||
@ -266,42 +268,67 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
flex: 2,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
image: DecorationImage(
|
||||
image: AssetImage(
|
||||
'assets/images/login/login_travel.png',
|
||||
),
|
||||
|
||||
// fit: BoxFit.fill
|
||||
// image: DecorationImage(
|
||||
// image: AssetImage(
|
||||
// 'assets/images/login/login_travel.png',
|
||||
// ),
|
||||
// // fit: BoxFit.fill
|
||||
// fit: BoxFit.contain
|
||||
// fit: BoxFit.cover, // or BoxFit.contain, BoxFit.fill, etc.
|
||||
),
|
||||
color: Colors.white,
|
||||
// // fit: BoxFit.cover, // or BoxFit.contain, BoxFit.fill, etc.
|
||||
// ),
|
||||
color: Color(0xFFE6F0FA),
|
||||
// color: Color(0xFFF0F7FF),
|
||||
// color: Colors.white,
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(25), // Rounded top-left corner
|
||||
topRight: Radius.circular(250), // Rounded top-left corner
|
||||
bottomRight:
|
||||
Radius.circular(25), // Rounded bottom-left corner
|
||||
Radius.circular(250), // Rounded bottom-left corner
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
left: 0,
|
||||
),
|
||||
child: Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Image.asset(
|
||||
// child: Padding(
|
||||
// padding: const EdgeInsets.only(
|
||||
// left: 0,
|
||||
// ),
|
||||
// child: Align(
|
||||
// alignment: Alignment.topLeft,
|
||||
// child: Image.asset(
|
||||
// 'assets/images/login/logoNew.jpg',
|
||||
// width: 200, // Optional: control size
|
||||
// height: 100,
|
||||
// fit: BoxFit.contain,
|
||||
// )),
|
||||
// ),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/images/login/logoNew.jpg',
|
||||
width: 200, // Optional: control size
|
||||
height: 100,
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: Align(
|
||||
// alignment: Alignment.bottomRight,
|
||||
child: Image.asset(
|
||||
'assets/images/login/login_travel.png',
|
||||
// width: 200, // Optional: control size
|
||||
// height: 100,
|
||||
fit: BoxFit.contain,
|
||||
)),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
// color: Colors.white,
|
||||
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(25), // Rounded top-left corner
|
||||
bottomLeft: Radius.circular(25), // Rounded bottom-left corner
|
||||
@ -329,20 +356,18 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Text(
|
||||
Text(
|
||||
"Sign In",
|
||||
style: TextStyle(
|
||||
fontSize: 26,
|
||||
fontFamily: "Nunito",
|
||||
fontWeight: FontWeight.w600,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF212121)),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
const Text(
|
||||
Text(
|
||||
"Welcome To TravelSpends",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
fontFamily: "Nunito",
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Color(0xFF212121)),
|
||||
),
|
||||
@ -353,10 +378,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
_buildLabel("Email Address"),
|
||||
TextFormField(
|
||||
controller: _emailController,
|
||||
style: TextStyle(
|
||||
fontFamily: "Archivo",
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 11),
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w600, fontSize: 11),
|
||||
decoration:
|
||||
_inputDecoration("Enter your email address").copyWith(
|
||||
prefixIcon: Icon(
|
||||
@ -374,10 +397,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
_buildLabel("Password"),
|
||||
TextFormField(
|
||||
controller: _passwordController,
|
||||
style: TextStyle(
|
||||
fontFamily: "Archivo",
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 11),
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w600, fontSize: 11),
|
||||
obscureText: _obscureText,
|
||||
decoration: _inputDecoration("Enter your password").copyWith(
|
||||
prefixIcon: Icon(
|
||||
@ -422,10 +443,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
children: [
|
||||
Text(
|
||||
"Sign In",
|
||||
style: TextStyle(
|
||||
fontFamily: "Nunito",
|
||||
fontWeight: FontWeight.w800,
|
||||
fontSize: 15),
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w800, fontSize: 15),
|
||||
),
|
||||
SizedBox(
|
||||
width: 3,
|
||||
@ -445,10 +464,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
_buildLabel("Email Address"),
|
||||
TextFormField(
|
||||
controller: _emailController,
|
||||
style: TextStyle(
|
||||
fontFamily: "Archivo",
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 11),
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w600, fontSize: 11),
|
||||
decoration:
|
||||
_inputDecoration("Enter your email address").copyWith(
|
||||
prefixIcon: Icon(
|
||||
@ -481,10 +498,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
children: [
|
||||
Text(
|
||||
"Submit",
|
||||
style: TextStyle(
|
||||
fontFamily: "Nunito",
|
||||
fontWeight: FontWeight.w800,
|
||||
fontSize: 15),
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w800, fontSize: 15),
|
||||
),
|
||||
SizedBox(
|
||||
width: 3,
|
||||
@ -505,10 +520,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
TextFormField(
|
||||
controller: _emailController,
|
||||
readOnly: true,
|
||||
style: TextStyle(
|
||||
fontFamily: "Archivo",
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 11),
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w600, fontSize: 11),
|
||||
decoration:
|
||||
_inputDecoration("Enter your email address").copyWith(
|
||||
prefixIcon: Icon(
|
||||
@ -523,10 +536,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
_buildLabel("OTP"),
|
||||
TextFormField(
|
||||
controller: _otpController,
|
||||
style: TextStyle(
|
||||
fontFamily: "Archivo",
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 11),
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w600, fontSize: 11),
|
||||
decoration: _inputDecoration("Enter your OTP").copyWith(
|
||||
prefixIcon: Icon(
|
||||
Icons.email_outlined,
|
||||
@ -540,10 +551,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
_buildLabel("New Password"),
|
||||
TextFormField(
|
||||
controller: _newPasswordController,
|
||||
style: TextStyle(
|
||||
fontFamily: "Archivo",
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 11),
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w600, fontSize: 11),
|
||||
obscureText: _obscureText,
|
||||
decoration:
|
||||
_inputDecoration("Enter your new password").copyWith(
|
||||
@ -569,10 +578,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
_buildLabel("Confirm Password"),
|
||||
TextFormField(
|
||||
controller: _confirmPasswordController,
|
||||
style: TextStyle(
|
||||
fontFamily: "Archivo",
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 11),
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w600, fontSize: 11),
|
||||
obscureText: _obscureText,
|
||||
decoration:
|
||||
_inputDecoration("Enter your confirm password").copyWith(
|
||||
@ -630,10 +637,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
children: [
|
||||
Text(
|
||||
"Submit",
|
||||
style: TextStyle(
|
||||
fontFamily: "Nunito",
|
||||
fontWeight: FontWeight.w800,
|
||||
fontSize: 15),
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w800, fontSize: 15),
|
||||
),
|
||||
SizedBox(
|
||||
width: 3,
|
||||
@ -663,10 +668,10 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
},
|
||||
child: Text(
|
||||
"Forgot Password",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w300,
|
||||
fontFamily: "Nunito",
|
||||
|
||||
color: Color(0xFF212121), // Text color
|
||||
decoration:
|
||||
TextDecoration.underline, // Underline the text
|
||||
@ -686,10 +691,10 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
},
|
||||
child: Text(
|
||||
"Back to Login",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w300,
|
||||
fontFamily: "Nunito",
|
||||
|
||||
color: Color(0xFF212121), // Text color
|
||||
decoration:
|
||||
TextDecoration.underline, // Underline the text
|
||||
@ -726,10 +731,8 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
children: [
|
||||
Text(
|
||||
"Sign In With Microsoft",
|
||||
style: TextStyle(
|
||||
fontFamily: "Nunito",
|
||||
fontWeight: FontWeight.w500,
|
||||
fontSize: 15),
|
||||
style: GoogleFonts.poppins(
|
||||
fontWeight: FontWeight.w500, fontSize: 14),
|
||||
),
|
||||
SizedBox(
|
||||
width: 3,
|
||||
@ -785,10 +788,9 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
padding: const EdgeInsets.only(bottom: 8),
|
||||
child: Text(
|
||||
text,
|
||||
style: const TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w700,
|
||||
fontFamily: "Nunito",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF212121)),
|
||||
),
|
||||
),
|
||||
@ -803,7 +805,7 @@ class _LoginWidgetState extends State<LoginWidget> {
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 1.0, horizontal: 0.0),
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
labelStyle: TextStyle(fontSize: 11, color: Colors.grey),
|
||||
labelStyle: GoogleFonts.poppins(fontSize: 11, color: Colors.grey),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(18),
|
||||
borderSide: BorderSide(
|
||||
|
||||
@ -8,6 +8,7 @@ import 'package:frontend/Screens/organization/mailSettings.dart';
|
||||
import 'package:frontend/Screens/organization/themeColor.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:image_picker/image_picker.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
@ -415,7 +416,7 @@ class _groupState extends State<Group> {
|
||||
children: [
|
||||
Text(
|
||||
"Create Group",
|
||||
style: TextStyle(fontSize: 18),
|
||||
style: GoogleFonts.poppins(fontSize: 18),
|
||||
),
|
||||
// Container(
|
||||
// color: Color(0xFFE9EBF6),
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../config/apiUrl.dart';
|
||||
@ -224,7 +225,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
children: [
|
||||
Text(
|
||||
"Sender Email",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -254,11 +255,11 @@ class _MailSettingState extends State<MailSetting> {
|
||||
"Invalid email format";
|
||||
}
|
||||
},
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "sender email",
|
||||
labelStyle:
|
||||
TextStyle(fontSize: 12, color: Colors.grey),
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
@ -315,7 +316,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
children: [
|
||||
Text(
|
||||
"Test Mail",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
color: Color(0xFF114D8B), fontWeight: FontWeight.w600),
|
||||
),
|
||||
],
|
||||
@ -340,7 +341,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
children: [
|
||||
Text(
|
||||
"User Name",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -360,10 +361,11 @@ class _MailSettingState extends State<MailSetting> {
|
||||
onChanged: (value) {
|
||||
_clearError("mail_user_name");
|
||||
},
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "user name",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
@ -385,7 +387,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
children: [
|
||||
Text(
|
||||
"Password",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -409,7 +411,8 @@ class _MailSettingState extends State<MailSetting> {
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "password",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
@ -449,7 +452,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
children: [
|
||||
Text(
|
||||
"Host",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -469,10 +472,11 @@ class _MailSettingState extends State<MailSetting> {
|
||||
onChanged: (value) {
|
||||
_clearError("mail_host");
|
||||
},
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "host",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
@ -494,7 +498,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
children: [
|
||||
Text(
|
||||
"Port",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -514,10 +518,11 @@ class _MailSettingState extends State<MailSetting> {
|
||||
onChanged: (value) {
|
||||
_clearError("mail_port");
|
||||
},
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "port",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
@ -544,7 +549,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
children: [
|
||||
Text(
|
||||
"Enter Your Mail Id",
|
||||
style: TextStyle(
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF575A74)),
|
||||
@ -573,10 +578,11 @@ class _MailSettingState extends State<MailSetting> {
|
||||
errorMessages["to_mail"] = "Invalid email format";
|
||||
}
|
||||
},
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
labelText: "To mail",
|
||||
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
@ -616,7 +622,7 @@ class _MailSettingState extends State<MailSetting> {
|
||||
},
|
||||
child: Text(
|
||||
"Test Email",
|
||||
style: TextStyle(fontSize: 12),
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
))
|
||||
],
|
||||
),
|
||||
|
||||
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:frontend/Screens/organization/mailSettings.dart';
|
||||
import 'package:frontend/Screens/organization/themeColor.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http_parser/http_parser.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
@ -444,7 +445,8 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(20),
|
||||
padding: const EdgeInsets.only(
|
||||
left: 20, right: 20, bottom: 20, top: 5),
|
||||
// height: MediaQuery.of(context).size.height * 0.8,
|
||||
color: Colors.white,
|
||||
child: Column(
|
||||
@ -460,8 +462,8 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
selectedOrg != null && selectedOrg!.isNotEmpty
|
||||
? "Update Organization"
|
||||
: "Create Organization",
|
||||
style: TextStyle(
|
||||
fontSize: 15, fontWeight: FontWeight.w800),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 15, fontWeight: FontWeight.w500),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -472,12 +474,11 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 1.0),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 1.0),
|
||||
child: Text(
|
||||
"Name:",
|
||||
style: TextStyle(
|
||||
fontFamily: "Archivo",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF212121)),
|
||||
@ -487,14 +488,15 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
controller: _orgNameController,
|
||||
style: TextStyle(
|
||||
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 16,
|
||||
color: Color(0xFF114D8B),
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
hintText: "Enter Organization Name",
|
||||
hintStyle:
|
||||
TextStyle(fontSize: 14, color: Colors.grey),
|
||||
hintStyle: GoogleFonts.poppins(
|
||||
fontSize: 14, color: Colors.grey),
|
||||
floatingLabelBehavior:
|
||||
FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
@ -543,8 +545,90 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: 5,
|
||||
height: 10,
|
||||
),
|
||||
|
||||
Text(
|
||||
"Services",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF212121)),
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Color(0xFFF4F4FB)),
|
||||
borderRadius: BorderRadius.circular(1),
|
||||
// color: bodyColor,
|
||||
// color: Color(0xFFF5F5F5),
|
||||
color: Colors.white),
|
||||
padding:
|
||||
EdgeInsets.only(left: 5, right: 5, top: 15, bottom: 5),
|
||||
child: isDesktop
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
children: _buildOptions(),
|
||||
)
|
||||
: Expanded(
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: _buildOptions(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Choose Theme",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF212121)),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
// border: Border.all(color: Color(0xFFF4F4FB)),
|
||||
borderRadius: BorderRadius.circular(1),
|
||||
// color: Color(0xFFF4F4FB),
|
||||
),
|
||||
padding: EdgeInsets.only(
|
||||
left: 5, right: 5, top: 15, bottom: 5),
|
||||
child: layoutColor != null && bodyColor != null
|
||||
? ColorThemePickerWidget(
|
||||
initialLayoutColor: layoutColor,
|
||||
initialBodyColor: bodyColor,
|
||||
onLayoutColorSelected:
|
||||
(Color selectedLayoutColor) {
|
||||
setState(() {
|
||||
layoutColor = selectedLayoutColor;
|
||||
});
|
||||
},
|
||||
onBodyColorSelected: (Color selectedBodyColor) {
|
||||
setState(() {
|
||||
bodyColor = selectedBodyColor;
|
||||
});
|
||||
},
|
||||
)
|
||||
: CircularProgressIndicator(),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
Container(
|
||||
color: Colors.white,
|
||||
@ -555,8 +639,7 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
children: [
|
||||
Text(
|
||||
"Mail Settings",
|
||||
style: TextStyle(
|
||||
fontFamily: "Archivo",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF212121)),
|
||||
@ -615,89 +698,6 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
))
|
||||
],
|
||||
)),
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
|
||||
Text(
|
||||
"Services",
|
||||
style: TextStyle(
|
||||
fontFamily: "Archivo",
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF212121)),
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Color(0xFFF4F4FB)),
|
||||
borderRadius: BorderRadius.circular(1),
|
||||
// color: bodyColor,
|
||||
// color: Color(0xFFF5F5F5),
|
||||
color: Colors.white),
|
||||
padding:
|
||||
EdgeInsets.only(left: 5, right: 5, top: 15, bottom: 5),
|
||||
child: isDesktop
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
children: _buildOptions(),
|
||||
)
|
||||
: Expanded(
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: _buildOptions(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
height: 15,
|
||||
),
|
||||
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Choose Theme",
|
||||
style: TextStyle(
|
||||
fontFamily: "Archivo",
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Color(0xFF212121)),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
// border: Border.all(color: Color(0xFFF4F4FB)),
|
||||
borderRadius: BorderRadius.circular(1),
|
||||
// color: Color(0xFFF4F4FB),
|
||||
),
|
||||
padding: EdgeInsets.only(
|
||||
left: 5, right: 5, top: 15, bottom: 5),
|
||||
child: layoutColor != null && bodyColor != null
|
||||
? ColorThemePickerWidget(
|
||||
initialLayoutColor: layoutColor,
|
||||
initialBodyColor: bodyColor,
|
||||
onLayoutColorSelected:
|
||||
(Color selectedLayoutColor) {
|
||||
setState(() {
|
||||
layoutColor = selectedLayoutColor;
|
||||
});
|
||||
},
|
||||
onBodyColorSelected: (Color selectedBodyColor) {
|
||||
setState(() {
|
||||
bodyColor = selectedBodyColor;
|
||||
});
|
||||
},
|
||||
)
|
||||
: CircularProgressIndicator(),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
// isDesktop
|
||||
// ? Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.end,
|
||||
@ -775,21 +775,19 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
color:
|
||||
isSelected == name ? Color(0xFF114D8B) : Color(0xFF475569)),
|
||||
|
||||
SizedBox(width: 5),
|
||||
SizedBox(width: 2),
|
||||
|
||||
SizedBox(width: 5),
|
||||
Text(
|
||||
name,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
color: isSelected == name ? Color(0xFF114D8B) : Color(0xFF475569),
|
||||
fontFamily: "Archivo",
|
||||
fontWeight:
|
||||
isSelected == name ? FontWeight.bold : FontWeight.w500),
|
||||
// fontWeight: selectedListOption == title ? FontWeight.bold : FontWeight.normal,)),
|
||||
),
|
||||
|
||||
SizedBox(width: 5),
|
||||
SizedBox(width: 2),
|
||||
// if (selectedListOption == title && widget.isViewMode == false)
|
||||
Container(
|
||||
height: 15,
|
||||
@ -849,7 +847,10 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
onPressed: () {
|
||||
context.go('/listPlan');
|
||||
},
|
||||
child: Text("Cancel")),
|
||||
child: Text(
|
||||
"Cancel",
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
)),
|
||||
SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
@ -871,7 +872,10 @@ class _OrgSetUpState extends State<OrgSetUp> {
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 12),
|
||||
),
|
||||
onPressed: handleSubmit, // Disable when in view mode
|
||||
child: Text("Submit"),
|
||||
child: Text(
|
||||
"Submit",
|
||||
style: GoogleFonts.poppins(fontSize: 12),
|
||||
),
|
||||
),
|
||||
)
|
||||
];
|
||||
|
||||
@ -379,7 +379,10 @@ class _ListPlansState extends State<ListPlans> {
|
||||
],
|
||||
),
|
||||
|
||||
Spacer(),
|
||||
// Spacer(),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.23,
|
||||
),
|
||||
if (isDesktop)
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width * 0.2,
|
||||
@ -773,7 +776,8 @@ class _ListPlansState extends State<ListPlans> {
|
||||
context); // Close popup manually
|
||||
ApiService.viewPlan(
|
||||
context, plan.planId,
|
||||
isViewMode: true);
|
||||
isViewMode: true,
|
||||
isMyTrips: true);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
@ -785,7 +789,8 @@ class _ListPlansState extends State<ListPlans> {
|
||||
Navigator.pop(context);
|
||||
ApiService.viewPlan(
|
||||
context, plan.planId,
|
||||
isViewMode: false);
|
||||
isViewMode: false,
|
||||
isMyTrips: true);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
|
||||
@ -70,6 +70,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
late List<dynamic>? apiRoleData;
|
||||
late List<dynamic>? apiUserData;
|
||||
Map<String, dynamic>? apiselectedUser;
|
||||
List<Map<String, dynamic>> selectedServiceIds = [];
|
||||
|
||||
late List<dynamic> userList;
|
||||
late Future<List<dynamic>> futureUsers;
|
||||
@ -146,7 +147,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
"address": controllers["address"]?.text,
|
||||
"gender": selectedGender,
|
||||
// "gender": personalDetailsKey.currentState?.selectedGender,
|
||||
|
||||
"agent_supported_service_ids": selectedServiceIds,
|
||||
"postal_code": controllers["postalCode"]?.text,
|
||||
"country_code": selectedCountry,
|
||||
"employee_code": controllers["employeeCode"]?.text,
|
||||
@ -270,6 +271,27 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
selectedThirdApprover =
|
||||
apiselectedUser?["third_approver"]?.toString() ?? "";
|
||||
}
|
||||
try {
|
||||
final raw = apiselectedUser!["agent_supported_service_ids"];
|
||||
|
||||
// Fix the invalid JSON (dangerous if the format changes)
|
||||
final fixedJson = raw.replaceAllMapped(
|
||||
RegExp(r'(\w+):'), // matches `service_id:`
|
||||
(match) => '"${match.group(1)}":',
|
||||
);
|
||||
|
||||
List<dynamic> decodedList = jsonDecode(fixedJson);
|
||||
|
||||
selectedServiceIds = decodedList.map<Map<String, dynamic>>((item) {
|
||||
final map = Map<String, dynamic>.from(item);
|
||||
return {
|
||||
"service_id": map['service_id'].toString(),
|
||||
};
|
||||
}).toList();
|
||||
} catch (e) {
|
||||
print("❌ Error decoding fixed agent_supported_service_ids: $e");
|
||||
selectedServiceIds = [];
|
||||
}
|
||||
|
||||
print("Updated selectedGender: $selectedGender"); // Debugging
|
||||
|
||||
@ -932,6 +954,13 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
selectedRole = role;
|
||||
});
|
||||
},
|
||||
|
||||
onServiceIdsChanged: (List<Map<String, dynamic>> updatedList) {
|
||||
setState(() {
|
||||
selectedServiceIds = updatedList;
|
||||
});
|
||||
},
|
||||
initialSelectedServices: selectedServiceIds,
|
||||
);
|
||||
case "office":
|
||||
return OfficeDetails(
|
||||
@ -991,6 +1020,11 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
selectedCountry: selectedCountry,
|
||||
apiselectedUser: isapiselectedUser,
|
||||
onUserTypeChanged: handleUserTypeChange,
|
||||
onServiceIdsChanged: (List<Map<String, dynamic>> updatedList) {
|
||||
setState(() {
|
||||
selectedServiceIds = updatedList;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,10 +20,13 @@ class PersonalDetails extends StatefulWidget {
|
||||
final bool isViewMode;
|
||||
final bool apiselectedUser;
|
||||
|
||||
final Function(List<Map<String, dynamic>>)? onServiceIdsChanged;
|
||||
|
||||
final ValueChanged<String?>? onGenderChanged;
|
||||
final ValueChanged<String?>? onCountryChanged;
|
||||
final ValueChanged<String?>? onRoleChanged;
|
||||
final void Function(bool)? onUserTypeChanged;
|
||||
final List<Map<String, dynamic>>? initialSelectedServices;
|
||||
|
||||
final String? selectedGender;
|
||||
final String? selectedCountry;
|
||||
@ -35,7 +38,9 @@ class PersonalDetails extends StatefulWidget {
|
||||
this.selectedGender,
|
||||
this.selectedCountry,
|
||||
this.selectedRole,
|
||||
this.onServiceIdsChanged,
|
||||
required this.personalDetailsKey,
|
||||
this.initialSelectedServices,
|
||||
required this.controllers,
|
||||
required this.errorMessages,
|
||||
required this.isDesktop,
|
||||
@ -131,6 +136,10 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
selectedRole = widget.selectedRole;
|
||||
fetchRoles();
|
||||
fetchCountries();
|
||||
selectedServiceIds =
|
||||
List<Map<String, dynamic>>.from(widget.initialSelectedServices ?? []);
|
||||
|
||||
print("selectedServiceIdsAPI - $selectedServiceIds");
|
||||
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
loadAllServices();
|
||||
@ -199,13 +208,22 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
services = [];
|
||||
}
|
||||
|
||||
if (selectedServiceIds.isEmpty && services.isNotEmpty) {
|
||||
selectedServiceIds = services.map<Map<String, dynamic>>((item) {
|
||||
// force cast or copy to a regular map
|
||||
final map = Map<String, dynamic>.from(item);
|
||||
return {
|
||||
"service_id": map['service_id'].toString(),
|
||||
};
|
||||
}).toList();
|
||||
}
|
||||
|
||||
// selectedServiceIds = services.map<Map<String, dynamic>>((item) {
|
||||
// // force cast or copy to a regular map
|
||||
// final map = Map<String, dynamic>.from(item);
|
||||
// return {
|
||||
// "service_id": map['service_id'].toString(),
|
||||
// };
|
||||
// }).toList();
|
||||
});
|
||||
|
||||
// orgId = await getOrgId();
|
||||
@ -351,6 +369,9 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
} else {
|
||||
selectedServiceIds.add({"service_id": serviceId});
|
||||
}
|
||||
|
||||
// Call the parent's callback
|
||||
widget.onServiceIdsChanged!(selectedServiceIds);
|
||||
});
|
||||
},
|
||||
child: Row(children: [
|
||||
@ -755,7 +776,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
setState(() {
|
||||
_selectedDateOfBirth = pickedDate;
|
||||
widget.controllers["dob"]?.text =
|
||||
DateFormat('yyyy-MM-dd').format(pickedDate);
|
||||
DateFormat('dd-MM-yyyy').format(pickedDate);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,6 +50,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
html.File? passportFile;
|
||||
late List<bool> isExpandedList;
|
||||
int? expandedIndex;
|
||||
bool isCountryLoading = true;
|
||||
|
||||
late final userId;
|
||||
String? selectedFileNames;
|
||||
@ -79,6 +80,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
|
||||
Map<String, String> countryMap = {};
|
||||
late List<dynamic>? apiCountryData;
|
||||
late List<dynamic>? apiAirlineCountryData;
|
||||
Map<String, dynamic>? apiData;
|
||||
final Map<String, TextEditingController> controllers = {};
|
||||
|
||||
@ -86,7 +88,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
"Passport Details",
|
||||
// "Local ID Details",
|
||||
"Visa Details",
|
||||
"Frequent Flier Information",
|
||||
"Frequent Flyer Information",
|
||||
"Hotel Loyalty Membership",
|
||||
"Preferences Domestic",
|
||||
"Preferences International",
|
||||
@ -94,6 +96,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
"Forex Details"
|
||||
];
|
||||
|
||||
//To Create Controllers
|
||||
List<String> dataHeader = [
|
||||
"Fname",
|
||||
"Lname",
|
||||
@ -111,6 +114,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
"forex_card_num",
|
||||
"full_name_as_id",
|
||||
"local_id_num",
|
||||
"forex_expiry_date"
|
||||
];
|
||||
|
||||
@override
|
||||
@ -120,11 +124,13 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
// userId = getUserId();
|
||||
|
||||
apiCountryData = null;
|
||||
apiAirlineCountryData = [];
|
||||
apiData = null;
|
||||
for (var field in dataHeader) {
|
||||
controllers[field] = TextEditingController();
|
||||
}
|
||||
fetchCountries();
|
||||
loadCountryList();
|
||||
fetchApiData();
|
||||
// Delay adding the row until after the first frame
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
@ -170,7 +176,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
frequentFlierEntries.add({
|
||||
"local_id": localId,
|
||||
"id": null, // to be set when backend responds
|
||||
"controller_airline": TextEditingController(),
|
||||
// "controller_airline": null,
|
||||
"airline": null,
|
||||
"controller_flier_number": TextEditingController(),
|
||||
"is_active": "1"
|
||||
});
|
||||
@ -196,7 +203,6 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
"visa_type_id": null,
|
||||
"controller_valid_from": TextEditingController(),
|
||||
"controller_valid_upto": TextEditingController(),
|
||||
|
||||
"is_active": "1"
|
||||
});
|
||||
setState(() {});
|
||||
@ -240,12 +246,13 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
"date_of_expiry": controllers["dateOfExpiry"]?.text,
|
||||
"d_meal_preference": controllers["d_meal_pref"]?.text,
|
||||
"d_seat_preference": selectedDomesticSeat,
|
||||
// "d_additonalInfo": controllers["d_additonal_Info"]?.text,
|
||||
"d_additonalInfo": controllers["d_additonal_Info"]?.text,
|
||||
"i_meal_preference": controllers["i_meal_pref"]?.text,
|
||||
"i_seat_preference": selectedIntenationalSeat,
|
||||
// "i_additonalInfo": controllers["i_additonal_Info"]?.text,
|
||||
"i_additonalInfo": controllers["i_additonal_Info"]?.text,
|
||||
"emergency_contact_number": controllers["emergency_contact"]?.text,
|
||||
"forex_pre_paid_card_number": controllers["forex_card_num"]?.text,
|
||||
"forex_expiry_date": controllers["forex_expiry_date"]?.text,
|
||||
// "frequent_flier_information": [],
|
||||
"frequent_flier_information": frequentFlierList,
|
||||
"hotel_membership": hotelMembershipList,
|
||||
@ -270,14 +277,33 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
}).toList();
|
||||
}
|
||||
|
||||
// List<Map<String, dynamic>> get frequentFlierList {
|
||||
// return frequentFlierEntries
|
||||
// // .where((entry) => entry["is_active"] != "0") // ✅ Only active entries
|
||||
// .map((entry) {
|
||||
// return {
|
||||
// "id": entry["id"],
|
||||
// "airline": entry["airline"],
|
||||
// "frequent_flier_number": entry["controller_flier_number"].text,
|
||||
// "created_by": null,
|
||||
// "updated_by": null,
|
||||
// "is_active": entry["is_active"] ?? "1",
|
||||
// };
|
||||
// }).toList();
|
||||
// }
|
||||
|
||||
List<Map<String, dynamic>> get frequentFlierList {
|
||||
return frequentFlierEntries
|
||||
// .where((entry) => entry["is_active"] != "0") // ✅ Only active entries
|
||||
.map((entry) {
|
||||
return frequentFlierEntries.map((entry) {
|
||||
final frequent_flier_number = entry["controller_flier_number"];
|
||||
|
||||
print("frequent_flier_number- $frequent_flier_number");
|
||||
|
||||
return {
|
||||
"id": entry["id"],
|
||||
"airline": entry["controller_airline"].text,
|
||||
"frequent_flier_number": entry["controller_flier_number"].text,
|
||||
"airline": entry["airline"], // ✅ string value
|
||||
"frequent_flier_number": frequent_flier_number is TextEditingController
|
||||
? frequent_flier_number.text
|
||||
: "",
|
||||
"created_by": null,
|
||||
"updated_by": null,
|
||||
"is_active": entry["is_active"] ?? "1",
|
||||
@ -346,10 +372,14 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
|
||||
controllers["d_meal_pref"]?.text =
|
||||
widget.travelDetails?["d_meal_preference"] ?? "";
|
||||
|
||||
controllers["i_meal_pref"]?.text =
|
||||
widget.travelDetails?["i_meal_preference"] ?? "";
|
||||
|
||||
controllers["d_additonal_Info"]?.text =
|
||||
widget.travelDetails?["d_additonalInfo"] ?? "";
|
||||
controllers["i_additonal_Info"]?.text =
|
||||
widget.travelDetails?["i_additonalInfo"] ?? "";
|
||||
|
||||
selectedIntenationalSeat =
|
||||
widget.travelDetails?["i_seat_preference"] ?? "";
|
||||
selectedDomesticSeat = widget.travelDetails?["d_seat_preference"] ?? "";
|
||||
@ -359,6 +389,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
|
||||
controllers["forex_card_num"]?.text =
|
||||
widget.travelDetails?["forex_pre_paid_card_number"] ?? "";
|
||||
controllers["forex_expiry_date"]?.text =
|
||||
widget.travelDetails?["forex_expiry_date"] ?? "";
|
||||
|
||||
String? apiDocPath = widget.travelDetails?["passport_document"];
|
||||
if (apiDocPath != null && apiDocPath.isNotEmpty) {
|
||||
@ -402,38 +434,6 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
|
||||
// 🚨 Frequent Flier Logic (pre-fill for edit)
|
||||
for (var entry in frequentFlierEntries) {
|
||||
entry["controller_airline"].dispose();
|
||||
entry["controller_flier_number"].dispose();
|
||||
}
|
||||
frequentFlierEntries.clear();
|
||||
|
||||
final frequentFlierList =
|
||||
widget.travelDetails?['frequent_flier_information'];
|
||||
if (frequentFlierList != null && frequentFlierList is List) {
|
||||
for (var item in frequentFlierList) {
|
||||
if (item["is_active"]?.toString() == "0") continue;
|
||||
|
||||
final localId = _rowFlierCounter++;
|
||||
frequentFlierEntries.add({
|
||||
"local_id": localId,
|
||||
"id": item["id"],
|
||||
"controller_airline":
|
||||
TextEditingController(text: item["airline"] ?? ""),
|
||||
"controller_flier_number": TextEditingController(
|
||||
text: item["frequent_flier_number"] ?? ""),
|
||||
});
|
||||
}
|
||||
|
||||
if (frequentFlierEntries.isEmpty) {
|
||||
addFrequentFlierEntry();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
|
||||
// 🚨 Visa Logic (pre-fill for edit)
|
||||
for (var entry in visaEntries) {
|
||||
entry["controller_valid_from"]?.dispose();
|
||||
@ -463,6 +463,40 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
addVisaEntry();
|
||||
}
|
||||
}
|
||||
// ----------------------------------------------------
|
||||
|
||||
// 🚨 Frequent Flier Logic (pre-fill for edit)
|
||||
for (var entry in frequentFlierEntries) {
|
||||
// entry["controller_airline"].dispose();
|
||||
entry["controller_flier_number"].dispose();
|
||||
}
|
||||
frequentFlierEntries.clear();
|
||||
|
||||
final frequentFlierList =
|
||||
widget.travelDetails?['frequent_flier_information'];
|
||||
|
||||
if (frequentFlierList != null && frequentFlierList is List) {
|
||||
for (var item in frequentFlierList) {
|
||||
if (item["is_active"]?.toString() == "0") continue;
|
||||
|
||||
final localId = _rowFlierCounter++;
|
||||
final airlineCode = item["airline"];
|
||||
|
||||
frequentFlierEntries.add({
|
||||
"local_id": localId,
|
||||
"id": item["id"],
|
||||
"airline": airlineCode ?? "",
|
||||
"controller_flier_number": TextEditingController(
|
||||
text: item["frequent_flier_number"] ?? ""),
|
||||
});
|
||||
}
|
||||
|
||||
if (frequentFlierEntries.isEmpty) {
|
||||
addFrequentFlierEntry();
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
|
||||
setState(() {});
|
||||
}
|
||||
@ -479,6 +513,35 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> loadCountryList() async {
|
||||
final newTripType = "2";
|
||||
final result = await apiService.fetchFlightsCountryList(newTripType);
|
||||
|
||||
print("resultFlight: $result ");
|
||||
|
||||
setState(() {
|
||||
apiAirlineCountryData = result;
|
||||
});
|
||||
|
||||
// print("ResultCountry : $result");
|
||||
//
|
||||
// // Create a map: Country_Code -> "City, Airport"
|
||||
// Map<String, String> tempCountryMap = {};
|
||||
//
|
||||
// for (var country in result) {
|
||||
// String city = country['City'] ?? '';
|
||||
// String airport = country['Airport'] ?? '';
|
||||
// String displayName = '${country['City']} - ${country['Airport']}';
|
||||
//
|
||||
// tempCountryMap[country['Code']] = displayName;
|
||||
// }
|
||||
//
|
||||
// setState(() {
|
||||
// countryMap = tempCountryMap; // Update the map
|
||||
// isCountryLoading = false;
|
||||
// });
|
||||
}
|
||||
|
||||
Future<void> fetchApiData() async {
|
||||
try {
|
||||
final data = await apiService.fetchMasterDropdown();
|
||||
@ -605,7 +668,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
case "Visa Details":
|
||||
return _buildVisaDetails(widget.isDesktop);
|
||||
|
||||
case "Frequent Flier Information":
|
||||
case "Frequent Flyer Information":
|
||||
return _buildFrequentFlierInfo(widget.isDesktop);
|
||||
|
||||
case "Hotel Loyalty Membership":
|
||||
@ -960,7 +1023,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
setState(() {
|
||||
_selectedDateOfIssue = pickedDate;
|
||||
controllers["dateOfIssue"]?.text =
|
||||
DateFormat('yyyy-MM-dd').format(pickedDate);
|
||||
DateFormat('dd-MM-yyyy').format(pickedDate);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -1038,7 +1101,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
setState(() {
|
||||
_selectedDateOfExpiry = pickedDate;
|
||||
controllers["dateOfExpiry"]?.text =
|
||||
DateFormat('yyyy-MM-dd').format(pickedDate);
|
||||
DateFormat('dd-MM-yyyy').format(pickedDate);
|
||||
|
||||
// controllers["dateOfExpiry"]?.text =
|
||||
// DateFormat('dd-MM-yyyy').format(pickedDate);
|
||||
@ -1497,8 +1560,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
buildDomesticSeatType(),
|
||||
SizedBox(width: 15),
|
||||
buildDomesticMealPref(),
|
||||
// SizedBox(width: 15),
|
||||
// buildDomesticAddtnlPref(),
|
||||
SizedBox(width: 15),
|
||||
buildDomesticAddtnlPref(),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
@ -1507,9 +1570,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
buildDomesticSeatType(),
|
||||
SizedBox(height: 8),
|
||||
buildDomesticMealPref(),
|
||||
// SizedBox(height: 8), // Vertical space
|
||||
//
|
||||
// buildDomesticAddtnlPref(),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
|
||||
buildDomesticAddtnlPref(),
|
||||
],
|
||||
),
|
||||
);
|
||||
@ -1702,8 +1765,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
buildInternationalSeatType(),
|
||||
SizedBox(width: 15),
|
||||
buildInternationalMealPref(),
|
||||
// SizedBox(width: 15),
|
||||
// buildInternationalAddtnlPref(),
|
||||
SizedBox(width: 15),
|
||||
buildInternationalAddtnlPref(),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
@ -1712,9 +1775,9 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
buildInternationalSeatType(),
|
||||
SizedBox(height: 8),
|
||||
buildInternationalMealPref(),
|
||||
// SizedBox(height: 8), // Vertical space
|
||||
//
|
||||
// buildInternationalAddtnlPref(),
|
||||
SizedBox(height: 8), // Vertical space
|
||||
|
||||
buildInternationalAddtnlPref(),
|
||||
],
|
||||
),
|
||||
);
|
||||
@ -1947,11 +2010,34 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
buildForexCardNumber(),
|
||||
_buildForexDetailDataRow1(isDesktop),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildForexDetailDataRow1(bool isDesktop) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: widget.isDesktop
|
||||
? Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildForexCardNumber(),
|
||||
SizedBox(width: 15),
|
||||
buildForexExpiryDate(),
|
||||
],
|
||||
)
|
||||
: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildForexCardNumber(),
|
||||
SizedBox(height: 8),
|
||||
buildForexExpiryDate()
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildForexCardNumber() {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@ -1989,6 +2075,79 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildForexExpiryDate() {
|
||||
DateTime? _selectedExpiryDate;
|
||||
|
||||
Future<void> _selectExpiryDate(BuildContext context) async {
|
||||
DateTime now = DateTime.now();
|
||||
DateTime today = DateTime(now.year, now.month, now.day);
|
||||
|
||||
DateTime? pickedDate = await showDatePicker(
|
||||
context: context,
|
||||
initialDate:
|
||||
_selectedExpiryDate != null && _selectedExpiryDate!.isAfter(today)
|
||||
? _selectedExpiryDate!
|
||||
: today,
|
||||
firstDate: DateTime(1900),
|
||||
lastDate: DateTime(2100),
|
||||
);
|
||||
|
||||
if (pickedDate != null && pickedDate != _selectedExpiryDate) {
|
||||
setState(() {
|
||||
_selectedExpiryDate = pickedDate;
|
||||
// controllers["forex_expiry_date"]?.text =
|
||||
// DateFormat('yyyy-MM-dd').format(pickedDate);
|
||||
controllers["forex_expiry_date"]?.text =
|
||||
DateFormat('dd-MM-yyyy').format(pickedDate);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Forex Expiry Date",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12, fontWeight: FontWeight.w400, color: Colors.black),
|
||||
),
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserTravellerWrapper(
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: GestureDetector(
|
||||
onTap: widget.isViewMode
|
||||
? null
|
||||
: () async {
|
||||
await _selectExpiryDate(context);
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: TextField(
|
||||
controller: controllers["forex_expiry_date"],
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
decoration: InputDecoration(
|
||||
labelText: "Select Date",
|
||||
labelStyle: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
suffixIcon: Icon(Icons.calendar_today,
|
||||
size: 16, color: Color(0xFF8B8FB2)),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
//-------------------------Frequent Flier Information -------------------------------
|
||||
|
||||
Widget _buildFrequentFlierInfo(bool isDesktop) {
|
||||
@ -2056,6 +2215,50 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
}
|
||||
|
||||
Widget buildAirline(Map<String, dynamic> entry) {
|
||||
late Map<String, String> countryMap; // Mapping country_code -> country_name
|
||||
late List<String> countryCodes; // List of country codes
|
||||
|
||||
// countryList = [];
|
||||
bool hasAirlineCountryData =
|
||||
apiAirlineCountryData == null || apiAirlineCountryData!.isEmpty;
|
||||
|
||||
countryList = apiAirlineCountryData!;
|
||||
print("TestcountryList2 - $countryList");
|
||||
|
||||
countryMap = {
|
||||
for (var country in countryList)
|
||||
country['Code'] as String: '${country['City']} - ${country['Airport']}'
|
||||
};
|
||||
|
||||
countryCodes = countryMap.keys.toList();
|
||||
|
||||
// setState(() {
|
||||
// countryMap = tempCountryMap; // Update the map
|
||||
// isCountryLoading = false;
|
||||
// });
|
||||
|
||||
// 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
|
||||
|
||||
//--------------------------
|
||||
|
||||
// String? selectedCountry = entry['airline'];
|
||||
String? selectedCode = entry['airline'];
|
||||
String? selectedText =
|
||||
selectedCode != null ? countryMap[selectedCode] : null;
|
||||
|
||||
print("selectedCode: $selectedCode");
|
||||
print("selectedText: $selectedText");
|
||||
print(
|
||||
"items.contains(selectedText): ${countryMap.values.contains(selectedText)}");
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -2067,30 +2270,105 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
SizedBox(height: 5),
|
||||
CustomTextFieldUserTravellerWrapper(
|
||||
width: widget.isDesktop
|
||||
? MediaQuery.of(context).size.width * 0.15
|
||||
? MediaQuery.of(context).size.width * 0.17
|
||||
: null,
|
||||
isFocused: false,
|
||||
isDesktop: widget.isDesktop,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: TextField(
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
controller: entry["controller_airline"],
|
||||
enabled: !widget.isViewMode,
|
||||
onChanged: (value) {
|
||||
_clearError("first_name");
|
||||
},
|
||||
child: hasAirlineCountryData
|
||||
? CircularProgressIndicator()
|
||||
: DropdownSearch<String>(
|
||||
// selectedItem: countryMap[selectedCountry],
|
||||
// selectedItem: entry['airline'] != null
|
||||
// ? countryMap[entry['airline']]
|
||||
// : null,
|
||||
// selectedItem: countryMap.containsKey(entry['airline'])
|
||||
// ? countryMap[entry['airline']]
|
||||
// : null,
|
||||
// selectedItem: countryMap[selectedCode],
|
||||
// selectedItem: countryMap.containsKey(selectedCode)
|
||||
// ? countryMap[selectedCode]
|
||||
// : null,
|
||||
selectedItem: (entry["airline"] != null &&
|
||||
countryMap.containsKey(entry["airline"]))
|
||||
? countryMap[entry["airline"]]
|
||||
: null,
|
||||
|
||||
popupProps: PopupProps.menu(
|
||||
showSearchBox: true, // Enables search functionality
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Airline",
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
hintText: "Search Country...",
|
||||
contentPadding: EdgeInsets.symmetric(horizontal: 10),
|
||||
),
|
||||
),
|
||||
),
|
||||
items: countryMap.values.toList(),
|
||||
dropdownDecoratorProps: DropDownDecoratorProps(
|
||||
dropdownSearchDecoration: InputDecoration(
|
||||
border: InputBorder.none,
|
||||
contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
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;
|
||||
|
||||
final selectedCode = countryMap.entries
|
||||
.firstWhere((entry) => entry.value == newValue)
|
||||
.key;
|
||||
entry['airline'] = selectedCode;
|
||||
|
||||
// final selectedCode = countryMap.entries
|
||||
// .firstWhere((entry) => entry.value == newValue)
|
||||
// .key;
|
||||
// entry['airline'] = selectedCode;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// CustomTextFieldUserTravellerWrapper(
|
||||
// width: widget.isDesktop
|
||||
// ? MediaQuery.of(context).size.width * 0.15
|
||||
// : null,
|
||||
// isFocused: false,
|
||||
// isDesktop: widget.isDesktop,
|
||||
// child: SizedBox(
|
||||
// height: 40,
|
||||
// child: TextField(
|
||||
// style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
// controller: entry["controller_airline"],
|
||||
// enabled: !widget.isViewMode,
|
||||
// onChanged: (value) {
|
||||
// _clearError("first_name");
|
||||
// },
|
||||
// decoration: InputDecoration(
|
||||
// labelText: "Airline",
|
||||
// labelStyle:
|
||||
// GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
// floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
// border: InputBorder.none,
|
||||
// contentPadding: EdgeInsets.symmetric(vertical: 16),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
);
|
||||
}
|
||||
@ -2102,7 +2380,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Frequent Flier Information",
|
||||
"Frequent Flyer Information",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12, fontWeight: FontWeight.w400, color: Colors.black),
|
||||
),
|
||||
@ -2120,7 +2398,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
_clearError("first_name");
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
labelText: "Frequent Flier Information",
|
||||
labelText: "Frequent Flyer Information",
|
||||
labelStyle:
|
||||
GoogleFonts.poppins(fontSize: 12, color: Colors.grey),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
@ -2145,7 +2423,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
size: 30,
|
||||
),
|
||||
onPressed: () => addFrequentFlierEntry(),
|
||||
tooltip: "Frequent Flier Information",
|
||||
tooltip: "Frequent Flyer Information",
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -2397,6 +2675,8 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
// countryList = [];
|
||||
countryList = apiCountryData ?? [];
|
||||
|
||||
print("TestcountryList1 - $countryList");
|
||||
|
||||
// Map country codes to country names
|
||||
countryMap = {
|
||||
for (var item in countryList)
|
||||
@ -2593,7 +2873,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
// _dateController.text = DateFormat('yyyy-MM-dd').format(pickedDate);
|
||||
|
||||
entry["controller_valid_from"].text =
|
||||
DateFormat('yyyy-MM-dd').format(pickedDate);
|
||||
DateFormat('dd-MM-yyyy').format(pickedDate);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -2673,7 +2953,7 @@ class TravellerDetailsState extends State<TravellerDetails> {
|
||||
// _dateController.text = DateFormat('yyyy-MM-dd').format(pickedDate);
|
||||
|
||||
entry["controller_valid_upto"].text =
|
||||
DateFormat('yyyy-MM-dd').format(pickedDate);
|
||||
DateFormat('dd-MM-yyyy').format(pickedDate);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ import 'package:shared_preferences/shared_preferences.dart'; // don't forget
|
||||
import '../services/apiService.dart';
|
||||
import '../utils/auth_utils.dart';
|
||||
|
||||
enum TabSelection { allTrips, myTrips, myApprovals }
|
||||
enum TabSelection { allTrips, myTrips, myApprovals, allMenu }
|
||||
|
||||
class CustomAppBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
final bool isDesktop;
|
||||
@ -34,7 +34,7 @@ class CustomAppBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
class _CustomAppBarState extends State<CustomAppBar> {
|
||||
final ApiService apiService = ApiService();
|
||||
|
||||
TabSelection selectedTab = TabSelection.allTrips;
|
||||
late TabSelection selectedTab;
|
||||
|
||||
String? token;
|
||||
Map<String, dynamic>? userData;
|
||||
@ -43,14 +43,10 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
Map<String, dynamic> profileUserDetails = {};
|
||||
|
||||
Map<String, dynamic>? selectedOrg;
|
||||
Color? layoutColor;
|
||||
// Color? layoutColor;
|
||||
Color? layoutColor = Colors.white10;
|
||||
Color? bodyColor;
|
||||
|
||||
Color _myTravelRequestColor = Color(0xFF475569); // Default color
|
||||
EdgeInsets _myTravelRequestPadding =
|
||||
EdgeInsets.symmetric(horizontal: 8, vertical: 4);
|
||||
Color _myApprovalsColor = Color(0xFF475569); // Default color
|
||||
|
||||
void initState() {
|
||||
super.initState();
|
||||
// initializeData();
|
||||
@ -58,6 +54,12 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
initializeData();
|
||||
getOrganizationData();
|
||||
});
|
||||
if (userData?["role"] == "Org Admin" ||
|
||||
userData?["role"] == "Travel Admin") {
|
||||
selectedTab = TabSelection.allTrips;
|
||||
} else {
|
||||
selectedTab = TabSelection.myTrips;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getProfileUser() async {
|
||||
@ -94,17 +96,6 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
getProfileUser();
|
||||
}
|
||||
|
||||
String getTabLabel(TabSelection tab) {
|
||||
switch (tab) {
|
||||
case TabSelection.allTrips:
|
||||
return "All Trips";
|
||||
case TabSelection.myTrips:
|
||||
return "My Trips";
|
||||
case TabSelection.myApprovals:
|
||||
return "My Approvals";
|
||||
}
|
||||
}
|
||||
|
||||
Future<String?> getToken() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
return prefs.getString("auth_token");
|
||||
@ -174,6 +165,43 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
}
|
||||
}
|
||||
|
||||
void handleTabChange(TabSelection tab, String route) {
|
||||
final currentUri =
|
||||
GoRouterState.of(context).uri.toString(); // ✅ safer than `.location`
|
||||
print("currentUri - $currentUri");
|
||||
|
||||
if (currentUri != route) {
|
||||
setState(() {
|
||||
selectedTab = tab;
|
||||
});
|
||||
context.go(route);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
|
||||
final location = GoRouterState.of(context).uri.toString();
|
||||
|
||||
print("location - $location");
|
||||
|
||||
setState(() {
|
||||
if (location.contains('/listAllPlan') ||
|
||||
location.contains('/allTrips/trips')) {
|
||||
selectedTab = TabSelection.allTrips;
|
||||
} else if (location.contains('/listPlan') ||
|
||||
location.contains('/createPlan') ||
|
||||
location.contains('/listTravelAgentPlan')) {
|
||||
selectedTab = TabSelection.myTrips;
|
||||
} else if (location.contains('/ApprovalList')) {
|
||||
selectedTab = TabSelection.myApprovals;
|
||||
} else {
|
||||
selectedTab = TabSelection.allMenu;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AppBar(
|
||||
@ -216,7 +244,7 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
)
|
||||
: const CircleAvatar(
|
||||
radius: 20,
|
||||
backgroundColor: Colors.white,
|
||||
// backgroundColor: Colors.white,
|
||||
child: Icon(
|
||||
Icons.add_a_photo,
|
||||
size: 10,
|
||||
@ -225,186 +253,8 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: MediaQuery.of(context).size.width * 0.2,
|
||||
width: MediaQuery.of(context).size.width * 0.18,
|
||||
),
|
||||
// Container(
|
||||
// width: MediaQuery.of(context).size.width * 0.35,
|
||||
// // color: Colors.blueGrey,
|
||||
// child: Row(
|
||||
// // crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: [
|
||||
// if (userData?["role"] == "Org Admin" ||
|
||||
// userData?["role"] == "Travel Admin")
|
||||
// MouseRegion(
|
||||
// cursor: SystemMouseCursors.click,
|
||||
// onEnter: (_) {
|
||||
// setState(() {
|
||||
// // _myTravelRequestPadding =
|
||||
// // EdgeInsets.symmetric(horizontal: 12, vertical: 78);
|
||||
// // _myTravelRequestColor =
|
||||
// // Color(0xFF114D8B); // Change color on hover
|
||||
// });
|
||||
// },
|
||||
// onExit: (_) {
|
||||
// setState(() {
|
||||
// // _myTravelRequestPadding = EdgeInsets.symmetric(
|
||||
// // horizontal: 8, vertical: 4); // Normal padding
|
||||
// // _myTravelRequestColor =
|
||||
// // Color(0xFF475569); // Revert color when hover ends
|
||||
// });
|
||||
// },
|
||||
// child: InkWell(
|
||||
// onTap: () {
|
||||
// context.go('/listAllPlan');
|
||||
// },
|
||||
// child: Text(
|
||||
// "All Trips",
|
||||
// style: TextStyle(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// // color: Color(0xFF475569),
|
||||
// color: _myTravelRequestColor,
|
||||
// fontFamily: "Inter",
|
||||
// ),
|
||||
// )),
|
||||
// ),
|
||||
// const SizedBox(width: 20),
|
||||
// if (userDetails["role"] == "Travel Agent")
|
||||
// MouseRegion(
|
||||
// cursor: SystemMouseCursors.click,
|
||||
// onEnter: (_) {
|
||||
// setState(() {
|
||||
// // _myTravelRequestPadding =
|
||||
// // EdgeInsets.symmetric(horizontal: 12, vertical: 78);
|
||||
// // _myTravelRequestColor =
|
||||
// // Color(0xFF114D8B); // Change color on hover
|
||||
// });
|
||||
// },
|
||||
// onExit: (_) {
|
||||
// setState(() {
|
||||
// // _myTravelRequestPadding = EdgeInsets.symmetric(
|
||||
// // horizontal: 8, vertical: 4); // Normal padding
|
||||
// // _myTravelRequestColor =
|
||||
// // Color(0xFF475569); // Revert color when hover ends
|
||||
// });
|
||||
// },
|
||||
// child: InkWell(
|
||||
// onTap: () {
|
||||
// context.go('/listTravelAgentPlan');
|
||||
// },
|
||||
// child: Text(
|
||||
// "My Trips",
|
||||
// style: TextStyle(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// // color: Color(0xFF475569),
|
||||
// color: _myTravelRequestColor,
|
||||
// fontFamily: "Inter",
|
||||
// ),
|
||||
// )),
|
||||
// ),
|
||||
// if (userDetails["role"] != "Travel Agent")
|
||||
// const SizedBox(width: 20),
|
||||
// if (userDetails["role"] != "Travel Agent")
|
||||
// MouseRegion(
|
||||
// cursor: SystemMouseCursors.click,
|
||||
// onEnter: (_) {
|
||||
// setState(() {
|
||||
// // _myTravelRequestPadding =
|
||||
// // EdgeInsets.symmetric(horizontal: 12, vertical: 78);
|
||||
// // _myTravelRequestColor =
|
||||
// // Color(0xFF114D8B); // Change color on hover
|
||||
// });
|
||||
// },
|
||||
// onExit: (_) {
|
||||
// setState(() {
|
||||
// // _myTravelRequestPadding = EdgeInsets.symmetric(
|
||||
// // horizontal: 8, vertical: 4); // Normal padding
|
||||
// // _myTravelRequestColor =
|
||||
// // Color(0xFF475569); // Revert color when hover ends
|
||||
// });
|
||||
// },
|
||||
// child: InkWell(
|
||||
// onTap: () {
|
||||
// context.go('/listPlan');
|
||||
// },
|
||||
// child: Text(
|
||||
// "My Trips",
|
||||
// style: TextStyle(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// // color: Color(0xFF475569),
|
||||
// color: _myTravelRequestColor,
|
||||
// fontFamily: "Inter",
|
||||
// ),
|
||||
// )),
|
||||
// ),
|
||||
// const SizedBox(width: 20),
|
||||
// if (userData?["role"] != "Travel Agent")
|
||||
// MouseRegion(
|
||||
// cursor: SystemMouseCursors.click,
|
||||
// onEnter: (_) {
|
||||
// setState(() {
|
||||
// _myApprovalsColor =
|
||||
// Color(0xFF114D8B); // Change color on hover
|
||||
// });
|
||||
// },
|
||||
// onExit: (_) {
|
||||
// setState(() {
|
||||
// _myApprovalsColor = Color(
|
||||
// 0xFF475569); // Revert color when hover ends
|
||||
// });
|
||||
// },
|
||||
// child: InkWell(
|
||||
// onTap: () {
|
||||
// context.go('/ApprovalList');
|
||||
// },
|
||||
// child: Text(
|
||||
// "My Approvals",
|
||||
// style: TextStyle(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: _myApprovalsColor,
|
||||
// // color: Color(0xFF475569),
|
||||
// fontFamily: "Inter",
|
||||
// ),
|
||||
// )),
|
||||
// ),
|
||||
// if (userData?["role"] == "Travel Agent")
|
||||
// MouseRegion(
|
||||
// cursor: SystemMouseCursors.click,
|
||||
// onEnter: (_) {
|
||||
// setState(() {
|
||||
// _myApprovalsColor =
|
||||
// Color(0xFF114D8B); // Change color on hover
|
||||
// });
|
||||
// },
|
||||
// onExit: (_) {
|
||||
// setState(() {
|
||||
// _myApprovalsColor = Color(
|
||||
// 0xFF475569); // Revert color when hover ends
|
||||
// });
|
||||
// },
|
||||
// child: InkWell(
|
||||
// onTap: () {
|
||||
// context.go('/listTravelAgentPlan');
|
||||
// },
|
||||
// child: Text(
|
||||
// "My Approvals",
|
||||
// style: TextStyle(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: _myApprovalsColor,
|
||||
// // color: Color(0xFF475569),
|
||||
// fontFamily: "Inter",
|
||||
// ),
|
||||
// )),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width * 0.35,
|
||||
child: Row(
|
||||
@ -412,9 +262,14 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
children: [
|
||||
if (userData?["role"] == "Org Admin" ||
|
||||
userData?["role"] == "Travel Admin")
|
||||
buildNavItem("All Trips", _myTravelRequestColor,
|
||||
() => context.go('/listAllPlan'),
|
||||
isSelected: selectedTab == "All Trips"),
|
||||
buildNavItem(
|
||||
"All Trips",
|
||||
() => handleTabChange(
|
||||
TabSelection.allTrips, '/listAllPlan'),
|
||||
layoutColor!,
|
||||
isSelected: selectedTab == TabSelection.allTrips,
|
||||
icon: Icons.insights_outlined,
|
||||
),
|
||||
|
||||
if (userDetails["role"] != "Travel Agent")
|
||||
const SizedBox(width: 20),
|
||||
@ -422,17 +277,23 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
if (userData?["role"] == "Travel Agent")
|
||||
buildNavItem(
|
||||
"My Trips",
|
||||
_myTravelRequestColor,
|
||||
() => context.go('/listTravelAgentPlan'),
|
||||
isSelected: selectedTab == "My Trips",
|
||||
() => handleTabChange(
|
||||
TabSelection.myTrips, '/listTravelAgentPlan'),
|
||||
layoutColor!,
|
||||
// () => context.go('/listTravelAgentPlan'),
|
||||
isSelected: selectedTab == TabSelection.myTrips,
|
||||
icon: Icons.request_page_outlined,
|
||||
),
|
||||
|
||||
if (userData?["role"] != "Travel Agent") // for others
|
||||
buildNavItem(
|
||||
"My Trips",
|
||||
_myTravelRequestColor,
|
||||
() => context.go('/listPlan'),
|
||||
isSelected: selectedTab == "My Trips",
|
||||
() => handleTabChange(
|
||||
TabSelection.myTrips, '/listPlan'),
|
||||
layoutColor!,
|
||||
// () => context.go('/listPlan'),
|
||||
isSelected: selectedTab == TabSelection.myTrips,
|
||||
icon: Icons.request_page_outlined,
|
||||
),
|
||||
// if (userDetails["role"] == "Travel Agent")
|
||||
// buildNavItem("My Trips", _myTravelRequestColor,
|
||||
@ -448,11 +309,23 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
|
||||
const SizedBox(width: 20),
|
||||
if (userData?["role"] != "Travel Agent")
|
||||
buildNavItem("My Approvals", _myApprovalsColor, () {
|
||||
isSelected:
|
||||
selectedTab == "My Approvals";
|
||||
context.go('/ApprovalList');
|
||||
})
|
||||
buildNavItem(
|
||||
"My Approvals",
|
||||
|
||||
() => handleTabChange(
|
||||
TabSelection.myApprovals, '/ApprovalList'),
|
||||
layoutColor!,
|
||||
// () => context.go('/ApprovalList'),
|
||||
isSelected: selectedTab == TabSelection.myApprovals,
|
||||
icon: Icons.assessment_outlined,
|
||||
),
|
||||
|
||||
// buildNavItem("My Approvals", _myApprovalsColor, () {
|
||||
// isSelected:
|
||||
// selectedTab == "My Approvals",
|
||||
// context.go('/ApprovalList'),
|
||||
// icon:Icons.insights_outlined;
|
||||
// })
|
||||
|
||||
// if (userData?["role"] == "Travel Agent") {
|
||||
// isSelected:
|
||||
@ -466,7 +339,6 @@ class _CustomAppBarState extends State<CustomAppBar> {
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Spacer(),
|
||||
],
|
||||
),
|
||||
@ -664,11 +536,64 @@ PopupMenuItem<String> buildMenuItem(Map<String, dynamic> item) {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildNavItem(String label, Color color, VoidCallback onTap,
|
||||
{bool isSelected = false}) {
|
||||
Widget buildNavItem(String label, VoidCallback onTap, Color? layoutColor,
|
||||
{bool isSelected = true, IconData? icon}) {
|
||||
final effectiveColor =
|
||||
isSelected ? (layoutColor ?? Colors.blue) : Colors.black;
|
||||
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: InkWell(
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
if (icon != null) Icon(icon, size: 16, color: effectiveColor),
|
||||
if (icon != null) const SizedBox(width: 4),
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: effectiveColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (isSelected)
|
||||
AnimatedPositioned(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
bottom: -20,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
opacity: 1.0,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
curve: Curves.easeInOut,
|
||||
height: 2,
|
||||
width: isSelected
|
||||
? 50
|
||||
: 0, // Animate width (make sure isSelected changes)
|
||||
color: effectiveColor,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildNavItem1(String label, VoidCallback onTap,
|
||||
{bool isSelected = true, IconData? icon}) {
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
onTap: onTap,
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(bottom: 2),
|
||||
@ -676,22 +601,43 @@ Widget buildNavItem(String label, Color color, VoidCallback onTap,
|
||||
? BoxDecoration(
|
||||
border: Border(
|
||||
bottom: BorderSide(
|
||||
color: color, // underline color
|
||||
width: 2, // underline thickness
|
||||
),
|
||||
color: Colors.red),
|
||||
),
|
||||
)
|
||||
: null, // no underline when not selected
|
||||
child: Text(
|
||||
child: Row(
|
||||
children: [
|
||||
if (icon != null)
|
||||
Icon(
|
||||
icon,
|
||||
size: 16,
|
||||
color: isSelected ? Colors.red : Colors.black,
|
||||
// color: Colors.red,
|
||||
),
|
||||
if (icon != null) SizedBox(width: 4),
|
||||
Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12, fontWeight: FontWeight.w500, color: Colors.black),
|
||||
// style: TextStyle(
|
||||
// fontSize: 12,
|
||||
// fontWeight: FontWeight.w600,
|
||||
// color: color,
|
||||
// fontFamily: "Inter",
|
||||
// ),
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: isSelected ? Colors.red : Colors.black,
|
||||
// color: Colors.red,
|
||||
),
|
||||
),
|
||||
|
||||
// Red underline positioned below (e.g. under green line)
|
||||
if (isSelected)
|
||||
Positioned(
|
||||
bottom: -50, // adjust this to push it below green line
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
height: 2,
|
||||
color: Colors.red,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -173,11 +173,11 @@ class _CustomDrawerState extends State<CustomDrawer> {
|
||||
|
||||
if (userData?["role"] == "Org Admin" ||
|
||||
userData?["role"] == "Travel Admin")
|
||||
_buildDrawerItem(context, Icons.request_page_outlined,
|
||||
'All Trips', '/listAllPlan'),
|
||||
_buildDrawerItem(context, Icons.insights_outlined, 'All Trips',
|
||||
'/listAllPlan'),
|
||||
|
||||
if (userDetails["role"] == "Travel Agent")
|
||||
_buildDrawerItem(context, Icons.request_page_outlined,
|
||||
_buildDrawerItem(context, Icons.assessment_outlined,
|
||||
'My Approvals', '/listTravelAgentPlan'),
|
||||
|
||||
if (userDetails["role"] != "Travel Agent")
|
||||
|
||||
@ -47,6 +47,10 @@ final GoRouter router = GoRouter(
|
||||
path: '/createPlan',
|
||||
builder: (context, state) => CreatePlan(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/allTrips/trips',
|
||||
builder: (context, state) => CreatePlan(),
|
||||
),
|
||||
GoRoute(
|
||||
path: '/listUser',
|
||||
builder: (context, state) => UserListScreen(),
|
||||
|
||||
@ -412,12 +412,12 @@ class ApiService {
|
||||
}
|
||||
|
||||
static Future<void> viewPlan(BuildContext context, String planId,
|
||||
{bool isViewMode = false}) async {
|
||||
{bool isViewMode = false, bool isMyTrips = false}) async {
|
||||
try {
|
||||
Map<String, dynamic> planData = await getViewPlan(planId);
|
||||
print("ViewAAA - $planData");
|
||||
|
||||
context.go('/createPlan',
|
||||
context.go(isMyTrips ? '/createPlan' : '/allTrips/trips',
|
||||
extra: {'planData': planData, 'isViewMode': isViewMode});
|
||||
} catch (e) {
|
||||
print("Error fetching plan: $e");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user