bug fixed
This commit is contained in:
parent
cac8d1cb2e
commit
ebd0e4c4f5
@ -30,20 +30,31 @@ const AddAdminUsers = ({ isOpen, onClose, onSave }) => {
|
||||
setToastData(null);
|
||||
}, 4000);
|
||||
};
|
||||
const validateForm = () => {
|
||||
const newErrors = {};
|
||||
if (!formData.name.trim()) newErrors.name = 'Name is required';
|
||||
if (!formData.email.trim()) newErrors.email = 'Email is required';
|
||||
else if (!/^\S+@\S+\.\S+$/.test(formData.email))
|
||||
newErrors.email = 'Please enter a valid email';
|
||||
if (!formData.status) newErrors.status = 'Status is required';
|
||||
if (!formData.password) newErrors.password = 'Password is required';
|
||||
else if (formData.password.length < 12)
|
||||
newErrors.password = 'Password must be at least 12 characters';
|
||||
if (formData.password !== formData.confirmPassword)
|
||||
newErrors.confirmPassword = 'Passwords do not match';
|
||||
return newErrors;
|
||||
};
|
||||
const validateForm = () => {
|
||||
const newErrors = {};
|
||||
|
||||
if (!formData.name.trim()) newErrors.name = 'Name is required';
|
||||
|
||||
if (!formData.email.trim()) newErrors.email = 'Email is required';
|
||||
else if (!/^\S+@\S+\.\S+$/.test(formData.email))
|
||||
newErrors.email = 'Please enter a valid email';
|
||||
|
||||
if (!formData.status) newErrors.status = 'Status is required';
|
||||
|
||||
if (!formData.password) {
|
||||
newErrors.password = 'Password is required';
|
||||
} else if (formData.password.length < 8) {
|
||||
newErrors.password = 'Password must be at least 8 characters';
|
||||
} else if (formData.password.length > 12) {
|
||||
newErrors.password = 'Password cannot exceed 12 characters';
|
||||
}
|
||||
|
||||
if (formData.password !== formData.confirmPassword)
|
||||
newErrors.confirmPassword = 'Passwords do not match';
|
||||
|
||||
return newErrors;
|
||||
};
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
|
||||
@ -351,27 +351,34 @@ const AdminUsers = () => {
|
||||
};
|
||||
|
||||
// Validate reset password form - Updated to allow 8 to 12 characters
|
||||
const validateResetForm = () => {
|
||||
const newErrors = {};
|
||||
const validateResetForm = () => {
|
||||
const newErrors = {};
|
||||
|
||||
// Old password validation
|
||||
if (!oldPassword?.trim()) {
|
||||
newErrors.oldPassword = 'Old password is required';
|
||||
}
|
||||
|
||||
// New password validation
|
||||
if (!newPassword?.trim()) {
|
||||
newErrors.newPassword = 'New password is required';
|
||||
} else if (newPassword.length < 8) {
|
||||
newErrors.newPassword = 'Password must be at least 8 characters long';
|
||||
}
|
||||
|
||||
// Confirm password validation
|
||||
if (!confirmPassword?.trim()) {
|
||||
newErrors.confirmPassword = 'Please confirm your password';
|
||||
} else if (newPassword !== confirmPassword) {
|
||||
newErrors.confirmPassword = 'Passwords do not match';
|
||||
}
|
||||
|
||||
return newErrors;
|
||||
};
|
||||
|
||||
if (!oldPassword.trim()) {
|
||||
newErrors.oldPassword = 'Old password is required';
|
||||
}
|
||||
|
||||
if (!newPassword.trim()) {
|
||||
newErrors.newPassword = 'New password is required';
|
||||
} else if (newPassword.length < 8) {
|
||||
newErrors.newPassword = 'Password must be at least 8 characters';
|
||||
}
|
||||
|
||||
if (!confirmPassword.trim()) {
|
||||
newErrors.confirmPassword = 'Please confirm your password';
|
||||
} else if (newPassword !== confirmPassword) {
|
||||
newErrors.confirmPassword = 'Passwords do not match';
|
||||
}
|
||||
|
||||
return newErrors;
|
||||
};
|
||||
|
||||
// Reset Password API Integration
|
||||
const handleResetPassword = async () => {
|
||||
@ -697,6 +704,7 @@ const AdminUsers = () => {
|
||||
showToast('User added locally', 'success');
|
||||
}}
|
||||
passwordMinLength={8}
|
||||
passwordMaxLength={12}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -734,6 +742,7 @@ const AdminUsers = () => {
|
||||
errors={resetErrors}
|
||||
setErrors={setResetErrors}
|
||||
passwordMinLength={8}
|
||||
passwordMaxLength={12}
|
||||
/>
|
||||
|
||||
{/* Toast */}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { Eye, EyeOff } from 'lucide-react';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const ResetPasswordModal = ({
|
||||
@ -18,6 +19,7 @@ const ResetPasswordModal = ({
|
||||
const [showNewPassword, setShowNewPassword] = useState(false);
|
||||
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
|
||||
|
||||
// ✅ Validation: minimum 8 characters (no 12 limit)
|
||||
const validateForm = () => {
|
||||
const newErrors = {};
|
||||
|
||||
@ -27,8 +29,8 @@ const ResetPasswordModal = ({
|
||||
|
||||
if (!newPassword.trim()) {
|
||||
newErrors.newPassword = 'New password is required';
|
||||
} else if (newPassword.length < 6) {
|
||||
newErrors.newPassword = 'Password must be at least 6 characters';
|
||||
} else if (newPassword.length < 8) {
|
||||
newErrors.newPassword = 'Password must be at least 8 characters long';
|
||||
}
|
||||
|
||||
if (!confirmPassword.trim()) {
|
||||
@ -72,8 +74,9 @@ const ResetPasswordModal = ({
|
||||
if (!isOpen) return null;
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-opacity-70 backdrop-blur-sm">
|
||||
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-opacity-70 backdrop-blur-sm">
|
||||
<div className="bg-white rounded-2xl w-[90%] max-w-md shadow-xl p-6 relative border border-gray-200">
|
||||
|
||||
{/* Header */}
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h3 className="text-xl font-bold text-gray-900">Reset Password</h3>
|
||||
@ -88,9 +91,9 @@ const ResetPasswordModal = ({
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Form */}
|
||||
{/* Form Fields */}
|
||||
<div className="space-y-4">
|
||||
{/* Old Password Field */}
|
||||
{/* Old Password */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
Old Password <span className="text-red-500">*</span>
|
||||
@ -115,29 +118,16 @@ const ResetPasswordModal = ({
|
||||
onClick={() => setShowOldPassword(!showOldPassword)}
|
||||
disabled={loading}
|
||||
>
|
||||
{showOldPassword ? (
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
||||
</svg>
|
||||
) : (
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.878 9.878L9 9m13 11l-4-4m0 0l-4 4m4-4V9" />
|
||||
</svg>
|
||||
)}
|
||||
{showOldPassword ? <EyeOff className="w-5 h-5 text-[#B68A35]" /> : <Eye className="w-5 h-5 text-[#B68A35]" />}
|
||||
|
||||
</button>
|
||||
</div>
|
||||
{errors.oldPassword && (
|
||||
<p className="text-red-600 text-xs mt-2 flex items-center gap-1">
|
||||
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
|
||||
</svg>
|
||||
{errors.oldPassword}
|
||||
</p>
|
||||
<p className="text-red-600 text-xs mt-2">{errors.oldPassword}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* New Password Field */}
|
||||
{/* New Password */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
New Password <span className="text-red-500">*</span>
|
||||
@ -162,29 +152,16 @@ const ResetPasswordModal = ({
|
||||
onClick={() => setShowNewPassword(!showNewPassword)}
|
||||
disabled={loading}
|
||||
>
|
||||
{showNewPassword ? (
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
||||
</svg>
|
||||
) : (
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.878 9.878L9 9m13 11l-4-4m0 0l-4 4m4-4V9" />
|
||||
</svg>
|
||||
)}
|
||||
{showNewPassword ? <EyeOff className="w-5 h-5 text-[#B68A35]" /> : <Eye className="w-5 h-5 text-[#B68A35]" />}
|
||||
|
||||
</button>
|
||||
</div>
|
||||
{errors.newPassword && (
|
||||
<p className="text-red-600 text-xs mt-2 flex items-center gap-1">
|
||||
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
|
||||
</svg>
|
||||
{errors.newPassword}
|
||||
</p>
|
||||
<p className="text-red-600 text-xs mt-2">{errors.newPassword}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Confirm Password Field */}
|
||||
{/* Confirm Password */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||||
Confirm Password <span className="text-red-500">*</span>
|
||||
@ -209,52 +186,39 @@ const ResetPasswordModal = ({
|
||||
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
|
||||
disabled={loading}
|
||||
>
|
||||
{showConfirmPassword ? (
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
||||
</svg>
|
||||
) : (
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.878 9.878L9 9m13 11l-4-4m0 0l-4 4m4-4V9" />
|
||||
</svg>
|
||||
)}
|
||||
{showConfirmPassword ? <EyeOff className="w-5 h-5 text-[#B68A35]" /> : <Eye className="w-5 h-5 text-[#B68A35]" />}
|
||||
|
||||
</button>
|
||||
</div>
|
||||
{errors.confirmPassword && (
|
||||
<p className="text-red-600 text-xs mt-2 flex items-center gap-1">
|
||||
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7 4a1 1 0 11-2 0 1 1 0 012 0zm-1-9a1 1 0 00-1 1v4a1 1 0 102 0V6a1 1 0 00-1-1z" clipRule="evenodd" />
|
||||
</svg>
|
||||
{errors.confirmPassword}
|
||||
</p>
|
||||
<p className="text-red-600 text-xs mt-2">{errors.confirmPassword}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Note Section */}
|
||||
{/* Note */}
|
||||
<div className="mt-4 p-3 bg-blue-50 rounded-lg border border-blue-200">
|
||||
<div className="flex items-start gap-2">
|
||||
<svg className="w-4 h-4 text-blue-600 mt-0.5 flex-shrink-0" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
|
||||
<svg className="w-4 h-4 text-blue-600 mt-0.5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
|
||||
</svg>
|
||||
<p className="text-sm text-blue-700">
|
||||
<span className="font-medium">Note:</span> Password must be at least 6 characters long.
|
||||
<span className="font-medium">Note:</span> Password must be at least <b>8 characters</b> long.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Action Buttons */}
|
||||
{/* Buttons */}
|
||||
<div className="flex justify-end gap-3 mt-6 pt-4 border-t border-gray-200">
|
||||
<button
|
||||
className="px-6 py-2.5 rounded-lg border border-gray-300 text-gray-700 font-medium hover:bg-gray-50 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
|
||||
className="px-6 py-2.5 rounded-lg border border-gray-300 text-gray-700 font-medium hover:bg-gray-50 disabled:opacity-50"
|
||||
onClick={onClose}
|
||||
disabled={loading}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
className="px-6 py-2.5 rounded-lg bg-[#B68A35] text-white font-medium hover:bg-[#9c6f28] disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2 transition-colors"
|
||||
className="px-6 py-2.5 rounded-lg bg-[#B68A35] text-white font-medium hover:bg-[#9c6f28] disabled:opacity-50 flex items-center gap-2"
|
||||
onClick={handleSubmit}
|
||||
disabled={loading}
|
||||
>
|
||||
|
||||
@ -664,10 +664,11 @@ const QuarterlyWindows = () => {
|
||||
required
|
||||
onChange={(e) => handleFormChange('survey_name')(e.target.value)}
|
||||
placeholder="Enter survey name"
|
||||
// error={validationErrors.survey_name}
|
||||
error={validationErrors.survey_name}
|
||||
className={validationErrors.survey_name ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
|
||||
/>
|
||||
{validationErrors.survey_name && (
|
||||
<p className="mt-1 text-sm text-red-600">{validationErrors.survey_name}</p>
|
||||
<p className="mt-1 text-sm text-red-600"></p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -684,10 +685,11 @@ const QuarterlyWindows = () => {
|
||||
onChange={(e) => handleFormChange('quarter')(e.target.value)}
|
||||
options={['Q1', 'Q2', 'Q3', 'Q4'].map((q) => ({ label: q, value: q }))}
|
||||
placeholder="Select Quarter"
|
||||
// error={validationErrors.quarter}
|
||||
error={validationErrors.quarter}
|
||||
className={validationErrors.quarter ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
|
||||
/>
|
||||
{validationErrors.quarter && (
|
||||
<p className="mt-1 text-sm text-red-600">{validationErrors.quarter}</p>
|
||||
<p className="mt-1 text-sm text-red-600"></p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -706,10 +708,11 @@ const QuarterlyWindows = () => {
|
||||
})}
|
||||
required
|
||||
placeholder="Select Year"
|
||||
// error={validationErrors.year}
|
||||
error={validationErrors.year}
|
||||
className={validationErrors.year ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
|
||||
/>
|
||||
{validationErrors.year && (
|
||||
<p className="mt-1 text-sm text-red-600">{validationErrors.year}</p>
|
||||
<p className="mt-1 text-sm text-red-600"></p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -725,9 +728,10 @@ const QuarterlyWindows = () => {
|
||||
onChange={(e) => handleFormChange('startDate')(e.target.value)}
|
||||
placeholder="Select Date"
|
||||
error={validationErrors.startDate}
|
||||
className={validationErrors.startDate ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
|
||||
/>
|
||||
{validationErrors.startDate && (
|
||||
<p className="mt-1 text-sm text-red-600">{validationErrors.startDate}</p>
|
||||
<p className="mt-1 text-sm text-red-500">{validationErrors.startDate}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -743,6 +747,7 @@ const QuarterlyWindows = () => {
|
||||
onChange={(e) => handleFormChange('endDate')(e.target.value)}
|
||||
placeholder="Select Date"
|
||||
error={validationErrors.endDate}
|
||||
className={validationErrors.endDate ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
|
||||
/>
|
||||
{validationErrors.endDate && (
|
||||
<p className="mt-1 text-sm text-red-600">{validationErrors.endDate}</p>
|
||||
|
||||
@ -542,10 +542,11 @@ const UnitMaster = () => {
|
||||
value={form.unitName}
|
||||
onChange={handleFormChange('unitName')}
|
||||
placeholder="Enter Unit Name"
|
||||
// error={formErrors.unitName}
|
||||
error={formErrors.unitName}
|
||||
className={formErrors.unitName ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
|
||||
/>
|
||||
{formErrors.unitName && (
|
||||
<p className="mt-1 text-sm text-red-600">{formErrors.unitName}</p>
|
||||
<p className="mt-1 text-sm text-red-600"></p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -560,10 +561,11 @@ const UnitMaster = () => {
|
||||
onChange={handleFormChange('description')}
|
||||
placeholder="Enter Description"
|
||||
width="100%"
|
||||
// error={formErrors.description}
|
||||
error={formErrors.description}
|
||||
className={formErrors.description ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
|
||||
/>
|
||||
{formErrors.description && (
|
||||
<p className="mt-1 text-sm text-red-600">{formErrors.description}</p>
|
||||
<p className="mt-1 text-sm text-red-600"></p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user