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 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) {
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) {

View File

@ -354,24 +354,31 @@ const AdminUsers = () => {
const validateResetForm = () => {
const newErrors = {};
if (!oldPassword.trim()) {
// Old password validation
if (!oldPassword?.trim()) {
newErrors.oldPassword = 'Old password is required';
}
if (!newPassword.trim()) {
// 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';
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';
} 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 */}

View File

@ -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()) {
@ -74,6 +76,7 @@ const ResetPasswordModal = ({
return (
<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}
>

View File

@ -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>

View File

@ -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>