minor issues fixes

This commit is contained in:
venba-Inspriron-3558 2025-06-23 16:11:45 +05:30
parent 1c77a03067
commit 284ff8779f
17 changed files with 2653 additions and 502 deletions

View File

@ -289,9 +289,15 @@ class HotelsDataState extends State<HotelsData> {
countryList = apiCountryData ?? [];
// Map country codes to country names
// countryMap = {
// for (var item in countryList)
// item['country_code'] as String: item['country_name'] as String,
// };
countryMap = {
for (var item in countryList)
item['country_code'] as String: item['country_name'] as String,
for (var country in countryList)
(country['country_code'] ?? ''):
'${country['country_name'] ?? ''} (${country['country_code'] ?? ''})',
};
// Extract only country codes for processing
@ -482,16 +488,34 @@ class HotelsDataState extends State<HotelsData> {
menuProps: const MenuProps(backgroundColor: Colors.white),
constraints: BoxConstraints(maxHeight: 200),
itemBuilder:
(context, item, isSelected) => Padding(
(context, item, isSelected) {
print("contryItem - $item");
final match = RegExp(r'^(.*)\s\((.*)\)$',).firstMatch(item);
final countryName = match?.group(1) ?? '';
final countryCode = match?.group(2) ?? '';
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 8.0,
horizontal: 8.0,
vertical: 6.0,
),
child: Text(
item,
style: GoogleFonts.poppins(fontSize: 11.5),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
countryName,
style: GoogleFonts.poppins(fontSize: 11.5),
),
Text(
countryCode,
style: GoogleFonts.poppins(fontSize: 11.5,color:Colors.grey),
),
],
),
),
),
);},
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
hintText: "Search ...",

View File

@ -346,9 +346,15 @@ class ForexDataState extends State<ForexData> {
countryList = apiCountryData ?? [];
// Map country codes to country names
// countryMap = {
// for (var item in countryList)
// item['country_code'] as String: item['country_name'] as String,
// };
countryMap = {
for (var item in countryList)
item['country_code'] as String: item['country_name'] as String,
for (var country in countryList)
(country['country_code'] ?? ''):
'${country['country_name'] ?? ''} (${country['country_code'] ?? ''})',
};
// Extract only country codes for processing
@ -426,18 +432,35 @@ class ForexDataState extends State<ForexData> {
popupProps: PopupProps.menu(
showSearchBox: true, // Enables search functionality
menuProps: const MenuProps(backgroundColor: Colors.white),
constraints: BoxConstraints(maxHeight: 250),
constraints: BoxConstraints(maxHeight: 200),
itemBuilder:
(context, item, isSelected) => Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 8.0,
),
child: Text(
item,
style: GoogleFonts.poppins(fontSize: 11.5),
),
),
(context, item, isSelected) {
print("contryItem - $item");
final match = RegExp(r'^(.*)\s\((.*)\)$',).firstMatch(item);
final countryName = match?.group(1) ?? '';
final countryCode = match?.group(2) ?? '';
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
vertical: 6.0,
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
countryName,
style: GoogleFonts.poppins(fontSize: 11.5),
),
Text(
countryCode,
style: GoogleFonts.poppins(fontSize: 11.5,color:Colors.grey),
),
],
),
),
);},
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
hintText: "Search ...",
@ -495,10 +518,87 @@ class ForexDataState extends State<ForexData> {
.firstWhere((entry) => entry.value == newValue)
.key;
selectedCountryName = newValue;
setCurrencyFromSelectedCountry(selectedCountry!);
});
},
),
// child: DropdownSearch<String>(
// selectedItem: countryMap[selectedCountry],
// popupProps: PopupProps.menu(
// showSearchBox: true, // Enables search functionality
// menuProps: const MenuProps(backgroundColor: Colors.white),
// constraints: BoxConstraints(maxHeight: 250),
// itemBuilder:
// (context, item, isSelected) => Padding(
// padding: const EdgeInsets.symmetric(
// horizontal: 10.0,
// vertical: 8.0,
// ),
// child: Text(
// item,
// style: GoogleFonts.poppins(fontSize: 11.5),
// ),
// ),
// searchFieldProps: TextFieldProps(
// decoration: InputDecoration(
// hintText: "Search ...",
// hintStyle: GoogleFonts.poppins(fontSize: 11),
// contentPadding: EdgeInsets.symmetric(horizontal: 4),
// ),
// ),
// ),
// items: countryMap.values.toList(),
// dropdownDecoratorProps: DropDownDecoratorProps(
// dropdownSearchDecoration: InputDecoration(
// // border: InputBorder.none,
// border: OutlineInputBorder(
// borderRadius: BorderRadius.circular(8),
// borderSide: BorderSide(
// color:
// (focusStates["country_codeFocused"] ?? false)
// ? widget.layoutColor!
// : Colors.white,
// // width: 0.5,
// ),
// ),
// enabledBorder: OutlineInputBorder(
// borderSide: BorderSide(
// color:
// (focusStates["country_codeFocused"] ?? false)
// ? widget.layoutColor!
// : Colors.white,
// // : const Color(0xFFD6D5E6),
// // width: 0.5,
// // const Color(0xFFD6D5E6),
// ),
// ),
// focusedBorder: OutlineInputBorder(
// borderSide: BorderSide(color: widget.layoutColor!, width: 1),
// ),
// contentPadding: EdgeInsets.symmetric(horizontal: 10.0,
// vertical: 8.0,),
// ),
// ),
// dropdownBuilder:
// (context, selectedItem) => Align(
// // Center-align selected item
// alignment: Alignment.centerLeft,
// child: Text(
// selectedItem ?? "Select ",
// style: GoogleFonts.poppins(fontSize: 11),
// ),
// ),
// onChanged: (String? newValue) {
// setState(() {
// // Find the country_code based on selected country_name
// selectedCountry =
// countryMap.entries
// .firstWhere((entry) => entry.value == newValue)
// .key;
// selectedCountryName = newValue;
// setCurrencyFromSelectedCountry(selectedCountry!);
// });
// },
// ),
)
)
),

