bug fixed

This commit is contained in:
Malini 2025-11-10 12:12:45 +05:30
parent cac8d1cb2e
commit ebd0e4c4f5
5 changed files with 340 additions and 349 deletions

View File

@ -32,18 +32,29 @@ const AddAdminUsers = ({ isOpen, onClose, onSave }) => {
}; };
const validateForm = () => { const validateForm = () => {
const newErrors = {}; const newErrors = {};
if (!formData.name.trim()) newErrors.name = 'Name is required'; if (!formData.name.trim()) newErrors.name = 'Name is required';
if (!formData.email.trim()) newErrors.email = 'Email is required'; if (!formData.email.trim()) newErrors.email = 'Email is required';
else if (!/^\S+@\S+\.\S+$/.test(formData.email)) else if (!/^\S+@\S+\.\S+$/.test(formData.email))
newErrors.email = 'Please enter a valid email'; newErrors.email = 'Please enter a valid email';
if (!formData.status) newErrors.status = 'Status is required'; if (!formData.status) newErrors.status = 'Status is required';
if (!formData.password) newErrors.password = 'Password is required';
else if (formData.password.length < 12) if (!formData.password) {
newErrors.password = 'Password must be at least 12 characters'; 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) if (formData.password !== formData.confirmPassword)
newErrors.confirmPassword = 'Passwords do not match'; newErrors.confirmPassword = 'Passwords do not match';
return newErrors; return newErrors;
}; };
useEffect(() => { useEffect(() => {
if (isOpen) { if (isOpen) {

View File

@ -354,24 +354,31 @@ const AdminUsers = () => {
const validateResetForm = () => { const validateResetForm = () => {
const newErrors = {}; const newErrors = {};
if (!oldPassword.trim()) { // Old password validation
if (!oldPassword?.trim()) {
newErrors.oldPassword = 'Old password is required'; newErrors.oldPassword = 'Old password is required';
} }
if (!newPassword.trim()) { // New password validation
if (!newPassword?.trim()) {
newErrors.newPassword = 'New password is required'; newErrors.newPassword = 'New password is required';
} else if (newPassword.length < 8) { } else if (newPassword.length < 8) {
newErrors.newPassword = 'Password must be at least 8 characters'; newErrors.newPassword = 'Password must be at least 8 characters long';
} }
if (!confirmPassword.trim()) { // Confirm password validation
if (!confirmPassword?.trim()) {
newErrors.confirmPassword = 'Please confirm your password'; newErrors.confirmPassword = 'Please confirm your password';
} else if (newPassword !== confirmPassword) { } else if (newPassword !== confirmPassword) {
newErrors.confirmPassword = 'Passwords do not match'; newErrors.confirmPassword = 'Passwords do not match';
} }
return newErrors; return newErrors;
}; };
// Reset Password API Integration // Reset Password API Integration
const handleResetPassword = async () => { const handleResetPassword = async () => {
@ -697,6 +704,7 @@ const AdminUsers = () => {
showToast('User added locally', 'success'); showToast('User added locally', 'success');
}} }}
passwordMinLength={8} passwordMinLength={8}
passwordMaxLength={12}
/> />
)} )}
@ -734,6 +742,7 @@ const AdminUsers = () => {
errors={resetErrors} errors={resetErrors}
setErrors={setResetErrors} setErrors={setResetErrors}
passwordMinLength={8} passwordMinLength={8}
passwordMaxLength={12}
/> />
{/* Toast */} {/* Toast */}

View File

@ -1,3 +1,4 @@
import { Eye, EyeOff } from 'lucide-react';
import React, { useState } from 'react'; import React, { useState } from 'react';
const ResetPasswordModal = ({ const ResetPasswordModal = ({
@ -18,6 +19,7 @@ const ResetPasswordModal = ({
const [showNewPassword, setShowNewPassword] = useState(false); const [showNewPassword, setShowNewPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false); const [showConfirmPassword, setShowConfirmPassword] = useState(false);
// Validation: minimum 8 characters (no 12 limit)
const validateForm = () => { const validateForm = () => {
const newErrors = {}; const newErrors = {};
@ -27,8 +29,8 @@ const ResetPasswordModal = ({
if (!newPassword.trim()) { if (!newPassword.trim()) {
newErrors.newPassword = 'New password is required'; newErrors.newPassword = 'New password is required';
} else if (newPassword.length < 6) { } else if (newPassword.length < 8) {
newErrors.newPassword = 'Password must be at least 6 characters'; newErrors.newPassword = 'Password must be at least 8 characters long';
} }
if (!confirmPassword.trim()) { if (!confirmPassword.trim()) {
@ -74,6 +76,7 @@ const ResetPasswordModal = ({
return ( 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"> <div className="bg-white rounded-2xl w-[90%] max-w-md shadow-xl p-6 relative border border-gray-200">
{/* Header */} {/* Header */}
<div className="flex items-center justify-between mb-6"> <div className="flex items-center justify-between mb-6">
<h3 className="text-xl font-bold text-gray-900">Reset Password</h3> <h3 className="text-xl font-bold text-gray-900">Reset Password</h3>
@ -88,9 +91,9 @@ const ResetPasswordModal = ({
</button> </button>
</div> </div>
{/* Form */} {/* Form Fields */}
<div className="space-y-4"> <div className="space-y-4">
{/* Old Password Field */} {/* Old Password */}
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-2"> <label className="block text-sm font-medium text-gray-700 mb-2">
Old Password <span className="text-red-500">*</span> Old Password <span className="text-red-500">*</span>
@ -115,29 +118,16 @@ const ResetPasswordModal = ({
onClick={() => setShowOldPassword(!showOldPassword)} onClick={() => setShowOldPassword(!showOldPassword)}
disabled={loading} disabled={loading}
> >
{showOldPassword ? ( {showOldPassword ? <EyeOff className="w-5 h-5 text-[#B68A35]" /> : <Eye className="w-5 h-5 text-[#B68A35]" />}
<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>
)}
</button> </button>
</div> </div>
{errors.oldPassword && ( {errors.oldPassword && (
<p className="text-red-600 text-xs mt-2 flex items-center gap-1"> <p className="text-red-600 text-xs mt-2">{errors.oldPassword}</p>
<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>
)} )}
</div> </div>
{/* New Password Field */} {/* New Password */}
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-2"> <label className="block text-sm font-medium text-gray-700 mb-2">
New Password <span className="text-red-500">*</span> New Password <span className="text-red-500">*</span>
@ -162,29 +152,16 @@ const ResetPasswordModal = ({
onClick={() => setShowNewPassword(!showNewPassword)} onClick={() => setShowNewPassword(!showNewPassword)}
disabled={loading} disabled={loading}
> >
{showNewPassword ? ( {showNewPassword ? <EyeOff className="w-5 h-5 text-[#B68A35]" /> : <Eye className="w-5 h-5 text-[#B68A35]" />}
<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>
)}
</button> </button>
</div> </div>
{errors.newPassword && ( {errors.newPassword && (
<p className="text-red-600 text-xs mt-2 flex items-center gap-1"> <p className="text-red-600 text-xs mt-2">{errors.newPassword}</p>
<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>
)} )}
</div> </div>
{/* Confirm Password Field */} {/* Confirm Password */}
<div> <div>
<label className="block text-sm font-medium text-gray-700 mb-2"> <label className="block text-sm font-medium text-gray-700 mb-2">
Confirm Password <span className="text-red-500">*</span> Confirm Password <span className="text-red-500">*</span>
@ -209,52 +186,39 @@ const ResetPasswordModal = ({
onClick={() => setShowConfirmPassword(!showConfirmPassword)} onClick={() => setShowConfirmPassword(!showConfirmPassword)}
disabled={loading} disabled={loading}
> >
{showConfirmPassword ? ( {showConfirmPassword ? <EyeOff className="w-5 h-5 text-[#B68A35]" /> : <Eye className="w-5 h-5 text-[#B68A35]" />}
<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>
)}
</button> </button>
</div> </div>
{errors.confirmPassword && ( {errors.confirmPassword && (
<p className="text-red-600 text-xs mt-2 flex items-center gap-1"> <p className="text-red-600 text-xs mt-2">{errors.confirmPassword}</p>
<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>
)} )}
</div> </div>
</div> </div>
{/* Note Section */} {/* Note */}
<div className="mt-4 p-3 bg-blue-50 rounded-lg border border-blue-200"> <div className="mt-4 p-3 bg-blue-50 rounded-lg border border-blue-200">
<div className="flex items-start gap-2"> <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"> <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 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" /> <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> </svg>
<p className="text-sm text-blue-700"> <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> </p>
</div> </div>
</div> </div>
{/* Action Buttons */} {/* Buttons */}
<div className="flex justify-end gap-3 mt-6 pt-4 border-t border-gray-200"> <div className="flex justify-end gap-3 mt-6 pt-4 border-t border-gray-200">
<button <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} onClick={onClose}
disabled={loading} disabled={loading}
> >
Cancel Cancel
</button> </button>
<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} onClick={handleSubmit}
disabled={loading} disabled={loading}
> >

View File

@ -664,10 +664,11 @@ const QuarterlyWindows = () => {
required required
onChange={(e) => handleFormChange('survey_name')(e.target.value)} onChange={(e) => handleFormChange('survey_name')(e.target.value)}
placeholder="Enter survey name" 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 && ( {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> </div>
@ -684,10 +685,11 @@ const QuarterlyWindows = () => {
onChange={(e) => handleFormChange('quarter')(e.target.value)} onChange={(e) => handleFormChange('quarter')(e.target.value)}
options={['Q1', 'Q2', 'Q3', 'Q4'].map((q) => ({ label: q, value: q }))} options={['Q1', 'Q2', 'Q3', 'Q4'].map((q) => ({ label: q, value: q }))}
placeholder="Select Quarter" 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 && ( {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> </div>
@ -706,10 +708,11 @@ const QuarterlyWindows = () => {
})} })}
required required
placeholder="Select Year" 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 && ( {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> </div>
@ -725,9 +728,10 @@ const QuarterlyWindows = () => {
onChange={(e) => handleFormChange('startDate')(e.target.value)} onChange={(e) => handleFormChange('startDate')(e.target.value)}
placeholder="Select Date" placeholder="Select Date"
error={validationErrors.startDate} error={validationErrors.startDate}
className={validationErrors.startDate ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
/> />
{validationErrors.startDate && ( {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> </div>
@ -743,6 +747,7 @@ const QuarterlyWindows = () => {
onChange={(e) => handleFormChange('endDate')(e.target.value)} onChange={(e) => handleFormChange('endDate')(e.target.value)}
placeholder="Select Date" placeholder="Select Date"
error={validationErrors.endDate} error={validationErrors.endDate}
className={validationErrors.endDate ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
/> />
{validationErrors.endDate && ( {validationErrors.endDate && (
<p className="mt-1 text-sm text-red-600">{validationErrors.endDate}</p> <p className="mt-1 text-sm text-red-600">{validationErrors.endDate}</p>

View File

@ -542,10 +542,11 @@ const UnitMaster = () => {
value={form.unitName} value={form.unitName}
onChange={handleFormChange('unitName')} onChange={handleFormChange('unitName')}
placeholder="Enter Unit Name" 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 && ( {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> </div>
@ -560,10 +561,11 @@ const UnitMaster = () => {
onChange={handleFormChange('description')} onChange={handleFormChange('description')}
placeholder="Enter Description" placeholder="Enter Description"
width="100%" width="100%"
// error={formErrors.description} error={formErrors.description}
className={formErrors.description ? 'border-red-500 focus:border-red-500 focus:ring-red-500' : ''}
/> />
{formErrors.description && ( {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>
</div> </div>