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 {
|
||||
_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();
|
||||
String label = "";
|
||||
List<Map<String, dynamic>> approverData = [];
|
||||
@ -530,7 +531,9 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
if (response.statusCode == 200) {
|
||||
final data = json.decode(response.body);
|
||||
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 {
|
||||
print('Failed to load');
|
||||
label = "Error - Failed to load data";
|
||||
@ -543,76 +546,104 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (approverData.isNotEmpty)
|
||||
SizedBox(
|
||||
height: 250,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: DataTable(
|
||||
columns: [
|
||||
// DataColumn(label: Text('S.No', style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w600))),
|
||||
// DataColumn(label: Text('Approver ID', style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w600))),
|
||||
DataColumn(label: Text('Status', style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w600))),
|
||||
],
|
||||
rows: 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))),
|
||||
builder:
|
||||
(context) => AlertDialog(
|
||||
title: Text(
|
||||
label,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
content: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (approverData.isNotEmpty)
|
||||
SizedBox(
|
||||
height: 250,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: DataTable(
|
||||
columns: [
|
||||
// DataColumn(label: Text('S.No', style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w600))),
|
||||
// DataColumn(label: Text('Approver ID', style: GoogleFonts.poppins(fontSize: 14, fontWeight: FontWeight.w600))),
|
||||
DataColumn(
|
||||
label: Text(
|
||||
'Status',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}).toList(),
|
||||
rows:
|
||||
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) {
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInfo) {
|
||||
@ -688,7 +719,10 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
|
||||
return Container(
|
||||
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:
|
||||
isDesktop
|
||||
? MediaQuery.of(context).size.height * 0.98
|
||||
@ -788,10 +822,10 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
isDesktop
|
||||
? SizedBox.shrink()
|
||||
: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width * 0.8,
|
||||
width: MediaQuery.of(context).size.width * 0.82,
|
||||
height: 35,
|
||||
child: TextField(
|
||||
controller: searchController,
|
||||
@ -858,7 +892,8 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
// fontWeight: FontWeight.bold,
|
||||
// color: Colors.redAccent)),
|
||||
SizedBox(height: adjHgt / 4),
|
||||
Text("No Data Found",
|
||||
Text(
|
||||
"No Data Found",
|
||||
textAlign: TextAlign.center,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 20,
|
||||
@ -1138,14 +1173,20 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
height: 25,
|
||||
alignment: Alignment.center,
|
||||
decoration: BoxDecoration(
|
||||
color: getStatusColor(plan.statusValue),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: getStatusColor(
|
||||
plan.statusValue,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
8,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
plan.statusValue,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: getStatusTextColor(plan.statusValue),
|
||||
color: getStatusTextColor(
|
||||
plan.statusValue,
|
||||
),
|
||||
fontSize: 12,
|
||||
fontFamily: "Inter",
|
||||
fontWeight: FontWeight.w400,
|
||||
@ -1412,8 +1453,12 @@ class _ApprovalListState extends State<ApprovalList> {
|
||||
vertical: 4,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: getStatusColor(plan.statusValue),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
color: getStatusColor(
|
||||
plan.statusValue,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(
|
||||
8,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
plan.statusValue,
|
||||
|
||||
@ -31,7 +31,10 @@ class _ColorThemePickerWidgetState extends State<ColorThemePickerWidget> {
|
||||
Color(0xFF448AFF), // BlueAccent
|
||||
Color(0xFF027E87), // Blue Shade
|
||||
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(0xFFE67E22), // Orange 2
|
||||
Color(0xFFBF4C0D), // Orange dark orange 3
|
||||
|
||||
@ -61,10 +61,10 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
|
||||
bool isCheckingToken = false;
|
||||
bool isDisable = false;
|
||||
bool isValid = false;
|
||||
|
||||
final FocusNode submitButtonFocusNode = FocusNode();
|
||||
|
||||
|
||||
String? token;
|
||||
|
||||
late bool isapiselectedUser = false;
|
||||
@ -180,7 +180,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
"first_approver": selectedFirstApprover,
|
||||
"second_approver": selectedSecondApprover,
|
||||
"third_approver": selectedThirdApprover,
|
||||
"exceptional_approver" : selectedExceptionalApprover,
|
||||
"exceptional_approver": selectedExceptionalApprover,
|
||||
"delegated_to_user_id": selectedSubstituteApprover,
|
||||
// "passport_number": controllers["passportNumber"]?.text,
|
||||
// "place_of_issue": controllers["placeOfIssue"]?.text,
|
||||
@ -784,9 +784,10 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
|
||||
final currentTab = tabKeys[currentIndex];
|
||||
if (currentTab == "personal") {
|
||||
isValid = isValidData(userDetials);
|
||||
// isValid = isValidData(userDetials);
|
||||
isValid = await isValidData(userDetials);
|
||||
} else if (currentTab == "office") {
|
||||
isValid = isValidDataTwo(userDetials);
|
||||
isValid = await isValidDataTwo(userDetials);
|
||||
} else {
|
||||
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;
|
||||
|
||||
print("userDetials ====> $userDetials");
|
||||
if (!isValidData(data)) {
|
||||
if (!await isValidData(data)) {
|
||||
print("USERDETAILS : $userDetials");
|
||||
print("Validation Failed: Required fields are missing.");
|
||||
setState(() {});
|
||||
@ -942,7 +943,7 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
|
||||
// Map<String, dynamic> data = userDetials;
|
||||
|
||||
if (!isValidData(data) && isValidDataTwo(data)) {
|
||||
if (!await isValidData(data) && !await isValidDataTwo(data)) {
|
||||
print("USERDETAILS : $userDetials");
|
||||
print("Validation Failed: Required fields are missing.");
|
||||
setState(() {});
|
||||
@ -958,7 +959,72 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
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
|
||||
|
||||
// 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())) {
|
||||
errorMessages["mobile_no"] =
|
||||
"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 &&
|
||||
@ -1006,12 +1108,43 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$",
|
||||
).hasMatch(data["email"].toString())) {
|
||||
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
|
||||
}
|
||||
|
||||
bool isValidDataTwo(Map<String, dynamic> data) {
|
||||
Future<bool> isValidDataTwo(Map<String, dynamic> data) async {
|
||||
errorMessages.clear(); // Reset errors
|
||||
|
||||
// Required fields that must not be empty
|
||||
@ -1021,6 +1154,20 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
for (String field in requiredFields) {
|
||||
if (data[field] == null || data[field].toString().trim().isEmpty) {
|
||||
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: [
|
||||
if (apiselectedUser != null)
|
||||
isEditProfile
|
||||
? Text( "Profile",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 15 : 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
)
|
||||
? Text(
|
||||
"Profile",
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: isDesktop ? 15 : 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
color: Colors.black,
|
||||
),
|
||||
)
|
||||
: BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Users',
|
||||
tooltip: 'Go To Users',
|
||||
onTap: (context) {
|
||||
context.go("/listUser");
|
||||
},
|
||||
),
|
||||
BreadcrumbItem(title: 'Edit User'),
|
||||
],
|
||||
)
|
||||
isDesktop: isDesktop,
|
||||
breadcrumbItems: [
|
||||
BreadcrumbItem(
|
||||
title: 'Users',
|
||||
tooltip: 'Go To Users',
|
||||
onTap: (context) {
|
||||
context.go("/listUser");
|
||||
},
|
||||
),
|
||||
BreadcrumbItem(title: 'Edit User'),
|
||||
],
|
||||
)
|
||||
else
|
||||
BreadcrumbNavigation(
|
||||
isDesktop: isDesktop,
|
||||
@ -1584,28 +1732,37 @@ class _CreateUserFormDetialsState extends State<CreateUserFormDetials> {
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
setState(() async {
|
||||
bool isValid = false;
|
||||
|
||||
final currentTab = selectedTab;
|
||||
if (currentTab == "personal") {
|
||||
isValid = isValidData(userDetials);
|
||||
// isValid = isValidData(userDetials);
|
||||
isValid = await isValidData(userDetials);
|
||||
|
||||
if (isValid) {
|
||||
selectedTab = entry.key;
|
||||
setState(() {
|
||||
selectedTab = entry.key;
|
||||
});
|
||||
}
|
||||
} else if (currentTab == "office" &&
|
||||
targetTab == "personal") {
|
||||
selectedTab = entry.key;
|
||||
} else if (currentTab == "office") {
|
||||
isValid = isValidDataTwo(userDetials);
|
||||
if (isValid) {
|
||||
setState(() {
|
||||
selectedTab = entry.key;
|
||||
});
|
||||
} else if (currentTab == "office") {
|
||||
isValid = await isValidDataTwo(userDetials);
|
||||
if (isValid) {
|
||||
setState(() {
|
||||
selectedTab = entry.key;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
isValid =
|
||||
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
|
||||
? SystemMouseCursors.forbidden
|
||||
: SystemMouseCursors.click,
|
||||
child: Focus( // 👈 Wrap with Focus here
|
||||
child: Focus(
|
||||
// 👈 Wrap with Focus here
|
||||
focusNode: submitButtonFocusNode,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor:
|
||||
isViewMode ? layoutColor : layoutColor, // Keep original color
|
||||
isViewMode
|
||||
? layoutColor
|
||||
: layoutColor, // Keep original color
|
||||
foregroundColor:
|
||||
isViewMode
|
||||
? Colors.white
|
||||
|
||||
@ -229,6 +229,18 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
_clearError(field);
|
||||
widget.errorMessages[field] = "$label is invalid";
|
||||
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
|
||||
}
|
||||
|
||||
@ -241,7 +253,7 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
if (response.isNotEmpty) {
|
||||
// _clearError(field);
|
||||
widget.errorMessages[field] =
|
||||
response['message'] ?? "$label Already Exists";
|
||||
response['message'] ?? "$label already exists";
|
||||
print("Duplicate found: ${response['message']}");
|
||||
return;
|
||||
} else {
|
||||
@ -1410,6 +1422,14 @@ class PersonalDetailsState extends State<PersonalDetails> {
|
||||
),
|
||||
),
|
||||
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
|
||||
Text(
|
||||
widget.errorMessages["mobile_no"]!,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user