UI_HOTEL_NAME

This commit is contained in:
venbaittech 2025-08-05 18:32:24 +05:30
parent a7310238c0
commit bf9a2b1277
4 changed files with 337 additions and 176 deletions

View File

@ -40,7 +40,8 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
// late Map<String, String> countryMap;
Map<String, String> countryMap = {};
List<String> allItems = [];
List<String> filteredItems = [];
String? selectedClass;
String? exceptionalClass = "0";
bool hasExceptionalClass = false;
@ -68,6 +69,8 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
late TextEditingController _checkOutTimeController = TextEditingController();
late TextEditingController _commentsController = TextEditingController();
List<dynamic>? futureHotels;
bool _destinationFocused = false;
bool _isHotelNameFocused = false;
bool _CategoryFocused = false;
@ -129,6 +132,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
WidgetsBinding.instance.addPostFrameCallback((_) {
loadInitialData();
});
_addFocusListener(
_destinationFocusNode,
(focus) => _destinationFocused = focus,
@ -284,11 +288,36 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
// : Colors.redAccent;
// });
futureHotels = await apiService.fetchGetHotels();
print("futureHotels - $futureHotels");
// Extract hotel_name and assign to items
allItems =
futureHotels!
.map<String>((hotel) => hotel['hotel_name'].toString())
.toList();
setState(() {
layoutColor =
layoutString != null
? Color(int.parse(layoutString))
: Colors.redAccent;
filteredItems = List.from(allItems);
print("items - $allItems");
_hotelNameController.addListener(_filterItems);
});
}
void _filterItems() {
print("Filter iteks");
String query = _hotelNameController.text.toLowerCase();
print("Filter iteks - $query");
setState(() {
filteredItems =
allItems.where((item) => item.toLowerCase().contains(query)).toList();
});
}
@ -587,7 +616,7 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
),
);
}
final List<String> items = ['Apple', 'Banana', 'Orange', 'Mango'];
// final List<String> items = ['Apple Banana', 'Banana', 'Orange', 'Mango'];
// Default selected value
// selectedClass ??=
// dropdownItems.isNotEmpty ? dropdownItems.first.value : null;
@ -665,26 +694,124 @@ class _AccomodationScreenState extends State<AccomodationScreen> {
),
SizedBox(height: 5),
CustomTextFieldItnerarySubWrapper(
isFocused: _isHotelNameFocused,
// isFocused: _isHotelNameFocused,
isFocused: false,
padding: const EdgeInsets.symmetric(horizontal: 0),
isDesktop: isDesktop,
// width:
// isDesktop
// ? MediaQuery.of(context).size.width * 0.34
// : MediaQuery.of(context).size.width * 0.66,
child: SizedBox(
height: 40,
child: TextField(
focusNode: _hotelNameFocusNode, // Assign the correct focus node
controller: _hotelNameController,
style: TextStyle(fontSize: 12),
decoration: InputDecoration(
labelText: "Hotel Name",
labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
floatingLabelBehavior: FloatingLabelBehavior.never,
border: InputBorder.none,
contentPadding: EdgeInsets.symmetric(vertical: 16),
child: Focus(
focusNode: _hotelNameFocusNode,
onFocusChange: (hasFocus) {
setState(() {
_isHotelNameFocused = hasFocus;
});
},
child: SizedBox(
height: 40,
child: GestureDetector(
onTap: () {
_hotelNameFocusNode.requestFocus();
},
child: DropdownSearch<String>(
items: allItems,
selectedItem: _hotelNameController.text,
popupProps: PopupProps.menu(
menuProps: const MenuProps(backgroundColor: Colors.white),
showSearchBox: true,
itemBuilder:
(context, item, isSelected) => Padding(
padding: const EdgeInsets.symmetric(
horizontal: 12,
vertical: 2,
),
child: Text(
item,
style: GoogleFonts.poppins(
fontSize: 11,
), // 👈 smaller font size here
),
),
searchFieldProps: TextFieldProps(
controller: _hotelNameController,
decoration: InputDecoration(
labelText: "Enter/ Search Hotel Name",
labelStyle: GoogleFonts.poppins(fontSize: 11),
isDense: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
// contentPadding: EdgeInsets.symmetric(
// vertical: 12,
// horizontal: 10,
// ),
border: OutlineInputBorder(),
),
),
fit: FlexFit.loose,
),
dropdownDecoratorProps: DropDownDecoratorProps(
dropdownSearchDecoration: InputDecoration(
labelText: "Hotel Name",
labelStyle: GoogleFonts.poppins(
fontSize: 11,
color: Colors.grey,
),
// border: OutlineInputBorder(),
// border: InputBorder.none,
isDense: true,
floatingLabelBehavior: FloatingLabelBehavior.never,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5),
borderSide: BorderSide(
color:
(_isHotelNameFocused ?? false)
? layoutColor!
: Colors.white,
width: 1,
),
),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color:
(_CategoryFocused ?? false)
? layoutColor
: Colors.white,
// : const Color(0xFFD6D5E6),
width: 1,
// const Color(0xFFD6D5E6),
),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: layoutColor, width: 1),
),
contentPadding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 10,
),
),
),
onChanged: (value) {
_hotelNameController.text = value ?? '';
},
),
),
// TextField(
// focusNode: _hotelNameFocusNode, // Assign the correct focus node
// controller: _hotelNameController,
// style: TextStyle(fontSize: 12),
// decoration: InputDecoration(
// labelText: "Hotel Name",
// labelStyle: TextStyle(fontSize: 12, color: Colors.grey),
// floatingLabelBehavior: FloatingLabelBehavior.never,
// border: InputBorder.none,
// contentPadding: EdgeInsets.symmetric(vertical: 16),
// ),
// ),
),
),
),

