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 ?? []; countryList = apiCountryData ?? [];
// Map country codes to country names // Map country codes to country names
// countryMap = {
// for (var item in countryList)
// item['country_code'] as String: item['country_name'] as String,
// };
countryMap = { countryMap = {
for (var item in countryList) for (var country in countryList)
item['country_code'] as String: item['country_name'] as String, (country['country_code'] ?? ''):
'${country['country_name'] ?? ''} (${country['country_code'] ?? ''})',
}; };
// Extract only country codes for processing // Extract only country codes for processing
@ -482,16 +488,34 @@ class HotelsDataState extends State<HotelsData> {
menuProps: const MenuProps(backgroundColor: Colors.white), menuProps: const MenuProps(backgroundColor: Colors.white),
constraints: BoxConstraints(maxHeight: 200), constraints: BoxConstraints(maxHeight: 200),
itemBuilder: 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( padding: const EdgeInsets.symmetric(
horizontal: 10.0, horizontal: 8.0,
vertical: 8.0, vertical: 6.0,
), ),
child: Text( child: Padding(
item, padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
countryName,
style: GoogleFonts.poppins(fontSize: 11.5), style: GoogleFonts.poppins(fontSize: 11.5),
), ),
Text(
countryCode,
style: GoogleFonts.poppins(fontSize: 11.5,color:Colors.grey),
), ),
],
),
),
);},
searchFieldProps: TextFieldProps( searchFieldProps: TextFieldProps(
decoration: InputDecoration( decoration: InputDecoration(
hintText: "Search ...", hintText: "Search ...",

View File

@ -346,9 +346,15 @@ class ForexDataState extends State<ForexData> {
countryList = apiCountryData ?? []; countryList = apiCountryData ?? [];
// Map country codes to country names // Map country codes to country names
// countryMap = {
// for (var item in countryList)
// item['country_code'] as String: item['country_name'] as String,
// };
countryMap = { countryMap = {
for (var item in countryList) for (var country in countryList)
item['country_code'] as String: item['country_name'] as String, (country['country_code'] ?? ''):
'${country['country_name'] ?? ''} (${country['country_code'] ?? ''})',
}; };
// Extract only country codes for processing // Extract only country codes for processing
@ -426,18 +432,35 @@ class ForexDataState extends State<ForexData> {
popupProps: PopupProps.menu( popupProps: PopupProps.menu(
showSearchBox: true, // Enables search functionality showSearchBox: true, // Enables search functionality
menuProps: const MenuProps(backgroundColor: Colors.white), menuProps: const MenuProps(backgroundColor: Colors.white),
constraints: BoxConstraints(maxHeight: 250), constraints: BoxConstraints(maxHeight: 200),
itemBuilder: 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( padding: const EdgeInsets.symmetric(
horizontal: 10.0, horizontal: 8.0,
vertical: 8.0, vertical: 6.0,
), ),
child: Text( child: Padding(
item, padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
countryName,
style: GoogleFonts.poppins(fontSize: 11.5), style: GoogleFonts.poppins(fontSize: 11.5),
), ),
Text(
countryCode,
style: GoogleFonts.poppins(fontSize: 11.5,color:Colors.grey),
), ),
],
),
),
);},
searchFieldProps: TextFieldProps( searchFieldProps: TextFieldProps(
decoration: InputDecoration( decoration: InputDecoration(
hintText: "Search ...", hintText: "Search ...",
@ -495,10 +518,87 @@ class ForexDataState extends State<ForexData> {
.firstWhere((entry) => entry.value == newValue) .firstWhere((entry) => entry.value == newValue)
.key; .key;
selectedCountryName = newValue; 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( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ // children: [
Text( // Text(
"Choose Policy Type", // "Choose Policy Type",
style: GoogleFonts.poppins( // style: GoogleFonts.poppins(
fontSize: 12, // fontSize: 12,
fontWeight: FontWeight.w600, // fontWeight: FontWeight.w600,
color: Color(0xFF575A74), // color: Color(0xFF575A74),
), // ),
), // ),
], // ],
), ),
), ),
], ],

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1521,9 +1521,14 @@ class PersonalDetailsState extends State<PersonalDetails> {
Widget buildRole() { Widget buildRole() {
// Map dropdown_key (ID) -> dropdown_value (Name) // 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 = { Map<String, String> roleMap = {
for (var item in apiRoleData ?? []) 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(); List<String> roleNames = roleMap.values.toList();

View File

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

View File

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

View File

@ -898,7 +898,7 @@ class ApiService {
} }
// download the Template for bulk upload the user // download the Template for bulk upload the user
Future<void> getDownloadUserTemplateForUpload() async { Future<Map<String, dynamic>> getDownloadUserTemplateForUpload() async {
final String apiUrldata = final String apiUrldata =
'$apiUrl/api/user/userUploadTemplate'; // download the Template for bulk upload user => api '$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 // Revoke the download URL to free up resources
html.Url.revokeObjectUrl(url); html.Url.revokeObjectUrl(url);
return {'status': true, 'message': 'Successfully Downloaded'};
} catch (e) { } catch (e) {
throw Exception('Error parsing response: $e'); return {'status': false, 'message': 'Download error: $e'};
} }
} else if (response.statusCode == 404) { } else if (response.statusCode == 404) {
// showDialog( return {'status': false, 'message': 'File not found (404).'};
// 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
// },
// ),
// ],
// );
// },
// );
} else { } 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 { 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(); final token = await getToken();
@ -1560,11 +1545,7 @@ class ApiService {
} }
} }
Future<void> reportExcelDownload( Future<Map<String, dynamic>> reportExcelDownload(String apiRoute,String body,String name,) async {
String apiRoute,
String body,
String name,
) async {
final String apiUrldata = '$apiUrl/api/$apiRoute'; final String apiUrldata = '$apiUrl/api/$apiRoute';
// Sanitize name for filename (optional) // Sanitize name for filename (optional)
@ -1607,14 +1588,18 @@ class ApiService {
// Revoke the download URL to free up resources // Revoke the download URL to free up resources
html.Url.revokeObjectUrl(url); html.Url.revokeObjectUrl(url);
throw Exception('Sucessfully Downloaded'); // throw Exception('Sucessfully Downloaded');
return {'status': true, 'message': 'Successfully Downloaded'};
} catch (e) { } 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) { } else if (response.statusCode == 404) {
throw Exception('File not found.'); // throw Exception('File not found.');
return {'status': false, 'message': 'File not found (404).'};
} else { } 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, mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
GestureDetector( // GestureDetector(
child: Tooltip( // child: Tooltip(
message: 'View Details', // message: 'View Details',
child: Icon(Icons.remove_red_eye,
color: Color(0xFF475569), size: 18)
),
// child: Icon(Icons.remove_red_eye, // child: Icon(Icons.remove_red_eye,
// color: Color(0xFF475569), size: 18,), // color: Color(0xFF475569), size: 18)
onTap: () async { // ),
Navigator.pop(context); // Close the menu // // child: Icon(Icons.remove_red_eye,
final userId = getUserId(user['user_id']); // // color: Color(0xFF475569), size: 18,),
final usersData = await getUserDetails(userId); // onTap: () async {
context.go("/CreateTravelAgent", extra: { // Navigator.pop(context); // Close the menu
"selectedUser": usersData, // final userId = getUserId(user['user_id']);
"isViewMode": true, // final usersData = await getUserDetails(userId);
}); // context.go("/CreateTravelAgent", extra: {
}, // "selectedUser": usersData,
), // "isViewMode": true,
SizedBox(width: 8), // });
// },
// ),
// SizedBox(width: 8),
GestureDetector( GestureDetector(
child: Tooltip( child: Tooltip(
message: 'Edit Details', message: 'Edit Details',

View File

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