BUGFIX_USER_MNGMT
This commit is contained in:
parent
186a07d126
commit
80db60c39c
@ -509,7 +509,8 @@ class _ApprovalListState extends State<ApprovalList> {
|
|||||||
|
|
||||||
Future<void> _showDetails(id) async {
|
Future<void> _showDetails(id) async {
|
||||||
_dialogShown = true;
|
_dialogShown = true;
|
||||||
final String apiUrldata = '$apiUrl/api/plans/get_plan_approval_status?plan_id=$id';
|
final String apiUrldata =
|
||||||
|
'$apiUrl/api/plans/get_plan_approval_status?plan_id=$id';
|
||||||
final String? token = await getToken();
|
final String? token = await getToken();
|
||||||
String label = "";
|
String label = "";
|
||||||
List<Map<String, dynamic>> approverData = [];
|
List<Map<String, dynamic>> approverData = [];
|
||||||
@ -530,7 +531,9 @@ class _ApprovalListState extends State<ApprovalList> {
|
|||||||
if (response.statusCode == 200) {
|
if (response.statusCode == 200) {
|
||||||
final data = json.decode(response.body);
|
final data = json.decode(response.body);
|
||||||
label = data['data']['model_heading'] ?? "";
|
label = data['data']['model_heading'] ?? "";
|
||||||
approverData = List<Map<String, dynamic>>.from(data['data']['approver_data'] ?? []);
|
approverData = List<Map<String, dynamic>>.from(
|
||||||
|
data['data']['approver_data'] ?? [],
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
print('Failed to load');
|
print('Failed to load');
|
||||||
label = "Error - Failed to load data";
|
label = "Error - Failed to load data";
|
||||||
@ -543,76 +546,104 @@ class _ApprovalListState extends State<ApprovalList> {
|
|||||||
|
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => AlertDialog(
|
builder:
|
||||||
title: Text(
|
(context) => AlertDialog(
|
||||||
label,
|
title: Text(
|
||||||
style: GoogleFonts.poppins(
|
label,
|
||||||
fontSize: 18,
|
style: GoogleFonts.poppins(
|
||||||
fontWeight: FontWeight.w600,
|
fontSize: 18,
|
||||||
color: Colors.black,
|
fontWeight: FontWeight.w600,
|
||||||
),
|
color: Colors.black,
|
||||||
overflow: TextOverflow.ellipsis,
|
),
|
||||||
),
|
overflow: TextOverflow.ellipsis,
|
||||||
content: SingleChildScrollView(
|
),
|
||||||
child: Column(
|
content: SingleChildScrollView(
|
||||||
mainAxisSize: MainAxisSize.min,
|
child: Column(
|
||||||
children: [
|
mainAxisSize: MainAxisSize.min,
|
||||||
if (approverData.isNotEmpty)
|
children: [
|
||||||
SizedBox(
|
if (approverData.isNotEmpty)
|
||||||
height: 250,
|
SizedBox(
|
||||||
child: SingleChildScrollView(
|
height: 250,
|
||||||
scrollDirection: Axis.horizontal,
|
child: SingleChildScrollView(
|
||||||
child: SingleChildScrollView(
|
scrollDirection: Axis.horizontal,
|
||||||
scrollDirection: Axis.vertical,
|
child: SingleChildScrollView(
|
||||||
child: DataTable(
|
scrollDirection: Axis.vertical,
|
||||||
columns: [
|
child: DataTable(
|
||||||
// DataColumn(label: Text('S.No', style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w600))),
|
columns: [
|
||||||
// DataColumn(label: Text('Approver ID', style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w600))),
|
// DataColumn(label: Text('S.No', style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w600))),
|
||||||
DataColumn(label: Text('Status', style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w600))),
|
// DataColumn(label: Text('Approver ID', style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w600))),
|
||||||
],
|
DataColumn(
|
||||||
rows: approverData.asMap().entries.map((entry) {
|
label: Text(
|
||||||
final index = entry.key + 1;
|
'Status',
|
||||||
final item = entry.value;
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 14,
|
||||||
final approverIdKey = item.keys.firstWhere((k) => k.endsWith('_id'), orElse: () => '');
|
fontWeight: FontWeight.w600,
|
||||||
final statusKey = item.keys.firstWhere((k) => k.endsWith('_status'), orElse: () => '');
|
),
|
||||||
|
),
|
||||||
final approverId = item[approverIdKey]?.toString() ?? '-';
|
),
|
||||||
final statusText = item[statusKey]?.toString() ?? 'Unknown';
|
|
||||||
|
|
||||||
return DataRow(
|
|
||||||
cells: [
|
|
||||||
// DataCell(Text('$index')),
|
|
||||||
// DataCell(SizedBox(width: 120, child: Text(approverId, overflow: TextOverflow.ellipsis))),
|
|
||||||
DataCell(SizedBox(child: Text(statusText, overflow: TextOverflow.ellipsis))),
|
|
||||||
],
|
],
|
||||||
);
|
rows:
|
||||||
}).toList(),
|
approverData.asMap().entries.map((entry) {
|
||||||
|
final index = entry.key + 1;
|
||||||
|
final item = entry.value;
|
||||||
|
|
||||||
|
final approverIdKey = item.keys.firstWhere(
|
||||||
|
(k) => k.endsWith('_id'),
|
||||||
|
orElse: () => '',
|
||||||
|
);
|
||||||
|
final statusKey = item.keys.firstWhere(
|
||||||
|
(k) => k.endsWith('_status'),
|
||||||
|
orElse: () => '',
|
||||||
|
);
|
||||||
|
|
||||||
|
final approverId =
|
||||||
|
item[approverIdKey]?.toString() ?? '-';
|
||||||
|
final statusText =
|
||||||
|
item[statusKey]?.toString() ?? 'Unknown';
|
||||||
|
|
||||||
|
return DataRow(
|
||||||
|
cells: [
|
||||||
|
// DataCell(Text('$index')),
|
||||||
|
// DataCell(SizedBox(width: 120, child: Text(approverId, overflow: TextOverflow.ellipsis))),
|
||||||
|
DataCell(
|
||||||
|
SizedBox(
|
||||||
|
child: Text(
|
||||||
|
statusText,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
else
|
||||||
|
Text(
|
||||||
|
"-- no data. --",
|
||||||
|
style: GoogleFonts.poppins(
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: FontWeight.w300,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
)
|
),
|
||||||
else
|
),
|
||||||
Text("-- no data. --", style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w300)),
|
actions: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.pop(context);
|
||||||
|
_dialogShown = false;
|
||||||
|
},
|
||||||
|
child: Text("Close"),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
Navigator.pop(context);
|
|
||||||
_dialogShown = false;
|
|
||||||
},
|
|
||||||
child: Text("Close"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ResponsiveBuilder(
|
return ResponsiveBuilder(
|
||||||
builder: (context, sizingInfo) {
|
builder: (context, sizingInfo) {
|
||||||
@ -688,7 +719,10 @@ class _ApprovalListState extends State<ApprovalList> {
|
|||||||
|
|
||||||
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
|
||||||
@ -788,10 +822,10 @@ class _ApprovalListState extends State<ApprovalList> {
|
|||||||
isDesktop
|
isDesktop
|
||||||
? SizedBox.shrink()
|
? SizedBox.shrink()
|
||||||
: Row(
|
: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Container(
|
Container(
|
||||||
width: MediaQuery.of(context).size.width * 0.8,
|
width: MediaQuery.of(context).size.width * 0.82,
|
||||||
height: 35,
|
height: 35,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
controller: searchController,
|
controller: searchController,
|
||||||
@ -858,7 +892,8 @@ class _ApprovalListState extends State<ApprovalList> {
|
|||||||
// fontWeight: FontWeight.bold,
|
// fontWeight: FontWeight.bold,
|
||||||
// color: Colors.redAccent)),
|
// color: Colors.redAccent)),
|
||||||
SizedBox(height: adjHgt / 4),
|
SizedBox(height: adjHgt / 4),
|
||||||
Text("No Data Found",
|
Text(
|
||||||
|
"No Data Found",
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: GoogleFonts.poppins(
|
style: GoogleFonts.poppins(
|
||||||
fontSize: 20,
|
fontSize: 20,
|
||||||
@ -1138,14 +1173,20 @@ class _ApprovalListState extends State<ApprovalList> {
|
|||||||
height: 25,
|
height: 25,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: getStatusColor(plan.statusValue),
|
color: getStatusColor(
|
||||||
borderRadius: BorderRadius.circular(8),
|
plan.statusValue,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
8,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
plan.statusValue,
|
plan.statusValue,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: getStatusTextColor(plan.statusValue),
|
color: getStatusTextColor(
|
||||||
|
plan.statusValue,
|
||||||
|
),
|
||||||
fontSize: 12,
|
fontSize: 12,
|
||||||
fontFamily: "Inter",
|
fontFamily: "Inter",
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
@ -1412,8 +1453,12 @@ class _ApprovalListState extends State<ApprovalList> {
|
|||||||
vertical: 4,
|
vertical: 4,
|
||||||
),
|
),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: getStatusColor(plan.statusValue),
|
color: getStatusColor(
|
||||||
borderRadius: BorderRadius.circular(8),
|
plan.statusValue,
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.circular(
|
||||||
|
8,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
plan.statusValue,
|
plan.statusValue,
|
||||||
|
|||||||
@ -31,7 +31,10 @@ class _ColorThemePickerWidgetState extends State<ColorThemePickerWidget> {
|
|||||||
Color(0xFF448AFF), // BlueAccent
|
Color(0xFF448AFF), // BlueAccent
|
||||||
Color(0xFF027E87), // Blue Shade
|
Color(0xFF027E87), // Blue Shade
|
||||||
Color(0xFF12B24B), // Green
|
Color(0xFF12B24B), // Green
|
||||||
Color(0xFF2ECC71), // Emerald Green
|
Color(0xFFe30f01), // Emerald Green
|
||||||
|
// Color(0xFFef3030), // Emerald Green
|
||||||
|
Color(0xFFf26157), // Emerald Green
|
||||||
|
// Color(0xFF2ECC71), // Emerald Green
|
||||||
Color(0xFFFF9800), // Orange
|
Color(0xFFFF9800), // Orange
|
||||||
Color(0xFFE67E22), // Orange 2
|
Color(0xFFE67E22), // Orange 2
|
||||||
Color(0xFFBF4C0D), // Orange dark orange 3
|
Color(0xFFBF4C0D), // Orange dark orange 3
|
||||||
|
|||||||
@ -61,10 +61,10 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
|
|
||||||
bool isCheckingToken = false;
|
bool isCheckingToken = false;
|
||||||
bool isDisable = false;
|
bool isDisable = false;
|
||||||
|
bool isValid = false;
|
||||||
|
|
||||||
final FocusNode submitButtonFocusNode = FocusNode();
|
final FocusNode submitButtonFocusNode = FocusNode();
|
||||||
|
|
||||||
|
|
||||||
String? token;
|
String? token;
|
||||||
|
|
||||||
late bool isapiselectedUser = false;
|
late bool isapiselectedUser = false;
|
||||||
@ -180,7 +180,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
"first_approver": selectedFirstApprover,
|
"first_approver": selectedFirstApprover,
|
||||||
"second_approver": selectedSecondApprover,
|
"second_approver": selectedSecondApprover,
|
||||||
"third_approver": selectedThirdApprover,
|
"third_approver": selectedThirdApprover,
|
||||||
"exceptional_approver" : selectedExceptionalApprover,
|
"exceptional_approver": selectedExceptionalApprover,
|
||||||
"delegated_to_user_id": selectedSubstituteApprover,
|
"delegated_to_user_id": selectedSubstituteApprover,
|
||||||
// "passport_number": controllers["passportNumber"]?.text,
|
// "passport_number": controllers["passportNumber"]?.text,
|
||||||
// "place_of_issue": controllers["placeOfIssue"]?.text,
|
// "place_of_issue": controllers["placeOfIssue"]?.text,
|
||||||
@ -784,9 +784,10 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
|
|
||||||
final currentTab = tabKeys[currentIndex];
|
final currentTab = tabKeys[currentIndex];
|
||||||
if (currentTab == "personal") {
|
if (currentTab == "personal") {
|
||||||
isValid = isValidData(userDetials);
|
// isValid = isValidData(userDetials);
|
||||||
|
isValid = await isValidData(userDetials);
|
||||||
} else if (currentTab == "office") {
|
} else if (currentTab == "office") {
|
||||||
isValid = isValidDataTwo(userDetials);
|
isValid = await isValidDataTwo(userDetials);
|
||||||
} else {
|
} else {
|
||||||
isValid = true; // Travel tab might not need validation at this point
|
isValid = true; // Travel tab might not need validation at this point
|
||||||
}
|
}
|
||||||
@ -827,7 +828,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
Map<String, dynamic> data = userDetials;
|
Map<String, dynamic> data = userDetials;
|
||||||
|
|
||||||
print("userDetials ====> $userDetials");
|
print("userDetials ====> $userDetials");
|
||||||
if (!isValidData(data)) {
|
if (!await isValidData(data)) {
|
||||||
print("USERDETAILS : $userDetials");
|
print("USERDETAILS : $userDetials");
|
||||||
print("Validation Failed: Required fields are missing.");
|
print("Validation Failed: Required fields are missing.");
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@ -942,7 +943,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
|
|
||||||
// Map<String, dynamic> data = userDetials;
|
// Map<String, dynamic> data = userDetials;
|
||||||
|
|
||||||
if (!isValidData(data) && isValidDataTwo(data)) {
|
if (!await isValidData(data) && !await isValidDataTwo(data)) {
|
||||||
print("USERDETAILS : $userDetials");
|
print("USERDETAILS : $userDetials");
|
||||||
print("Validation Failed: Required fields are missing.");
|
print("Validation Failed: Required fields are missing.");
|
||||||
setState(() {});
|
setState(() {});
|
||||||
@ -958,7 +959,72 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
if (mounted) Navigator.of(context, rootNavigator: true).pop();
|
if (mounted) Navigator.of(context, rootNavigator: true).pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValidData(Map<String, dynamic> data) {
|
// Future<bool> apiCheckDuplicate(
|
||||||
|
// String label,
|
||||||
|
// String field,
|
||||||
|
// String value,
|
||||||
|
// String? userId,
|
||||||
|
// ) async
|
||||||
|
// {
|
||||||
|
// try {
|
||||||
|
// // Basic validation: Check mobile number length
|
||||||
|
// if (field == "mobile_no" && value.length != 10) {
|
||||||
|
// return true; // Skip the API call if input is invalid
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// final response = await apiService.CheckDuplicate(
|
||||||
|
// label,
|
||||||
|
// field,
|
||||||
|
// value,
|
||||||
|
// userId,
|
||||||
|
// );
|
||||||
|
// if (response.isNotEmpty) {
|
||||||
|
// // _clearError(field);
|
||||||
|
// errorMessages[field] = response['message'] ?? "$label Already Exists";
|
||||||
|
// print("Duplicate found: ${response['message']}");
|
||||||
|
//
|
||||||
|
// setState(() {});
|
||||||
|
// return true;
|
||||||
|
// } else {
|
||||||
|
// _clearError(field);
|
||||||
|
// print("No duplicates found.");
|
||||||
|
//
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// print("Error in checkDuplicate: $e");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
Future<bool> apiCheckDuplicate(
|
||||||
|
String label,
|
||||||
|
String field,
|
||||||
|
String value,
|
||||||
|
String? userId,
|
||||||
|
) {
|
||||||
|
return apiService.CheckDuplicate(label, field, value, userId)
|
||||||
|
.then((response) {
|
||||||
|
if (response.isNotEmpty) {
|
||||||
|
errorMessages[field] =
|
||||||
|
response['message'] ?? "$label Already Exists";
|
||||||
|
print("Duplicate found: ${response['message']}");
|
||||||
|
// setState(() {});
|
||||||
|
print("Duplicate found: true");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
_clearError(field);
|
||||||
|
print("No duplicates found.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catchError((e) {
|
||||||
|
print("Error in checkDuplicate: $e");
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> isValidData(Map<String, dynamic> data) async {
|
||||||
errorMessages.clear(); // Reset errors
|
errorMessages.clear(); // Reset errors
|
||||||
|
|
||||||
// Required fields that must not be empty
|
// Required fields that must not be empty
|
||||||
@ -987,7 +1053,43 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
if (!RegExp(r"^\d{10}$").hasMatch(data["mobile_no"].toString())) {
|
if (!RegExp(r"^\d{10}$").hasMatch(data["mobile_no"].toString())) {
|
||||||
errorMessages["mobile_no"] =
|
errorMessages["mobile_no"] =
|
||||||
"Enter 10 digits"; // Invalid mobile number format
|
"Enter 10 digits"; // Invalid mobile number format
|
||||||
|
} else {
|
||||||
|
bool isDuplicate = await apiCheckDuplicate(
|
||||||
|
"Mobile Number",
|
||||||
|
"mobile_no",
|
||||||
|
data["mobile_no"]!,
|
||||||
|
userIdApi,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDuplicate) {
|
||||||
|
print("REsduplica1 - $isDuplicate");
|
||||||
|
errorMessages["mobile_no"] = "Mobile Number already exist";
|
||||||
|
// errorMessages is already updated inside apiCheckDuplicate
|
||||||
|
// setState(() {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// else {
|
||||||
|
// apiCheckDuplicate(
|
||||||
|
// "Mobile Number",
|
||||||
|
// "mobile_no",
|
||||||
|
// data["mobile_no"]!,
|
||||||
|
// userIdApi,
|
||||||
|
// ).then((isDuplicate) {
|
||||||
|
// print("REsduplica - $isDuplicate");
|
||||||
|
//
|
||||||
|
// if (isDuplicate) {
|
||||||
|
// print("REsduplica1 - $isDuplicate");
|
||||||
|
// errorMessages["mobile_no"] = "Mobile Number Already Exist";
|
||||||
|
// // errorMessages is already updated inside apiCheckDuplicate
|
||||||
|
// // setState(() {});
|
||||||
|
// } else {
|
||||||
|
// // Optional: do something if no duplicate found
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// // errorMessages["mobile_no"] = "Mobile Number already exist";
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data["alternate_mobile_no"] != null &&
|
if (data["alternate_mobile_no"] != null &&
|
||||||
@ -1006,12 +1108,43 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",
|
r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",
|
||||||
).hasMatch(data["email"].toString())) {
|
).hasMatch(data["email"].toString())) {
|
||||||
errorMessages["email"] = "Invalid email format"; // Invalid email format
|
errorMessages["email"] = "Invalid email format"; // Invalid email format
|
||||||
|
} else {
|
||||||
|
bool isDuplicate = await apiCheckDuplicate(
|
||||||
|
"Email",
|
||||||
|
"email",
|
||||||
|
data["email"]!,
|
||||||
|
userIdApi,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDuplicate) {
|
||||||
|
errorMessages["email"] = "Email already exist";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// else {
|
||||||
|
// apiCheckDuplicate("Email", "email", data["email"]!, userIdApi).then((
|
||||||
|
// isDuplicate,
|
||||||
|
// ) {
|
||||||
|
// print("REsduplica - $isDuplicate");
|
||||||
|
//
|
||||||
|
// if (isDuplicate) {
|
||||||
|
// print("REsduplica1 - $isDuplicate");
|
||||||
|
// errorMessages["email"] = "Email Already Exist";
|
||||||
|
// // errorMessages is already updated inside apiCheckDuplicate
|
||||||
|
// // setState(() {});
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// // errorMessages["mobile_no"] = "Mobile Number already exist";
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print("ISEMPTY");
|
||||||
|
|
||||||
return errorMessages.isEmpty; // Valid if there are no errors
|
return errorMessages.isEmpty; // Valid if there are no errors
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isValidDataTwo(Map<String, dynamic> data) {
|
Future<bool> isValidDataTwo(Map<String, dynamic> data) async {
|
||||||
errorMessages.clear(); // Reset errors
|
errorMessages.clear(); // Reset errors
|
||||||
|
|
||||||
// Required fields that must not be empty
|
// Required fields that must not be empty
|
||||||
@ -1021,6 +1154,20 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
for (String field in requiredFields) {
|
for (String field in requiredFields) {
|
||||||
if (data[field] == null || data[field].toString().trim().isEmpty) {
|
if (data[field] == null || data[field].toString().trim().isEmpty) {
|
||||||
errorMessages[field] = "Required";
|
errorMessages[field] = "Required";
|
||||||
|
} else {
|
||||||
|
bool isDuplicate = await apiCheckDuplicate(
|
||||||
|
"Employee Code",
|
||||||
|
"employee_code",
|
||||||
|
data["employee_code"]!,
|
||||||
|
userIdApi,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isDuplicate) {
|
||||||
|
print("REsduplica1 - $isDuplicate");
|
||||||
|
errorMessages["employee_code"] = "Employee Code already exist";
|
||||||
|
// errorMessages is already updated inside apiCheckDuplicate
|
||||||
|
// setState(() {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1364,26 +1511,27 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
children: [
|
children: [
|
||||||
if (apiselectedUser != null)
|
if (apiselectedUser != null)
|
||||||
isEditProfile
|
isEditProfile
|
||||||
? Text( "Profile",
|
? Text(
|
||||||
style: GoogleFonts.poppins(
|
"Profile",
|
||||||
fontSize: isDesktop ? 15 : 12,
|
style: GoogleFonts.poppins(
|
||||||
fontWeight: FontWeight.w600,
|
fontSize: isDesktop ? 15 : 12,
|
||||||
color: Colors.black,
|
fontWeight: FontWeight.w600,
|
||||||
),
|
color: Colors.black,
|
||||||
)
|
),
|
||||||
|
)
|
||||||
: BreadcrumbNavigation(
|
: BreadcrumbNavigation(
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
breadcrumbItems: [
|
breadcrumbItems: [
|
||||||
BreadcrumbItem(
|
BreadcrumbItem(
|
||||||
title: 'Users',
|
title: 'Users',
|
||||||
tooltip: 'Go To Users',
|
tooltip: 'Go To Users',
|
||||||
onTap: (context) {
|
onTap: (context) {
|
||||||
context.go("/listUser");
|
context.go("/listUser");
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
BreadcrumbItem(title: 'Edit User'),
|
BreadcrumbItem(title: 'Edit User'),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
BreadcrumbNavigation(
|
BreadcrumbNavigation(
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
@ -1584,28 +1732,37 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
setState(() {
|
setState(() async {
|
||||||
bool isValid = false;
|
bool isValid = false;
|
||||||
|
|
||||||
final currentTab = selectedTab;
|
final currentTab = selectedTab;
|
||||||
if (currentTab == "personal") {
|
if (currentTab == "personal") {
|
||||||
isValid = isValidData(userDetials);
|
// isValid = isValidData(userDetials);
|
||||||
|
isValid = await isValidData(userDetials);
|
||||||
|
|
||||||
if (isValid) {
|
if (isValid) {
|
||||||
selectedTab = entry.key;
|
setState(() {
|
||||||
|
selectedTab = entry.key;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else if (currentTab == "office" &&
|
} else if (currentTab == "office" &&
|
||||||
targetTab == "personal") {
|
targetTab == "personal") {
|
||||||
selectedTab = entry.key;
|
setState(() {
|
||||||
} else if (currentTab == "office") {
|
|
||||||
isValid = isValidDataTwo(userDetials);
|
|
||||||
if (isValid) {
|
|
||||||
selectedTab = entry.key;
|
selectedTab = entry.key;
|
||||||
|
});
|
||||||
|
} else if (currentTab == "office") {
|
||||||
|
isValid = await isValidDataTwo(userDetials);
|
||||||
|
if (isValid) {
|
||||||
|
setState(() {
|
||||||
|
selectedTab = entry.key;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
isValid =
|
isValid =
|
||||||
true; // Travel tab might not need validation at this point
|
true; // Travel tab might not need validation at this point
|
||||||
selectedTab = entry.key;
|
setState(() {
|
||||||
|
selectedTab = entry.key;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -1759,12 +1916,15 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
|||||||
isViewMode
|
isViewMode
|
||||||
? SystemMouseCursors.forbidden
|
? SystemMouseCursors.forbidden
|
||||||
: SystemMouseCursors.click,
|
: SystemMouseCursors.click,
|
||||||
child: Focus( // 👈 Wrap with Focus here
|
child: Focus(
|
||||||
|
// 👈 Wrap with Focus here
|
||||||
focusNode: submitButtonFocusNode,
|
focusNode: submitButtonFocusNode,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor:
|
backgroundColor:
|
||||||
isViewMode ? layoutColor : layoutColor, // Keep original color
|
isViewMode
|
||||||
|
? layoutColor
|
||||||
|
: layoutColor, // Keep original color
|
||||||
foregroundColor:
|
foregroundColor:
|
||||||
isViewMode
|
isViewMode
|
||||||
? Colors.white
|
? Colors.white
|
||||||
|
|||||||
@ -229,6 +229,18 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
_clearError(field);
|
_clearError(field);
|
||||||
widget.errorMessages[field] = "$label is invalid";
|
widget.errorMessages[field] = "$label is invalid";
|
||||||
print("Validation failed: $label is too short.");
|
print("Validation failed: $label is too short.");
|
||||||
|
// widget.controllers["mobileNumber"]?.clear();
|
||||||
|
|
||||||
|
final controller = widget.controllers["mobileNumber"];
|
||||||
|
if (controller != null) {
|
||||||
|
print("Before clear: ${controller.text}");
|
||||||
|
// controller.clear();
|
||||||
|
print("After clear: ${controller.text}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure this setState rebuilds the widget that owns the TextField!
|
||||||
|
if (mounted) setState(() {});
|
||||||
|
// setState(() {});
|
||||||
return; // Skip the API call if input is invalid
|
return; // Skip the API call if input is invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,7 +253,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
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']}");
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -1410,6 +1422,14 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
if (widget.errorMessages["mobile_no"] != null) ...[
|
if (widget.errorMessages["mobile_no"] != null) ...[
|
||||||
|
// Builder(
|
||||||
|
// builder: (context) {
|
||||||
|
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
// widget.controllers["mobileNumber"]?.clear();
|
||||||
|
// });
|
||||||
|
// return const SizedBox.shrink();
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
SizedBox(height: 5), // Space before error message
|
SizedBox(height: 5), // Space before error message
|
||||||
Text(
|
Text(
|
||||||
widget.errorMessages["mobile_no"]!,
|
widget.errorMessages["mobile_no"]!,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user