View File

@ -173,7 +173,10 @@ class _CustomAppBarState extends State<CustomAppBar> {
// Save to SharedPreferences
await prefs.setString('layout_color', selectedOrg?['layout_color']);
await prefs.setString('secondary_color', selectedOrg?['secondary_color']);
await prefs.setString(
'secondary_color',
selectedOrg?['secondary_color'],
);
await prefs.setString('ternary_color', selectedOrg?['ternary_color']);
await prefs.setString('body_color', selectedOrg?['color']);
await prefs.setString('body_color', selectedOrg?['plan_action']);
@ -478,167 +481,169 @@ class _CustomAppBarState extends State<CustomAppBar> {
children: [
// if (userData?["role"] != "User")
ExcludeFocus(
// Focus(
// canRequestFocus: false,
child:Builder(
builder:
(context) => PopupMenuButton<String>(
color: Colors.white,
padding: EdgeInsets.zero,
offset: const Offset(
0,
50,
), // 👈 shift it 50 pixels down
onSelected: (String value) {
switch (value) {
case '/OrganizationSettings':
context.go('/OrganizationSettings');
break;
// case '/OrganizationSetup':
// context.go('/OrganizationSetup');
// break;
case '/listUser':
context.go('/listUser');
break;
case '/report':
context.go('/report');
break;
// case '/department':
// context.go('/department');
// break;
// case '/PolicyList':
// context.go('/PolicyList');
// case '/getPerdiem':
// context.go('/getPerdiem');
// case '/templateList':
// context.go('/templateList');
// case '/template':
// context.go('/template');
// Focus(
// canRequestFocus: false,
child: Builder(
builder:
(context) => PopupMenuButton<String>(
color: Colors.white,
padding: EdgeInsets.zero,
offset: const Offset(
0,
50,
), // 👈 shift it 50 pixels down
onSelected: (String value) {
switch (value) {
case '/OrganizationSettings':
context.go('/OrganizationSettings');
break;
// case '/OrganizationSetup':
// context.go('/OrganizationSetup');
// break;
case '/listUser':
context.go('/listUser');
break;
case '/report':
context.go('/report');
break;
// case '/department':
// context.go('/department');
// break;
// case '/PolicyList':
// context.go('/PolicyList');
// case '/getPerdiem':
// context.go('/getPerdiem');
// case '/templateList':
// context.go('/templateList');
// case '/template':
// context.go('/template');
case '/CreateUserDetails':
context.go(
"/CreateUserDetails",
extra: {
"selectedUser": profileUserDetails,
"isEditProfile": true,
"isViewMode": false,
},
);
case '/logout':
logout(context);
// context.go('/');
break;
}
},
case '/CreateUserDetails':
context.go(
"/CreateUserDetails",
extra: {
"selectedUser": profileUserDetails,
"isEditProfile": true,
"isViewMode": false,
},
);
case '/logout':
logout(context);
// context.go('/');
break;
}
},
// itemBuilder: (BuildContext context) =>
// menuItems.map(buildMenuItem).toList(),
itemBuilder: (BuildContext context) {
// final isUser = userData?["role"] == "User";
final role = userData?["role"];
List<Map<String, dynamic>> filteredItems;
// itemBuilder: (BuildContext context) =>
// menuItems.map(buildMenuItem).toList(),
itemBuilder: (BuildContext context) {
// final isUser = userData?["role"] == "User";
final role = userData?["role"];
List<Map<String, dynamic>> filteredItems;
if (role == "User") {
filteredItems =
menuItems
.where(
(item) =>
item['value'] ==
'/CreateUserDetails' ||
item['value'] == '/logout',
)
.toList();
} else if (role == "Travel Agent") {
filteredItems =
menuItems
.where((item) => item['value'] == '/logout')
.toList();
} else {
filteredItems = menuItems;
}
if (role == "User") {
filteredItems =
menuItems
.where(
(item) =>
item['value'] ==
'/CreateUserDetails' ||
item['value'] == '/logout',
)
.toList();
} else if (role == "Travel Agent") {
filteredItems =
menuItems
.where(
(item) => item['value'] == '/logout',
)
.toList();
} else {
filteredItems = menuItems;
}
// Create a new list starting with role display and divider
return [
PopupMenuItem<String>(
enabled: false, // Not clickable
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
userData?["role"] ?? '',
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.black,
// Create a new list starting with role display and divider
return [
PopupMenuItem<String>(
enabled: false, // Not clickable
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
userData?["role"] ?? '',
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
const PopupMenuDivider(),
// const Divider(), // 👈 Divider after role
],
),
),
...filteredItems
.map(buildMenuItem)
.toList(), // 👈 then normal items
// const PopupMenuDivider(),
PopupMenuItem<String>(
enabled: false, // Not clickable
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Last Login : ",
style: GoogleFonts.poppins(
fontSize: 10,
fontWeight: FontWeight.w500,
color: Colors.grey,
),
),
// SizedBox(width: 10),
Text(
"${userData?["last_login_at"] ?? ''}",
style: GoogleFonts.poppins(
fontSize: 10,
fontWeight: FontWeight.w400,
color: Colors.grey,
),
),
],
),
),
];
},
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
userData?["name"] ?? "N/A",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.black,
const PopupMenuDivider(),
// const Divider(), // 👈 Divider after role
],
),
// style: const TextStyle(
// fontSize: 14,
// fontWeight: FontWeight.w500,
// fontFamily: "Roboto",
// color: Colors.black,
// ),
),
const Icon(
Icons.arrow_drop_down,
size: 20,
color: Colors.black87,
...filteredItems
.map(buildMenuItem)
.toList(), // 👈 then normal items
// const PopupMenuDivider(),
PopupMenuItem<String>(
enabled: false, // Not clickable
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Last Login : ",
style: GoogleFonts.poppins(
fontSize: 10,
fontWeight: FontWeight.w500,
color: Colors.grey,
),
),
// SizedBox(width: 10),
Text(
"${userData?["last_login_at"] ?? ''}",
style: GoogleFonts.poppins(
fontSize: 10,
fontWeight: FontWeight.w400,
color: Colors.grey,
),
),
],
),
),
],
];
},
child: MouseRegion(
cursor: SystemMouseCursors.click,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Text(
userData?["name"] ?? "N/A",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.black,
),
// style: const TextStyle(
// fontSize: 14,
// fontWeight: FontWeight.w500,
// fontFamily: "Roboto",
// color: Colors.black,
// ),
),
const Icon(
Icons.arrow_drop_down,
size: 20,
color: Colors.black87,
),
],
),
),
),
),
),
),
),
const SizedBox(width: 8),
],
@ -653,7 +658,7 @@ class _CustomAppBarState extends State<CustomAppBar> {
color: layoutColor, // Set the color of the bottom border
),
),
),
),
);
}