View File

@ -644,16 +644,16 @@ class _PolicyState extends State<Policy> {
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
"Choose Policy Type",
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Color(0xFF575A74),
),
),
],
// children: [
// Text(
// "Choose Policy Type",
// style: GoogleFonts.poppins(
// fontSize: 12,
// fontWeight: FontWeight.w600,
// color: Color(0xFF575A74),
// ),
// ),
// ],
),
),
],

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:core';
import 'dart:typed_data';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
@ -323,12 +324,16 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
if (textControllers["from_date"]!.text.isEmpty ||
textControllers["to_date"]!.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent,
content: Text("Please choose a valid date range."),
behavior: SnackBarBehavior.floating,
),
Fluttertoast.showToast(
msg: "Please choose a valid date range.",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, '#dc1c13','#dc1c13')",
);
return;
}
@ -356,13 +361,21 @@ class _AdvancePurchaseState extends State<AdvancePurchase>
excelName,
);
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// backgroundColor: result['status'] ? Colors.green : Colors.red,
// content: Text(result['message']),
// behavior: SnackBarBehavior.floating,
// ),
// );
final String displayBackgroundColor = result['status'] ? '#28a745' : '#dc1c13';
final Color displayColor = result['status'] ? Colors.green : Colors.redAccent;
final String displayMessage = result['message'];
// final bool status = result['status'] == true;
Fluttertoast.showToast(
msg: displayMessage ,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: displayColor,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, $displayBackgroundColor, $displayBackgroundColor)",
);
}
void handleDomesticFilter(String query) {

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:core';
import 'dart:typed_data';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
@ -302,13 +303,18 @@ class _GuestHouseState extends State<GuestHouse>
if (textControllers["from_date"]!.text.isEmpty ||
textControllers["to_date"]!.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent,
content: Text("Please choose a valid date range."),
behavior: SnackBarBehavior.floating,
),
Fluttertoast.showToast(
msg: "Please choose a valid date range." ,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, '#dc1c13', '#dc1c13')",
);
return;
}
@ -335,13 +341,21 @@ class _GuestHouseState extends State<GuestHouse>
excelName,
);
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// backgroundColor: result['status'] ? Colors.green : Colors.red,
// content: Text(result['message']),
// behavior: SnackBarBehavior.floating,
// ),
// );
final String displayBackgroundColor = result['status'] ? '#28a745' : '#dc1c13';
final Color displayColor = result['status'] ? Colors.green : Colors.redAccent;
final String displayMessage = result['message'];
// final bool status = result['status'] == true;
Fluttertoast.showToast(
msg: displayMessage ,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: displayColor,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, $displayBackgroundColor, $displayBackgroundColor)",
);
}
void handleDomesticFilter(String query) {

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:core';
import 'dart:typed_data';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
@ -301,12 +302,16 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
if (textControllers["from_date"]!.text.isEmpty ||
textControllers["to_date"]!.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent,
content: Text("Please choose a valid date range."),
behavior: SnackBarBehavior.floating,
),
Fluttertoast.showToast(
msg: "Please choose a valid date range.",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, '#dc1c13', '#dc1c13')",
);
return;
}
@ -334,13 +339,21 @@ class _MISairState extends State<MISair> with SingleTickerProviderStateMixin {
excelName,
);
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// backgroundColor: result['status'] ? Colors.green : Colors.red,
// content: Text(result['message']),
// behavior: SnackBarBehavior.floating,
// ),
// );
final String displayBackgroundColor = result['status'] ? '#28a745' : '#dc1c13';
final Color displayColor = result['status'] ? Colors.green : Colors.redAccent;
final String displayMessage = result['message'];
// final bool status = result['status'] == true;
Fluttertoast.showToast(
msg: displayMessage ,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: displayColor,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, $displayBackgroundColor, $displayBackgroundColor)",
);
}
void handleDomesticFilter(String query) {

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:core';
import 'dart:typed_data';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
@ -262,12 +263,15 @@ class _MISforexState extends State<MISforex>
if (textControllers["from_date"]!.text.isEmpty ||
textControllers["to_date"]!.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent,
content: Text("Please choose a valid date range."),
behavior: SnackBarBehavior.floating,
),
Fluttertoast.showToast(
msg: "Please choose a valid date range.",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, '#dc1c13', '#dc1c13')",
);
return;
}
@ -295,13 +299,28 @@ class _MISforexState extends State<MISforex>
excelName,
);
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// backgroundColor: result['status'] ? Colors.green : Colors.red,
// content: Text(result['message']),
// behavior: SnackBarBehavior.floating,
// ),
// );
final String displayBackgroundColor = result['status'] ? '#28a745' : '#dc1c13';
final Color displayColor = result['status'] ? Colors.green : Colors.redAccent;
final String displayMessage = result['message'];
// final bool status = result['status'] == true;
Fluttertoast.showToast(
msg: displayMessage ,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: displayColor,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, $displayBackgroundColor, $displayBackgroundColor)",
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: result['status'] ? Colors.green : Colors.red,
content: Text(result['message']),
behavior: SnackBarBehavior.floating,
),
);
}
void handleInternationalFilter(String query) {

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:core';
import 'dart:typed_data';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
@ -302,12 +303,16 @@ class _MIShotelState extends State<MIShotel>
if (textControllers["from_date"]!.text.isEmpty ||
textControllers["to_date"]!.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent,
content: Text("Please choose a valid date range."),
behavior: SnackBarBehavior.floating,
),
Fluttertoast.showToast(
msg: "Please choose a valid date range.",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, '#dc1c13', '#dc1c13')",
);
return;
}
@ -335,13 +340,21 @@ class _MIShotelState extends State<MIShotel>
excelName,
);
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// backgroundColor: result['status'] ? Colors.green : Colors.red,
// content: Text(result['message']),
// behavior: SnackBarBehavior.floating,
// ),
// );
final String displayBackgroundColor = result['status'] ? '#28a745' : '#dc1c13';
final Color displayColor = result['status'] ? Colors.green : Colors.redAccent;
final String displayMessage = result['message'];
// final bool status = result['status'] == true;
Fluttertoast.showToast(
msg: displayMessage ,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: displayColor,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, $displayBackgroundColor, $displayBackgroundColor)",
);
}
void handleDomesticFilter(String query) {

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:core';
import 'dart:typed_data';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
@ -301,13 +302,17 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
if (textControllers["from_date"]!.text.isEmpty ||
textControllers["to_date"]!.text.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
backgroundColor: Colors.redAccent,
content: Text("Please choose a valid date range."),
behavior: SnackBarBehavior.floating,
),
Fluttertoast.showToast(
msg: "Please choose a valid date range.",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, '#dc1c13', '#dc1c13')",
);
return;
}
@ -334,13 +339,21 @@ class _ServicesAnalysisState extends State<ServicesAnalysis>
excelName,
);
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// backgroundColor: result['status'] ? Colors.green : Colors.red,
// content: Text(result['message']),
// behavior: SnackBarBehavior.floating,
// ),
// );
final String displayBackgroundColor = result['status'] ? '#28a745' : '#dc1c13';
final Color displayColor = result['status'] ? Colors.green : Colors.redAccent;
final String displayMessage = result['message'];
// final bool status = result['status'] == true;
Fluttertoast.showToast(
msg: displayMessage ,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: displayColor,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, $displayBackgroundColor, $displayBackgroundColor)",
);
}
void handleDomesticFilter(String query) {

View File

@ -1193,10 +1193,15 @@ class PersonalDetailsState extends State<PersonalDetails> {
countryList = apiCountryData ?? [];
// Map country codes to country names
// countryMap = {
// for (var item in countryList)
// item['country_code'] as String: item['country_name'] as String,
// // item['currency'] as String
// };
countryMap = {
for (var item in countryList)
item['country_code'] as String: item['country_name'] as String,
// item['currency'] as String
for (var country in countryList)
(country['country_code'] ?? ''):
'${country['country_name'] ?? ''} (${country['country_code'] ?? ''})',
};
// Extract only country codes for processing
@ -1229,16 +1234,44 @@ class PersonalDetailsState extends State<PersonalDetails> {
fit: FlexFit.loose, // Allows flexible height
menuProps: const MenuProps(backgroundColor: Colors.white),
itemBuilder:
(context, item, isSelected) => Container(
padding: EdgeInsets.symmetric(
horizontal: 10,
vertical: 6,
),
child: Text(
item,
style: GoogleFonts.poppins(fontSize: 11.5),
// (context, item, isSelected) => Container(
// padding: EdgeInsets.symmetric(
// horizontal: 10,
// vertical: 6,
// ),
// child: Text(
// item,
// style: GoogleFonts.poppins(fontSize: 11.5),
// ),
// ),
(context, item, isSelected) {
print("contryItem - $item");
final match = RegExp(r'^(.*)\s\((.*)\)$',).firstMatch(item);
final countryName = match?.group(1) ?? '';
final countryCode = match?.group(2) ?? '';
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8.0,
vertical: 6.0,
),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
countryName,
style: GoogleFonts.poppins(fontSize: 11.5),
),
Text(
countryCode,
style: GoogleFonts.poppins(fontSize: 11.5,color:Colors.grey),
),
],
),
),
);},
constraints: BoxConstraints(maxHeight: 200),
searchFieldProps: TextFieldProps(
decoration: InputDecoration(

View File

@ -1521,9 +1521,14 @@ class PersonalDetailsState extends State<PersonalDetails> {
Widget buildRole() {
// Map dropdown_key (ID) -> dropdown_value (Name)
// Map<String, String> roleMap = {
// for (var item in apiRoleData ?? [])
// item['dropdown_key'] as String: item['dropdown_value'] as String,
// };
Map<String, String> roleMap = {
for (var item in apiRoleData ?? [])
item['dropdown_key'] as String: item['dropdown_value'] as String,
if (item['dropdown_key'] != '5')
item['dropdown_key'].toString(): item['dropdown_value'].toString(),
};
List<String> roleNames = roleMap.values.toList();

View File

@ -1,5 +1,7 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:frontend/utils/auth_utils.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
@ -43,6 +45,9 @@ class _UserListScreenState extends State<UserListScreen> {
int currentPage = 0;
int itemsPerPage = 10;
bool _isUploading = false;
bool _isDownloading = false;
@override
void initState() {
super.initState();
@ -226,7 +231,7 @@ class _UserListScreenState extends State<UserListScreen> {
context: context,
builder: (context) => AlertDialog(
// title: Text("User Details"),
title: Text("User Details - $subtitle", style: TextStyle(fontWeight: FontWeight.bold)),
title: Text("Upload Status - $subtitle", style: TextStyle(fontWeight: FontWeight.bold)),
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -234,14 +239,14 @@ class _UserListScreenState extends State<UserListScreen> {
// Text(subtitle, style: TextStyle(fontWeight: FontWeight.bold)),
//
// SizedBox(height: 12),
Text("Users Created Successfully :", style: TextStyle(fontWeight: FontWeight.bold)),
Text("Success Report :", style: TextStyle(fontWeight: FontWeight.bold)),
if (successList.isNotEmpty)
...successList.asMap().entries.map((entry) => Text("${entry.key + 1}) ${entry.value} created."))
else
Text("-- There is no data to create. --"),
Text("-- no data. --"),
SizedBox(height: 12),
Text("Failed to Create Users :", style: TextStyle(fontWeight: FontWeight.bold)),
Text("Failed Report :", style: TextStyle(fontWeight: FontWeight.bold)),
if (failedList.isNotEmpty)
...failedList.asMap().entries.map((entry) {
final data = entry.value["data"] ?? "-";
@ -249,7 +254,7 @@ class _UserListScreenState extends State<UserListScreen> {
return Text("${entry.key + 1}) $data - unable to create due to \"$reason\".");
})
else
Text("-- There is no failed data. --"),
Text("-- no data. --"),
],
),
),
@ -267,7 +272,28 @@ class _UserListScreenState extends State<UserListScreen> {
}
Future<void> handleDownload() async {
final result = await apiService.getDownloadUserTemplateForUpload();
final String displayBackgroundColor = result['status'] ? '#28a745' : '#dc1c13';
final Color displayColor = result['status'] ? Colors.green : Colors.redAccent;
final String displayMessage = result['message'];
// final bool status = result['status'] == true;
Fluttertoast.showToast(
msg: displayMessage ,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: displayColor,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, $displayBackgroundColor, $displayBackgroundColor)",
);
}
Future<void> handleUpload() async {
final Completer<void> completer = Completer<void>();
final String apiUrldata = '$apiUrl/api/user/userUpload'; // api
final String? token = await getToken(); // 2kn
@ -287,16 +313,19 @@ class _UserListScreenState extends State<UserListScreen> {
await reader.onLoadEnd.first;
print(' file - extn : ${file.name.endsWith(".xlsx")}');
if (!file.name.endsWith('.xlsx')) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
// content: Text("Error: Not a valid Excel file "),
content: Text('Invalid file format. Please upload a .xlsx file.'),
backgroundColor: Colors.redAccent,
behavior: SnackBarBehavior.floating,
),
Fluttertoast.showToast(
msg: 'Invalid file format. Please upload a .xlsx file.',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, #dc1c13, #dc1c13)",
);
print("Error: Not a valid .xlsx file");
return;
completer.complete(); // Complete even on error
return; // Wait for upload to finish before proceeding
}
if (reader.readyState == html.FileReader.DONE) {
@ -309,13 +338,17 @@ class _UserListScreenState extends State<UserListScreen> {
if (fileBytes == null) {
print('File Bytes: null');
// ScaffoldMessenger.of(context).showSnackBar(
// SnackBar(
// content: Text("Issues Occur In Files"),
// backgroundColor: Colors.redAccent,
// behavior: SnackBarBehavior.floating,
// ),
// );
Fluttertoast.showToast(
msg: 'Issues occur in file format conversation',
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, #dc1c13, #dc1c13)",
);
completer.complete();
return; // No file selected
} else {
print('File Bytes: CALLING API');
@ -386,18 +419,22 @@ class _UserListScreenState extends State<UserListScreen> {
} else {
// For non-200 responses
final errorMsg = 'Failed to upload file: ${response.reasonPhrase}';
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(errorMsg),
backgroundColor: Colors.redAccent,
behavior: SnackBarBehavior.floating,
),
Fluttertoast.showToast(
msg: errorMsg,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 2,
backgroundColor: Colors.redAccent,
textColor: Colors.white,
fontSize: 18.0,
webBgColor: "linear-gradient(to right, #dc1c13, #dc1c13)",
);
print(errorMsg);
}
}
}
return completer.future; // Wait for upload to finish before proceeding
}
// if (!file.name.endsWith('.xlsx')) {
@ -747,7 +784,6 @@ class _UserListScreenState extends State<UserListScreen> {
},
),
SizedBox(width: 5),
// Upload Button
// OutlinedButton(
// onPressed: handleUpload,
@ -762,16 +798,39 @@ class _UserListScreenState extends State<UserListScreen> {
// ),
// child: Text("User Bulk Upload"),
// ),
IconButton(
icon: Image.asset(
'assets/images/IconsImg/upload.png',
width: 25,
height: 25,
// IconButton(
// icon: Image.asset(
// 'assets/images/IconsImg/upload.png',
// width: 25,
// height: 25,
// ),
// tooltip: 'User Bulk Upload',
// onPressed: () {
// handleUpload();
// },
// ),
// UPLOAD BUTTON
Align(
alignment: Alignment.centerLeft,
child: _isUploading
? const SizedBox(
width: 28,
height: 28,
child: CircularProgressIndicator(strokeWidth: 3),
)
: IconButton(
icon: Image.asset(
'assets/images/IconsImg/upload.png',
width: 25,
height: 25,
),
tooltip: 'User Bulk Upload',
onPressed: () async {
setState(() => _isUploading = true);
await handleUpload();
setState(() => _isUploading = false);
},
),
tooltip: 'User Bulk Upload',
onPressed: () {
handleUpload();
},
),
// Spacer(),
SizedBox(width: 5),

View File

@ -20,6 +20,8 @@ class OrganizationSettingState extends State<OrganizationSetting> {
final ApiService apiService = ApiService();
Color? layoutColor;
String? roleUser = "";
void initState() {
super.initState();
loadInitialData();
@ -28,7 +30,7 @@ class OrganizationSettingState extends State<OrganizationSetting> {
void loadInitialData() async {
String? layoutString = await getLayoutColor();
// String? bodyStringColor = await getBodyColor();
roleUser = await getRoleUser();
setState(() {
layoutColor =
layoutString != null
@ -103,7 +105,6 @@ class OrganizationSettingState extends State<OrganizationSetting> {
'label': 'Travel Policies',
'description': 'Create and Edit Travel Policy',
},
{
'value': '/getPerdiem',
'icon': Icons.attach_money,
@ -154,6 +155,10 @@ class OrganizationSettingState extends State<OrganizationSetting> {
},
];
if (roleUser == "Travel Admin") {
menuItems.removeWhere((item) => item['value'] == '/OrganizationSetup');
}
// List<Widget> rows = [];
// for (int i = 0; i < menuItems.length; i += cardsPerRow) {
// List<Widget> cards = [];

View File

@ -898,7 +898,7 @@ class ApiService {
}
// download the Template for bulk upload the user
Future<void> getDownloadUserTemplateForUpload() async {
Future<Map<String, dynamic>> getDownloadUserTemplateForUpload() async {
final String apiUrldata =
'$apiUrl/api/user/userUploadTemplate'; // download the Template for bulk upload user => api
@ -936,29 +936,14 @@ class ApiService {
// Revoke the download URL to free up resources
html.Url.revokeObjectUrl(url);
return {'status': true, 'message': 'Successfully Downloaded'};
} catch (e) {
throw Exception('Error parsing response: $e');
return {'status': false, 'message': 'Download error: $e'};
}
} else if (response.statusCode == 404) {
// showDialog(
// context: context,
// builder: (BuildContext context) {
// return AlertDialog(
// title: Text('File not found.'),
// // content: Text('File not found.'),
// actions: [
// TextButton(
// child: Text('OK'),
// onPressed: () {
// Navigator.of(context).pop(); // Close the dialog
// },
// ),
// ],
// );
// },
// );
return {'status': false, 'message': 'File not found (404).'};
} else {
throw Exception('Failed to load plans');
return {'status': false, 'message': 'Failed to download. Try again.'};
}
}
@ -1056,7 +1041,7 @@ class ApiService {
// ---
Future<Map<String, dynamic>> getDepartmentDetailsFind(int id) async {
final String apiUrldata = '$apiUrl/api/findDepartment?department_id=$id';
final String apiUrldata = '$apiUrl/api/findDepartment?id=$id';
final token = await getToken();
@ -1560,11 +1545,7 @@ class ApiService {
}
}
Future<void> 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)
@ -1607,14 +1588,18 @@ class ApiService {
// Revoke the download URL to free up resources
html.Url.revokeObjectUrl(url);
throw Exception('Sucessfully Downloaded');
// throw Exception('Sucessfully Downloaded');
return {'status': true, 'message': 'Successfully Downloaded'};
} catch (e) {
throw Exception('Error parsing response: $e');
// throw Exception('Error parsing response: $e');
return {'status': false, 'message': 'Download error: $e'};
}
} else if (response.statusCode == 404) {
throw Exception('File not found.');
// throw Exception('File not found.');
return {'status': false, 'message': 'File not found (404).'};
} else {
throw Exception('Failed to Download');
// throw Exception('Failed to Download');
return {'status': false, 'message': 'Failed to download. Try again.'};
}
}

View File

@ -40,25 +40,25 @@ class UserActionsMenu extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
child: Tooltip(
message: 'View Details',
child: Icon(Icons.remove_red_eye,
color: Color(0xFF475569), size: 18)
),
// child: Icon(Icons.remove_red_eye,
// color: Color(0xFF475569), size: 18,),
onTap: () async {
Navigator.pop(context); // Close the menu
final userId = getUserId(user['user_id']);
final usersData = await getUserDetails(userId);
context.go("/CreateTravelAgent", extra: {
"selectedUser": usersData,
"isViewMode": true,
});
},
),
SizedBox(width: 8),
// GestureDetector(
// child: Tooltip(
// message: 'View Details',
// child: Icon(Icons.remove_red_eye,
// color: Color(0xFF475569), size: 18)
// ),
// // child: Icon(Icons.remove_red_eye,
// // color: Color(0xFF475569), size: 18,),
// onTap: () async {
// Navigator.pop(context); // Close the menu
// final userId = getUserId(user['user_id']);
// final usersData = await getUserDetails(userId);
// context.go("/CreateTravelAgent", extra: {
// "selectedUser": usersData,
// "isViewMode": true,
// });
// },
// ),
// SizedBox(width: 8),
GestureDetector(
child: Tooltip(
message: 'Edit Details',

View File

@ -40,25 +40,25 @@ class UserActionsMenu extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
GestureDetector(
child: Tooltip(
message: 'View Details',
child: Icon(Icons.remove_red_eye,
color: Color(0xFF475569), size: 18)
),
// child: Icon(Icons.remove_red_eye,
// color: Color(0xFF475569), size: 18,),
onTap: () async {
Navigator.pop(context); // Close the menu
final userId = getUserId(user['user_id']);
final usersData = await getUserDetails(userId);
context.go("/CreateUserDetails", extra: {
"selectedUser": usersData,
"isViewMode": true,
});
},
),
SizedBox(width: 8),
// GestureDetector(
// child: Tooltip(
// message: 'View Details',
// child: Icon(Icons.remove_red_eye,
// color: Color(0xFF475569), size: 18)
// ),
// // child: Icon(Icons.remove_red_eye,
// // color: Color(0xFF475569), size: 18,),
// onTap: () async {
// Navigator.pop(context); // Close the menu
// final userId = getUserId(user['user_id']);
// final usersData = await getUserDetails(userId);
// context.go("/CreateUserDetails", extra: {
// "selectedUser": usersData,
// "isViewMode": true,
// });
// },
// ),
// SizedBox(width: 8),
GestureDetector(
child: Tooltip(
message: 'Edit Details',