UI_ADDITIONAL_COLOR, UI_ALLTRIPS_CARD

This commit is contained in:
venbaittech 2025-07-18 09:47:33 +05:30
parent bc8968f9c5
commit 66d62ca8f8
4 changed files with 1126 additions and 661 deletions

View File

@ -503,7 +503,10 @@ class _ListAllPlansState extends State<ListAllPlans> {
return Container( return Container(
margin: isDesktop ? EdgeInsets.all(10.0) : null, margin: isDesktop ? EdgeInsets.all(10.0) : null,
padding: const EdgeInsets.only(top: 15, bottom: 15, left: 20, right: 20), padding:
isDesktop
? const EdgeInsets.only(top: 15, bottom: 15, left: 20, right: 20)
: EdgeInsets.all(3.0),
height: height:
isDesktop isDesktop
? MediaQuery.of(context).size.height * 0.98 ? MediaQuery.of(context).size.height * 0.98
@ -1177,302 +1180,622 @@ class _ListAllPlansState extends State<ListAllPlans> {
// shadowColor: Colors.black54, // Softer shadow // shadowColor: Colors.black54, // Softer shadow
// clipBehavior: Clip.antiAlias, // clipBehavior: Clip.antiAlias,
child: Padding( child: Padding(
padding: const EdgeInsets.all(12.0), padding: const EdgeInsets.all(10.0),
// padding: EdgeInsets.symmetric(vertical: 12),
child: Column( child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
// Status and Employee Code Container(
Row( // color: Colors.red.shade50,
mainAxisAlignment: child: Column(
MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.center,
children: [ crossAxisAlignment:
Column( CrossAxisAlignment.center,
crossAxisAlignment: children: [
CrossAxisAlignment.start, Image.asset(
plan.tripType == 'Domestic'
? 'assets/images/IconsImg/Domestic_new.png'
: 'assets/images/IconsImg/International_new.png',
// width: 65,
height:
plan.tripType == 'Domestic'
? 37
: 40,
),
],
),
),
SizedBox(width: 10),
Expanded(
child: Container(
// color: Colors.yellow.shade50,
child: Column(
children: [ children: [
GestureDetector( Row(
onTap: mainAxisAlignment:
() => _showDetails(plan.planId), MainAxisAlignment.spaceBetween,
child: Container( children: [
padding: EdgeInsets.symmetric( Column(
horizontal: 8, crossAxisAlignment:
vertical: 4, CrossAxisAlignment.start,
), children: [
decoration: BoxDecoration( Text(
color: getStatusColor( '${plan.tripTitle}',
plan.statusValue, style: TextStyle(
), fontSize: 12,
borderRadius: fontFamily: "Inter",
BorderRadius.circular(8), fontWeight: FontWeight.bold,
), ),
child: Text(
plan.statusValue,
style: TextStyle(
color: getStatusTextColor(
plan.statusValue,
), ),
fontSize: 10, ],
fontWeight: FontWeight.w600,
),
), ),
), Column(
children: [
// PlanPopupMenu(
// plan: plan,
// deletePlan: deletePlan,
// apiService: apiService,
// layoutColor: layoutColor,
// ),
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: 1,
vertical: 1,
// 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,
),
tooltip:
'View The Trip Details',
onPressed: () {
Navigator.pop(
context,
); // Close popup manually
ApiService.viewPlan(
context,
plan.planId,
isViewMode:
true,
);
},
),
if (plan.statusValue ==
"Pending Approval" ||
plan.statusValue ==
"Partially Approved")
IconButton(
icon: Image.asset(
'assets/images/IconsImg/edit.png',
width: 20,
height:
15,
),
tooltip:
'Edit The Trip Details',
onPressed: () {
Navigator.pop(
context,
);
ApiService.viewPlan(
context,
plan.planId,
isViewMode:
false,
);
},
),
IconButton(
icon: Icon(
Icons
.cancel_rounded,
size: 18,
),
tooltip:
'Cancellation The Trip Details',
onPressed: () {
Navigator.pop(
context,
);
deletePlan(
plan.planId,
);
},
),
IconButton(
icon: Icon(
Icons
.download,
color: Color(
0xFF114D8B,
),
size: 18,
),
tooltip:
'Download The PDF',
onPressed: () {
Navigator.pop(
context,
);
apiService
.getPdfDownload(
plan.planId,
);
},
),
IconButton(
icon: const Icon(
Icons
.comment,
color: Color(
0xFF475569,
),
size: 11,
),
tooltip:
'Trip Comments',
onPressed: () {
showDialog(
context:
context,
builder:
(
context,
) => CommentModalList(
// planId: plan.planId,
planId:
plan.planId.toString(),
layoutColorForUser:
layoutColor!,
role:
"Admin",
),
);
},
),
],
),
),
),
],
),
],
),
],
), ),
],
), Row(
Column( mainAxisAlignment:
children: [ MainAxisAlignment.spaceBetween,
// PlanPopupMenu(
// plan: plan, children: [
// deletePlan: deletePlan, Column(
// apiService: apiService, crossAxisAlignment:
// layoutColor: layoutColor, CrossAxisAlignment.start,
// ), children: [
PopupMenuButton<int>( Text(
color: Colors.white, plan.userName.isNotEmpty
padding: EdgeInsets.zero, ? '${plan.userName}'
offset: Offset(0, 30), : '${plan.travellerName}',
icon: Icon( style: TextStyle(
Icons.more_vert, fontSize: 12,
color: Color(0xFF475569), fontFamily: "Inter",
size: 14, color: Colors.black87,
), ),
itemBuilder: ),
(context) => [ Text(
CustomPopupMenuEntry( plan.employeeCode ??
'No Data',
style: TextStyle(
fontSize: 9,
fontFamily: "Inter",
color: Colors.black87,
),
),
Text(
'${_formatDate(plan.createdOn)}',
style: TextStyle(
fontSize: 10,
color: Colors.black87,
fontFamily: "Inter",
),
),
// Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
//
// ],
// ),
// Spacer(),
// Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
//
// ],
// ),
// ],
// ),
],
),
Column(
children: [
GestureDetector(
onTap:
() => _showDetails(
plan.planId,
),
child: Container( child: Container(
padding: padding:
EdgeInsets.symmetric( EdgeInsets.symmetric(
horizontal: 8, horizontal: 8,
vertical: 8, vertical: 4,
), ),
child: Row( decoration: BoxDecoration(
mainAxisSize: color: getStatusColor(
MainAxisSize.min, plan.statusValue,
mainAxisAlignment: ),
MainAxisAlignment borderRadius:
.center, BorderRadius.circular(
children: [ 8,
IconButton( ),
icon: Icon( ),
Icons child: Text(
.remove_red_eye, plan.statusValue,
color: Color( style: TextStyle(
0xFF475569, color:
getStatusTextColor(
plan.statusValue,
), ),
size: 18, fontSize: 10,
), fontWeight:
tooltip: FontWeight.w600,
'View The Trip Details', ),
onPressed: () {
Navigator.pop(
context,
); // Close popup manually
ApiService.viewPlan(
context,
plan.planId,
isViewMode: true,
);
},
),
if (plan.statusValue ==
"Pending Approval" ||
plan.statusValue ==
"Partially Approved")
IconButton(
icon: Image.asset(
'assets/images/IconsImg/edit.png',
width: 20,
height: 15,
),
tooltip:
'Edit The Trip Details',
onPressed: () {
Navigator.pop(
context,
);
ApiService.viewPlan(
context,
plan.planId,
isViewMode:
false,
);
},
),
IconButton(
icon: Icon(
Icons
.cancel_rounded,
size: 18,
),
tooltip:
'Cancellation The Trip Details',
onPressed: () {
Navigator.pop(
context,
);
deletePlan(
plan.planId,
);
},
),
IconButton(
icon: Icon(
Icons.download,
color: Color(
0xFF114D8B,
),
size: 18,
),
tooltip:
'Download The PDF',
onPressed: () {
Navigator.pop(
context,
);
apiService
.getPdfDownload(
plan.planId,
);
},
),
IconButton(
icon: const Icon(
Icons.comment,
color: Color(
0xFF475569,
),
size: 11,
),
tooltip:
'Trip Comments',
onPressed: () {
showDialog(
context: context,
builder:
(
context,
) => CommentModalList(
// planId: plan.planId,
planId:
plan.planId
.toString(),
layoutColorForUser:
layoutColor!,
role:
"Admin",
),
);
},
),
],
), ),
), ),
), ),
], ],
),
],
), ),
], ],
), ),
], ),
), ),
SizedBox(height: 2),
// Trip Id and Trip Name
Row(
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
' ${plan.tripTitle}',
style: TextStyle(
fontSize: 12,
fontFamily: "Inter",
fontWeight: FontWeight.bold,
),
),
],
),
],
),
SizedBox(height: 2),
// Type and Created On
Row(
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
' ${plan.tripType}',
style: TextStyle(
fontSize: 9,
color: Colors.black87,
fontFamily: "Inter",
),
),
],
),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
'${_formatDate(plan.createdOn)}',
style: TextStyle(
fontSize: 9,
color: Colors.black87,
fontFamily: "Inter",
),
),
],
),
],
),
SizedBox(height: 3),
// Name
Row(
children: [
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
plan.userName.isNotEmpty
? '${plan.userName}'
: '${plan.travellerName}',
style: TextStyle(
fontSize: 9,
fontFamily: "Inter",
color: Colors.black87,
),
),
],
),
Spacer(),
Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
plan.employeeCode ?? 'No Data',
style: TextStyle(
fontSize: 9,
fontFamily: "Inter",
color: Colors.black87,
),
),
],
),
],
),
// Actions
], ],
), ),
// padding: EdgeInsets.symmetric(vertical: 12),
// child: Container(
// // color: Colors.yellow,
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisAlignment: MainAxisAlignment.start,
// children: [
// // Status and Employee Code
// Row(
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// GestureDetector(
// onTap:
// () => _showDetails(plan.planId),
// child: Container(
// padding: EdgeInsets.symmetric(
// horizontal: 8,
// vertical: 4,
// ),
// decoration: BoxDecoration(
// color: getStatusColor(
// plan.statusValue,
// ),
// borderRadius:
// BorderRadius.circular(8),
// ),
// child: Text(
// plan.statusValue,
// style: TextStyle(
// color: getStatusTextColor(
// plan.statusValue,
// ),
// fontSize: 10,
// fontWeight: FontWeight.w600,
// ),
// ),
// ),
// ),
// ],
// ),
// Column(
// children: [
// // PlanPopupMenu(
// // plan: plan,
// // deletePlan: deletePlan,
// // apiService: apiService,
// // layoutColor: layoutColor,
// // ),
// 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: 1,
// vertical: 1,
// // 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,
// ),
// tooltip:
// 'View The Trip Details',
// onPressed: () {
// Navigator.pop(
// context,
// ); // Close popup manually
// ApiService.viewPlan(
// context,
// plan.planId,
// isViewMode:
// true,
// );
// },
// ),
// if (plan.statusValue ==
// "Pending Approval" ||
// plan.statusValue ==
// "Partially Approved")
// IconButton(
// icon: Image.asset(
// 'assets/images/IconsImg/edit.png',
// width: 20,
// height: 15,
// ),
// tooltip:
// 'Edit The Trip Details',
// onPressed: () {
// Navigator.pop(
// context,
// );
// ApiService.viewPlan(
// context,
// plan.planId,
// isViewMode:
// false,
// );
// },
// ),
// IconButton(
// icon: Icon(
// Icons
// .cancel_rounded,
// size: 18,
// ),
// tooltip:
// 'Cancellation The Trip Details',
// onPressed: () {
// Navigator.pop(
// context,
// );
// deletePlan(
// plan.planId,
// );
// },
// ),
// IconButton(
// icon: Icon(
// Icons.download,
// color: Color(
// 0xFF114D8B,
// ),
// size: 18,
// ),
// tooltip:
// 'Download The PDF',
// onPressed: () {
// Navigator.pop(
// context,
// );
// apiService
// .getPdfDownload(
// plan.planId,
// );
// },
// ),
// IconButton(
// icon: const Icon(
// Icons.comment,
// color: Color(
// 0xFF475569,
// ),
// size: 11,
// ),
// tooltip:
// 'Trip Comments',
// onPressed: () {
// showDialog(
// context:
// context,
// builder:
// (
// context,
// ) => CommentModalList(
// // planId: plan.planId,
// planId:
// plan.planId
// .toString(),
// layoutColorForUser:
// layoutColor!,
// role:
// "Admin",
// ),
// );
// },
// ),
// ],
// ),
// ),
// ),
// ],
// ),
// ],
// ),
// ],
// ),
//
// SizedBox(height: 2),
// // Trip Id and Trip Name
// Row(
// children: [
// Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// Text(
// ' ${plan.tripTitle}',
// style: TextStyle(
// fontSize: 12,
// fontFamily: "Inter",
// fontWeight: FontWeight.bold,
// ),
// ),
// ],
// ),
// ],
// ),
// SizedBox(height: 2),
// // Type and Created On
// Row(
// mainAxisAlignment:
// MainAxisAlignment.spaceBetween,
// children: [
// Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// Text(
// ' ${plan.tripType}',
// style: TextStyle(
// fontSize: 9,
// color: Colors.black87,
// fontFamily: "Inter",
// ),
// ),
// ],
// ),
// Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// Text(
// '${_formatDate(plan.createdOn)}',
// style: TextStyle(
// fontSize: 9,
// color: Colors.black87,
// fontFamily: "Inter",
// ),
// ),
// ],
// ),
// ],
// ),
// SizedBox(height: 3),
// // Name
// Row(
// children: [
// Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// Text(
// plan.userName.isNotEmpty
// ? '${plan.userName}'
// : '${plan.travellerName}',
// style: TextStyle(
// fontSize: 9,
// fontFamily: "Inter",
// color: Colors.black87,
// ),
// ),
// ],
// ),
// Spacer(),
// Column(
// crossAxisAlignment:
// CrossAxisAlignment.start,
// children: [
// Text(
// plan.employeeCode ?? 'No Data',
// style: TextStyle(
// fontSize: 9,
// fontFamily: "Inter",
// color: Colors.black87,
// ),
// ),
// ],
// ),
// ],
// ),
// // Actions
// ],
// ),
// ),
), ),
); );
}, },

View File

@ -39,6 +39,8 @@ class _OrgSetUpState extends State<OrgSetUp> {
List<dynamic>? apiAllServices; List<dynamic>? apiAllServices;
Map<String, dynamic>? selectedOrg; Map<String, dynamic>? selectedOrg;
Color? layoutColor; Color? layoutColor;
Color? layoutSecondaryColor;
Color? layoutTertiaryColor;
Color? bodyColor; Color? bodyColor;
bool isSelected = false; bool isSelected = false;
@ -112,6 +114,10 @@ class _OrgSetUpState extends State<OrgSetUp> {
"layout_color": "layout_color":
"0x${layoutColor?.toARGB32().toRadixString(16).padLeft(8, '0').toUpperCase()}", "0x${layoutColor?.toARGB32().toRadixString(16).padLeft(8, '0').toUpperCase()}",
"secondary_color":
"0x${layoutSecondaryColor?.toARGB32().toRadixString(16).padLeft(8, '0').toUpperCase()}",
"tertiary_color":
"0x${layoutTertiaryColor?.toARGB32().toRadixString(16).padLeft(8, '0').toUpperCase()}",
"color": "color":
"0x${bodyColor?.toARGB32().toRadixString(16).padLeft(8, '0').toUpperCase()}", "0x${bodyColor?.toARGB32().toRadixString(16).padLeft(8, '0').toUpperCase()}",
@ -181,6 +187,7 @@ class _OrgSetUpState extends State<OrgSetUp> {
// } // }
String? rawLogoPath = selectedOrg?['logo']; String? rawLogoPath = selectedOrg?['logo'];
if (rawLogoPath != null && rawLogoPath.contains('/assets')) { if (rawLogoPath != null && rawLogoPath.contains('/assets')) {
const baseUrl = apiUrl; const baseUrl = apiUrl;
// const baseUrl = "https://apitest.tripapprovaltool.com"; // const baseUrl = "https://apitest.tripapprovaltool.com";
@ -202,6 +209,30 @@ class _OrgSetUpState extends State<OrgSetUp> {
), ),
) )
: Colors.white; : Colors.white;
layoutSecondaryColor =
selectedOrg?['secondary_color'] != null
? Color(
int.parse(
selectedOrg!['secondary_color'].toString().replaceFirst(
'0x',
'',
),
radix: 16,
),
)
: Colors.white;
layoutTertiaryColor =
selectedOrg?['tertiary_color'] != null
? Color(
int.parse(
selectedOrg!['tertiary_color'].toString().replaceFirst(
'0x',
'',
),
radix: 16,
),
)
: Colors.white;
bodyColor = bodyColor =
selectedOrg?['color'] != null selectedOrg?['color'] != null
@ -760,29 +791,39 @@ class _OrgSetUpState extends State<OrgSetUp> {
// color: Color(0xFFF5F5F5), // color: Color(0xFFF5F5F5),
color: Colors.white, color: Colors.white,
), ),
padding: EdgeInsets.only(left: 5, right: 5, top: 15, bottom: 5), padding: EdgeInsets.only(
left: 5,
right: 5,
top: 15,
bottom: 5,
),
child: SingleChildScrollView( child: SingleChildScrollView(
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
child: isDesktop child:
? Row( isDesktop
mainAxisAlignment: MainAxisAlignment.spaceEvenly, ? Row(
children: _buildOptions(), mainAxisAlignment:
) MainAxisAlignment.spaceEvenly,
: SingleChildScrollView( children: _buildOptions(),
scrollDirection: Axis.horizontal, )
child: ConstrainedBox( // Prevent overflow by setting min width : SingleChildScrollView(
constraints: BoxConstraints( scrollDirection: Axis.horizontal,
minWidth: MediaQuery.of(context).size.width, child: ConstrainedBox(
), // Prevent overflow by setting min width
child: IntrinsicWidth( // Let Row size itself correctly constraints: BoxConstraints(
child: Row( minWidth: MediaQuery.of(context).size.width,
crossAxisAlignment: CrossAxisAlignment.start, ),
children: _buildOptions(), child: IntrinsicWidth(
), // Let Row size itself correctly
), child: Row(
), crossAxisAlignment:
), CrossAxisAlignment.start,
children: _buildOptions(),
),
),
),
),
), ),
), ),
SizedBox(height: 15), SizedBox(height: 15),
@ -817,9 +858,15 @@ class _OrgSetUpState extends State<OrgSetUp> {
initialBodyColor: bodyColor, initialBodyColor: bodyColor,
onLayoutColorSelected: ( onLayoutColorSelected: (
Color selectedLayoutColor, Color selectedLayoutColor,
Color selectedSecondaryColor,
Color selectedTeritaryColor,
) { ) {
setState(() { setState(() {
layoutColor = selectedLayoutColor; layoutColor = selectedLayoutColor;
layoutSecondaryColor =
selectedSecondaryColor;
layoutTertiaryColor =
selectedTeritaryColor;
}); });
}, },
onBodyColorSelected: ( onBodyColorSelected: (

View File

@ -4,7 +4,8 @@ class ColorThemePickerWidget extends StatefulWidget {
final Color? initialLayoutColor; final Color? initialLayoutColor;
final Color? initialBodyColor; final Color? initialBodyColor;
final Function(Color) onLayoutColorSelected; final Function(Color layout, Color secondaryColor, Color tertiaryColor)
onLayoutColorSelected;
final Function(Color) onBodyColorSelected; final Function(Color) onBodyColorSelected;
const ColorThemePickerWidget({ const ColorThemePickerWidget({
@ -21,6 +22,8 @@ class ColorThemePickerWidget extends StatefulWidget {
class _ColorThemePickerWidgetState extends State<ColorThemePickerWidget> { class _ColorThemePickerWidgetState extends State<ColorThemePickerWidget> {
late Color selectedLayoutColor; late Color selectedLayoutColor;
Color? selectedSecondaryColor;
Color? selectedTertiaryColor;
late Color selectedBodyColor; late Color selectedBodyColor;
// Layout colors // Layout colors
@ -36,7 +39,35 @@ class _ColorThemePickerWidgetState extends State<ColorThemePickerWidget> {
Color(0xFFc94b92), // rose light Color(0xFFc94b92), // rose light
Color(0xFF9C27B0), // Purple Color(0xFF9C27B0), // Purple
Color(0xFF9B59B6), // Purple 2 Color(0xFF9B59B6), // Purple 2
]; ];
final List<Color> layoutSecondaryColors = [
Color(0xFF00B0FF), // Lighter Blue
Color(0xFF00ACC1), // Teal Blue
Color(0xFF43A047), // Dark Green
Color(0xFF27AE60), // Medium Emerald
Color(0xFFFFC107), // Amber (complementary to orange)
Color(0xFFFFA726), // Light orange
Color(0xFFE64A19), // Deep Orange
Color(0xFFFF4081), // Bright Pink (complementary to rose)
Color(0xFFF48FB1), // Light Pink
Color(0xFFBA68C8), // Light Purple
Color(0xFFAB47BC), // Orchid Purple
];
final List<Color> layoutTertiaryColors = [
Color(0xFF82B1FF), // Very Light Blue
Color(0xFF4DD0E1), // Lighter Teal
Color(0xFF81C784), // Light Green
Color(0xFFAAF0D1), // Pastel Mint
Color(0xFFFFE0B2), // Pale Orange
Color(0xFFFFCCBC), // Light Orange Peach
Color(0xFFFFAB91), // Light Coral
Color(0xFFF8BBD0), // Pastel Rose
Color(0xFFF8BBD0), // Pastel Pink
Color(0xFFE1BEE7), // Lavender
Color(0xFFD1C4E9), // Light Purple Grey
];
// Body colors // Body colors
final List<Color> bodyThemeColors = [ final List<Color> bodyThemeColors = [
@ -63,16 +94,36 @@ class _ColorThemePickerWidgetState extends State<ColorThemePickerWidget> {
children: [ children: [
// Layout Color Picker // Layout Color Picker
GestureDetector( GestureDetector(
onTap: () => _showColorPickerDialog( onTap:
title: "Choose Layout Color", () => _showColorPickerDialog(
colors: layoutThemeColors, title: "Choose Layout Color",
onColorSelected: (color) { colors: layoutThemeColors,
setState(() { onColorSelected: (color) {
selectedLayoutColor = color; setState(() {
}); selectedLayoutColor = color;
widget.onLayoutColorSelected(color); print("selectedLayoutColor - $selectedLayoutColor");
}, final SelectedIndex = layoutThemeColors.indexOf(color);
), print("SelectedIndexLayout - $SelectedIndex");
if (SelectedIndex != -1) {
final secondaryColor =
layoutSecondaryColors[SelectedIndex];
final primaryColor = layoutTertiaryColors[SelectedIndex];
selectedSecondaryColor = secondaryColor;
selectedTertiaryColor = primaryColor;
print("selectedSecondaryColor - $selectedSecondaryColor");
print("selectedPrimaryColor - $selectedTertiaryColor");
}
});
widget.onLayoutColorSelected(
color,
selectedSecondaryColor!,
selectedTertiaryColor!,
);
},
),
child: _buildColorBox( child: _buildColorBox(
selectedLayoutColor ?? Colors.grey.shade300, selectedLayoutColor ?? Colors.grey.shade300,
Icons.palette, Icons.palette,
@ -179,24 +230,37 @@ class _ColorThemePickerWidgetState extends State<ColorThemePickerWidget> {
showDialog( showDialog(
context: context, context: context,
builder: (context) => AlertDialog( builder:
title: Text(title), (context) => AlertDialog(
content: Column( title: Text(title),
mainAxisSize: MainAxisSize.min, content: Column(
children: [ mainAxisSize: MainAxisSize.min,
Row( children: [
mainAxisAlignment: MainAxisAlignment.center, Row(
children: firstRow.map((color) => _buildColorCircle(color, onColorSelected)).toList(), mainAxisAlignment: MainAxisAlignment.center,
children:
firstRow
.map(
(color) =>
_buildColorCircle(color, onColorSelected),
)
.toList(),
),
if (secondRow.isNotEmpty) SizedBox(height: 10),
if (secondRow.isNotEmpty)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children:
secondRow
.map(
(color) =>
_buildColorCircle(color, onColorSelected),
)
.toList(),
),
],
), ),
if (secondRow.isNotEmpty) SizedBox(height: 10), ),
if (secondRow.isNotEmpty)
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: secondRow.map((color) => _buildColorCircle(color, onColorSelected)).toList(),
),
],
),
),
); );
} }
@ -215,5 +279,4 @@ class _ColorThemePickerWidgetState extends State<ColorThemePickerWidget> {
), ),
); );
} }
} }

View File

@ -103,7 +103,6 @@ class PersonalDetailsState extends State<PersonalDetails> {
bool _postalCodeFocus = false; bool _postalCodeFocus = false;
bool _roleIdFocus = false; bool _roleIdFocus = false;
late bool isTravelAgent = false; late bool isTravelAgent = false;
String? selectedTab; String? selectedTab;
@ -158,7 +157,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
Color? bodyColor; Color? bodyColor;
final Map<String, TextEditingController> controllers = {}; final Map<String, TextEditingController> controllers = {};
Map<String, String> errorMessages2 = {}; Map<String, String> errorMessages = {};
@override @override
void initState() { void initState() {
@ -180,20 +179,27 @@ class PersonalDetailsState extends State<PersonalDetails> {
print("selectedServiceIdsAPI - $selectedServiceIds"); print("selectedServiceIdsAPI - $selectedServiceIds");
_addFocusListener(_fnameFocusNode, (focus) => _fnameFocus = focus);
_addFocusListener(_fnameFocusNode, (focus) => _fnameFocus = focus); _addFocusListener(_lnameFocusNode, (focus) => _lnameFocus = focus);
_addFocusListener(_lnameFocusNode, (focus) => _lnameFocus = focus); _addFocusListener(_emailFocusNode, (focus) => _emailFocus = focus);
_addFocusListener(_emailFocusNode, (focus) => _emailFocus = focus); _addFocusListener(_passwordFocusNode, (focus) => _passwordFocus = focus);
_addFocusListener(_passwordFocusNode, (focus) => _passwordFocus = focus); _addFocusListener(_dobFocusNode, (focus) => _dobFocus = focus);
_addFocusListener(_dobFocusNode, (focus) => _dobFocus = focus); _addFocusListener(_genderFocusNode, (focus) => _genderFocus = focus);
_addFocusListener(_genderFocusNode, (focus) => _genderFocus = focus); _addFocusListener(
_addFocusListener(_mobileNumberFocusNode, (focus) => _mobileNumberFocus = focus); _mobileNumberFocusNode,
_addFocusListener(_alternateMobileFocusNode, (focus) => _alternateMobileFocus = focus); (focus) => _mobileNumberFocus = focus,
_addFocusListener(_addressFocusNode, (focus) => _addressFocus = focus); );
_addFocusListener(_countryFocusNode, (focus) => _countryFocus = focus); _addFocusListener(
_addFocusListener(_postalCodeFocusNode, (focus) => _postalCodeFocus = focus); _alternateMobileFocusNode,
_addFocusListener(_roleIdFocusNode, (focus) => _roleIdFocus = focus); (focus) => _alternateMobileFocus = focus,
);
_addFocusListener(_addressFocusNode, (focus) => _addressFocus = focus);
_addFocusListener(_countryFocusNode, (focus) => _countryFocus = focus);
_addFocusListener(
_postalCodeFocusNode,
(focus) => _postalCodeFocus = focus,
);
_addFocusListener(_roleIdFocusNode, (focus) => _roleIdFocus = focus);
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
loadAllServices(); loadAllServices();
@ -233,7 +239,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
userId, userId,
); );
if (response.isNotEmpty) { if (response.isNotEmpty) {
_clearError(field); // _clearError(field);
widget.errorMessages[field] = widget.errorMessages[field] =
response['message'] ?? "$label Already Exists"; response['message'] ?? "$label Already Exists";
print("Duplicate found: ${response['message']}"); print("Duplicate found: ${response['message']}");
@ -1052,85 +1058,89 @@ class PersonalDetailsState extends State<PersonalDetails> {
onTap: () { onTap: () {
_genderFocusNode?.requestFocus(); _genderFocusNode?.requestFocus();
}, },
child: DropdownSearch<String>( child: DropdownSearch<String>(
selectedItem: selectedGender, selectedItem: selectedGender,
enabled: !widget.isViewMode, enabled: !widget.isViewMode,
popupProps: PopupProps.menu( popupProps: PopupProps.menu(
showSearchBox: false, // Set true if you want search showSearchBox: false, // Set true if you want search
fit: FlexFit.loose, fit: FlexFit.loose,
constraints: BoxConstraints(maxHeight: 200), constraints: BoxConstraints(maxHeight: 200),
itemBuilder: itemBuilder:
(context, item, isSelected) => Container( (context, item, isSelected) => Container(
color: Colors.white, color: Colors.white,
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 6,
),
child: Text(
item,
style: GoogleFonts.poppins(fontSize: 11.5),
),
),
),
items: genderOptions,
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
// border: InputBorder.none,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: BorderSide(
color:
(_genderFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(_genderFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: (layoutColor ?? Colors.grey),
width: 0.5,
),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 10, horizontal: 10,
vertical: 6, // vertical: 1,
), ),
child: Text( // contentPadding: EdgeInsets.symmetric(horizontal: 1),
item, ),
style: GoogleFonts.poppins(fontSize: 11.5), ),
dropdownBuilder:
(context, selectedItem) => Align(
alignment: Alignment.centerLeft,
child: Text(
selectedItem ?? "Select Gender",
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
),
), ),
), onChanged:
), widget.isViewMode
items: genderOptions, ? null
dropdownDecoratorProps: DropDownDecoratorProps( : (String? newValue) {
dropdownSearchDecoration: InputDecoration( setState(() {
// border: InputBorder.none, selectedGender = newValue;
border: OutlineInputBorder( print("selectedGender - $selectedGender");
borderRadius: BorderRadius.circular(5), });
borderSide: BorderSide( widget.onGenderChanged?.call(newValue);
color: },
(_genderFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(_genderFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color : (layoutColor ?? Colors.grey), width: 0.5),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 10,
// vertical: 1,
),
// contentPadding: EdgeInsets.symmetric(horizontal: 1),
), ),
), ),
dropdownBuilder: ),
(context, selectedItem) => Align(
alignment: Alignment.centerLeft,
child: Text(
selectedItem ?? "Select Gender",
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
),
),
onChanged:
widget.isViewMode
? null
: (String? newValue) {
setState(() {
selectedGender = newValue;
print("selectedGender - $selectedGender");
});
widget.onGenderChanged?.call(newValue);
},
),),),
), ),
), ),
], ],
@ -1187,8 +1197,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
child: child: Focus(
Focus(
focusNode: _dobFocusNode, focusNode: _dobFocusNode,
onKeyEvent: (FocusNode node, KeyEvent event) { onKeyEvent: (FocusNode node, KeyEvent event) {
// Only act on KeyDown and when Enter is pressed // Only act on KeyDown and when Enter is pressed
@ -1225,7 +1234,10 @@ class PersonalDetailsState extends State<PersonalDetails> {
child: TextField( child: TextField(
controller: widget.controllers["dob"], controller: widget.controllers["dob"],
readOnly: true, readOnly: true,
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
decoration: InputDecoration( decoration: InputDecoration(
labelText: "Select Date", labelText: "Select Date",
labelStyle: GoogleFonts.poppins( labelStyle: GoogleFonts.poppins(
@ -1247,46 +1259,46 @@ class PersonalDetailsState extends State<PersonalDetails> {
), ),
), ),
// GestureDetector( // GestureDetector(
// onTap: // onTap:
// widget.isViewMode // widget.isViewMode
// ? null // ? null
// : () async { // : () async {
// await _selectCheckDateOfBirth(context); // await _selectCheckDateOfBirth(context);
// if (widget.controllers["dob"]!.text.isNotEmpty) { // if (widget.controllers["dob"]!.text.isNotEmpty) {
// setState(() { // setState(() {
// // errorMessages.remove("start_date"); // // errorMessages.remove("start_date");
// }); // });
// // Delay re-focusing the DOB field slightly // // Delay re-focusing the DOB field slightly
// Future.delayed(Duration(milliseconds: 100), () { // Future.delayed(Duration(milliseconds: 100), () {
// _dobFocusNode?.requestFocus(); // _dobFocusNode?.requestFocus();
// }); // });
// } // }
// }, // },
// child: AbsorbPointer( // child: AbsorbPointer(
// child: TextField( // child: TextField(
// controller: widget.controllers["dob"], // controller: widget.controllers["dob"],
// focusNode:_dobFocusNode, // focusNode:_dobFocusNode,
// readOnly: true, // readOnly: true,
// style: GoogleFonts.poppins(fontSize: 12, color: Colors.black), // style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
// decoration: InputDecoration( // decoration: InputDecoration(
// labelText: "Select Date", // labelText: "Select Date",
// labelStyle: GoogleFonts.poppins( // labelStyle: GoogleFonts.poppins(
// fontSize: 12, // fontSize: 12,
// fontWeight: FontWeight.w400, // fontWeight: FontWeight.w400,
// color: Colors.grey, // color: Colors.grey,
// ), // ),
// floatingLabelBehavior: FloatingLabelBehavior.never, // floatingLabelBehavior: FloatingLabelBehavior.never,
// border: InputBorder.none, // border: InputBorder.none,
// contentPadding: EdgeInsets.symmetric(vertical: 16), // contentPadding: EdgeInsets.symmetric(vertical: 16),
// suffixIcon: Icon( // suffixIcon: Icon(
// Icons.calendar_today, // Icons.calendar_today,
// size: 16, // size: 16,
// color: Color(0xFF8B8FB2), // color: Color(0xFF8B8FB2),
// ), // ),
// ), // ),
// ), // ),
// ), // ),
// ), // ),
), ),
), ),
], ],
@ -1477,7 +1489,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
countryMap = { countryMap = {
for (var country in countryList) for (var country in countryList)
(country['country_code'] ?? ''): (country['country_code'] ?? ''):
'${country['country_name'] ?? ''} (${country['country_code'] ?? ''})', '${country['country_name'] ?? ''} (${country['country_code'] ?? ''})',
}; };
// Extract only country codes for processing // Extract only country codes for processing
@ -1503,125 +1515,137 @@ class PersonalDetailsState extends State<PersonalDetails> {
isDesktop: widget.isDesktop, isDesktop: widget.isDesktop,
child: SizedBox( child: SizedBox(
height: 40, height: 40,
width: double.infinity, width: double.infinity,
child: Focus( child: Focus(
focusNode: _countryFocusNode, focusNode: _countryFocusNode,
onFocusChange: (hasFocus) { onFocusChange: (hasFocus) {
setState(() { setState(() {
_countryFocus = hasFocus; _countryFocus = hasFocus;
}); });
},
child: GestureDetector(
onTap: () {
// Request focus when user taps
_countryFocusNode?.requestFocus();
}, },
child: GestureDetector( child: DropdownSearch<String>(
onTap: () { selectedItem: countryMap[selectedCountry],
// Request focus when user taps enabled: !widget.isViewMode,
_countryFocusNode?.requestFocus(); popupProps: PopupProps.menu(
}, showSearchBox: true, // Enables search functionality
child: DropdownSearch<String>( fit: FlexFit.loose, // Allows flexible height
selectedItem: countryMap[selectedCountry], menuProps: const MenuProps(backgroundColor: Colors.white),
enabled: !widget.isViewMode, itemBuilder:
popupProps: PopupProps.menu( (context, item, isSelected) => Container(
showSearchBox: true, // Enables search functionality padding: EdgeInsets.symmetric(
fit: FlexFit.loose, // Allows flexible height horizontal: 10,
menuProps: const MenuProps(backgroundColor: Colors.white), vertical: 6,
itemBuilder: ),
(context, item, isSelected) => Container( child: Text(
padding: EdgeInsets.symmetric( item,
horizontal: 10, style: GoogleFonts.poppins(fontSize: 11.5),
vertical: 6, ),
), ),
child: Text( constraints: BoxConstraints(maxHeight: 180),
item, searchFieldProps: TextFieldProps(
style: GoogleFonts.poppins(fontSize: 11.5), decoration: InputDecoration(
hintText: "Search Country...",
contentPadding: EdgeInsets.symmetric(
horizontal: 3,
vertical: 3,
),
), ),
), ),
constraints: BoxConstraints(maxHeight: 180),
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
hintText: "Search Country...",
contentPadding: EdgeInsets.symmetric(horizontal: 3,vertical: 3),
), ),
items: countryMap.values.toList(),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
// border: InputBorder.none,
// contentPadding: EdgeInsets.symmetric(horizontal: 1),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(_countryFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(_countryFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: (layoutColor ?? Colors.grey),
width: 0.5,
),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 8.0,
),
),
),
dropdownBuilder:
(context, selectedItem) => Align(
// Center-align selected item
alignment: Alignment.centerLeft,
child: Text(
selectedItem ?? "Select Country",
style: GoogleFonts.poppins(
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
},
), ),
), ),
items: countryMap.values.toList(), ),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
// border: InputBorder.none,
// contentPadding: EdgeInsets.symmetric(horizontal: 1),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(
color:
(_countryFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(_countryFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color : (layoutColor ?? Colors.grey), width: 0.5),
),
contentPadding: EdgeInsets.symmetric(horizontal: 10.0, vertical: 8.0),
),
),
dropdownBuilder:
(context, selectedItem) => Align(
// Center-align selected item
alignment: Alignment.centerLeft,
child: Text(
selectedItem ?? "Select Country",
style: GoogleFonts.poppins(
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
},
),),)
), ),
), ),
], ],
@ -1780,99 +1804,107 @@ class PersonalDetailsState extends State<PersonalDetails> {
// Request focus when user taps // Request focus when user taps
_roleIdFocusNode?.requestFocus(); _roleIdFocusNode?.requestFocus();
}, },
child: DropdownSearch<String>( child: DropdownSearch<String>(
selectedItem: selectedRole != null ? roleMap[selectedRole] : null, selectedItem:
enabled: !widget.isViewMode, selectedRole != null ? roleMap[selectedRole] : null,
popupProps: PopupProps.menu( enabled: !widget.isViewMode,
showSearchBox: true, popupProps: PopupProps.menu(
fit: FlexFit.loose, showSearchBox: true,
constraints: BoxConstraints(maxHeight: 250), fit: FlexFit.loose,
menuProps: const MenuProps(backgroundColor: Colors.white), constraints: BoxConstraints(maxHeight: 250),
itemBuilder: menuProps: const MenuProps(backgroundColor: Colors.white),
(context, item, isSelected) => Container( itemBuilder:
color: Colors.white, (context, item, isSelected) => Container(
padding: EdgeInsets.symmetric( color: Colors.white,
horizontal: 10, padding: EdgeInsets.symmetric(
vertical: 6, horizontal: 10,
), vertical: 6,
child: Text( ),
item, child: Text(
style: GoogleFonts.poppins(fontSize: 11.5), item,
style: GoogleFonts.poppins(fontSize: 11.5),
),
),
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
hintText: "Search Role...",
contentPadding: EdgeInsets.symmetric(horizontal: 10),
), ),
), ),
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
hintText: "Search Role...",
contentPadding: EdgeInsets.symmetric(horizontal: 10),
), ),
items: roleNames,
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
// border: InputBorder.none,
// contentPadding: EdgeInsets.symmetric(horizontal: 1),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: BorderSide(
color:
(_roleIdFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(_roleIdFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: (layoutColor ?? Colors.grey),
width: 0.5,
),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 8,
vertical: 1,
),
),
),
dropdownBuilder:
(context, selectedItem) => Align(
alignment: Alignment.centerLeft,
child: Text(
selectedItem ?? "Select Role",
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
),
),
onChanged:
widget.isViewMode
? null
: (String? newValue) {
widget.errorMessages.remove("role_id");
if (newValue == null) return;
final selectedKey =
roleMap.entries
.firstWhere(
(entry) => entry.value == newValue,
)
.key;
setState(() {
selectedRole = selectedKey;
isTravelAgent = selectedKey == "5";
});
widget.onUserTypeChanged?.call(isTravelAgent);
widget.onRoleChanged?.call(selectedKey);
},
), ),
), ),
items: roleNames, ),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
// border: InputBorder.none,
// contentPadding: EdgeInsets.symmetric(horizontal: 1),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: BorderSide(
color:
(_roleIdFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
width: 0.5,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(_roleIdFocus)
? (layoutColor ?? Colors.blue)
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 0.5,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color : (layoutColor ?? Colors.grey), width: 0.5),
),
contentPadding: EdgeInsets.symmetric(
horizontal: 8,
vertical: 1,
),
),
),
dropdownBuilder:
(context, selectedItem) => Align(
alignment: Alignment.centerLeft,
child: Text(
selectedItem ?? "Select Role",
style: GoogleFonts.poppins(
fontSize: 12,
color: Colors.black,
),
),
),
onChanged:
widget.isViewMode
? null
: (String? newValue) {
widget.errorMessages.remove("role_id");
if (newValue == null) return;
final selectedKey =
roleMap.entries
.firstWhere((entry) => entry.value == newValue)
.key;
setState(() {
selectedRole = selectedKey;
isTravelAgent = selectedKey == "5";
});
widget.onUserTypeChanged?.call(isTravelAgent);
widget.onRoleChanged?.call(selectedKey);
},
),),),
), ),
), ),
if (widget.errorMessages["role_id"] != null) ...[ if (widget.errorMessages["role_id"] != null) ...[