View File

@ -898,7 +898,7 @@ class ApiService {
}
// download the Template for bulk upload the user
Future<Map<String, dynamic>> getDownloadUserTemplateForUpload() async {
Future<Map<String, dynamic>> getDownloadUserTemplateForUpload() async {
final String apiUrldata =
'$apiUrl/api/user/userUploadTemplate'; // download the Template for bulk upload user => api
@ -1117,7 +1117,7 @@ class ApiService {
}
final List<Map<String, dynamic>> listData =
List<Map<String, dynamic>>.from(data['data']);
List<Map<String, dynamic>>.from(data['data']);
if (listData.isEmpty) {
throw Exception("No department found with ID $id");
@ -1591,7 +1591,11 @@ class ApiService {
}
}
Future<Map<String, dynamic>> reportExcelDownload(String apiRoute,String body,String name,) async {
Future<Map<String, dynamic>> reportExcelDownload(
String apiRoute,
String body,
String name,
) async {
final String apiUrldata = '$apiUrl/api/$apiRoute';
// Sanitize name for filename (optional)
@ -1617,7 +1621,6 @@ class ApiService {
);
if (response.statusCode == 200) {
try {
print("report XL Dowloaded");
print(excelName);
@ -1651,4 +1654,33 @@ class ApiService {
}
// ----------------------- Report -------------------------
Future<List<dynamic>> fetchGetHotels() async {
// return [];
final orgId = await getOrgId();
final String apiUrlData = '$apiUrl/api/getHotels';
final String? token = await getToken();
print("Fetch Hotels 2KN : $token");
if (token == null) {
throw Exception('Token not found. Please log in.');
}
final response = await http.get(
Uri.parse(apiUrlData),
headers: {
'Authorization': 'Bearer $token',
'Content-Type': 'application/json',
},
);
if (response.statusCode == 200) {
final data = json.decode(response.body);
return data['data']; // Returning raw JSON list
} else {
throw Exception('Failed to load users');
}
}
}

View File

@ -67,9 +67,6 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter