176 lines
5.2 KiB
JavaScript
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;
|