marco.pms.web/src/components/master/EditActivity.jsx
2025-04-11 15:30:15 +05:30

176 lines
5.2 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import { useFieldArray, useForm } from 'react-hook-form';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
// Zod Schema for validation
const schema = z.object({
activityName: z.string().min(1, { message: "Activity name is required" }),
unitOfMeasurement: z.string().min(1, { message: "Measurement is required" }),
checkList: z
.array(z.string().min(1, { message: "Checklist item cannot be empty" }))
.optional(),
} );
// for demo data
let initialData = {
activityName: "Item",
unitOfMeasurement: "Item-2",
checkList: [
'item 3',
'Item 4'
]
}
const EditActivity = ({onClose}) => {
const [isLoading, setIsLoading] = useState(false);
const {
register,
handleSubmit,
control,
setValue,
clearErrors,
setError,
getValues,
reset,
formState: { errors },
} = useForm({
resolver: zodResolver(schema),
defaultValues: {
activityName: '',
unitOfMeasurement: '',
checkList: [],
},
});
// Setting up field array for checkList (dynamic fields)
const {
fields: checkListItems,
append,
remove,
} = useFieldArray({
control,
name: 'checkList',
});
// Pre-populating the form with initial data when component mounts or initialData changes
useEffect(() => {
if (initialData) {
reset({
activityName: initialData.activityName,
unitOfMeasurement: initialData.unitOfMeasurement,
checkList: initialData.checkList || [],
});
}
}, [initialData, reset]);
// Form submission handler
const onSubmit = (data) => {
console.log('Submitted:', data);
};
// Add a new checklist item
const addChecklistItem = () => {
const values = getValues('checkList');
const lastIndex = checkListItems.length - 1;
// Prevent adding new input if the last one is empty
if (checkListItems.length > 0 && (!values?.[lastIndex] || values[lastIndex].trim() === '')) {
setError(`checkList.${lastIndex}`, {
type: 'manual',
message: 'Please fill this checklist item before adding another.',
});
return;
}
clearErrors(`checkList.${lastIndex}`); // Clear the error if the input is filled.
append(''); // Add a new empty checklist input
};
// Remove a checklist item
const removeChecklistItem = (index) => {
remove(index); // Remove the checklist item from the field array
};
// Handle checklist item input change
const handleChecklistChange = (index, value) => {
setValue(`checkList.${index}`, value); // Update the value of the checklist item
};
const handleCLose = () =>
{
() => reset()
onClose()
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<div className="row">
<div className="col-6">
<label className="form-label">Activity</label>
<input
type="text"
{...register('activityName')}
className={`form-control form-control-sm ${errors.activityName ? 'is-invalid' : ''}`}
/>
{errors.activityName && <p className="danger-text">{errors.activityName.message}</p>}
</div>
<div className="col-6">
<label className="form-label">Measurement</label>
<input
type="text"
{...register('unitOfMeasurement')}
className={`form-control form-control-sm ${errors.unitOfMeasurement ? 'is-invalid' : ''}`}
/>
{errors.unitOfMeasurement && (
<p className="danger-text">{errors.unitOfMeasurement.message}</p>
)}
</div>
<div className="col-md-6 text-start">
{/* Dynamic checklist items */}
{checkListItems.map((item, index) => (
<div key={item.id} className="d-flex align-items-center gap-2 my-1">
<input
{...register(`checkList.${index}`)}
className="form-control form-control-sm"
placeholder={`Checklist item ${index + 1}`}
onChange={(e) => handleChecklistChange(index, e.target.value)} // Handle input change
/>
<button
type="button"
onClick={() => removeChecklistItem(index)} // Remove button
className="btn btn-xs btn-icon btn-text-secondary"
>
<span className="icon-base bx bx-x"/>
</button>
{errors.checkList?.[index] && (
<p className="danger-text">{errors.checkList[index]?.message}</p>
)}
</div>
))}
{/* Add new checklist item */}
<button type="button" className="btn btn-sm btn-primary mt-2" onClick={addChecklistItem}>
+ Add Checklist Item
</button>
</div>
<div className="col-12 text-center mt-3">
<button type="submit" className="btn btn-sm btn-primary me-3">
Submit
</button>
<button
type="reset"
className="btn btn-sm btn-label-secondary"
onClick={handleCLose}
>
Cancel
</button>
</div>
</div>
</form>
);
};
export default EditActivity;