Activity master component made and is reday for api integration.
This commit is contained in:
parent
2428f15f35
commit
55b9420b6c
205
src/components/master/CreateActivity.jsx
Normal file
205
src/components/master/CreateActivity.jsx
Normal file
@ -0,0 +1,205 @@
|
||||
import React,{useState,useEffect} from 'react'
|
||||
import {useFieldArray, useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
import {zodResolver} from '@hookform/resolvers/zod';
|
||||
|
||||
import { MasterRespository } from '../../repositories/MastersRepository';
|
||||
import { clearApiCacheKey } from '../../slices/apiCacheSlice';
|
||||
import { getCachedData,cacheData } from '../../slices/apiDataManager';
|
||||
import showToast from '../../services/toastService';
|
||||
|
||||
const schema = z.object({
|
||||
activityName: z.string().min(1, { message: "Role is required" }),
|
||||
unitOfMeasurement: z.string().min(1, { message: "Description is required" }),
|
||||
checkList: z
|
||||
.array(z.string().min(1, { message: "Checklist item cannot be empty" }))
|
||||
.optional(),
|
||||
});
|
||||
|
||||
const CreateActivity = () =>
|
||||
{
|
||||
|
||||
const [ isLoading, setIsLoading ] = useState( false )
|
||||
|
||||
// const {
|
||||
// register,
|
||||
// handleSubmit,
|
||||
// formState: { errors },reset
|
||||
// } = useForm({
|
||||
// resolver: zodResolver(schema),
|
||||
// defaultValues: {
|
||||
// activityName: "",
|
||||
// unitOfMeasurement: "",
|
||||
// checkList: ['']
|
||||
// },
|
||||
// });
|
||||
|
||||
// const onSubmit = (data) => {
|
||||
// setIsLoading(true)
|
||||
// const result = {
|
||||
// name: data.activityName,
|
||||
// description: data.unitOfMeasurement,
|
||||
// };
|
||||
// console.log( result )
|
||||
// reset()
|
||||
// MasterRespository.createJobRole(result).then((resp)=>{
|
||||
// setIsLoading(false)
|
||||
// resetForm()
|
||||
// const cachedData = getCachedData("Job Role");
|
||||
// const updatedData = [...cachedData, resp?.data];
|
||||
// cacheData("Job Role", updatedData);
|
||||
// showToast("JobRole Added successfully.", "success");
|
||||
|
||||
// onClose()
|
||||
// }).catch((error)=>{
|
||||
// showToast(error.message, "error");
|
||||
// setIsLoading(false)
|
||||
// })
|
||||
|
||||
|
||||
// };
|
||||
// const resetForm =()=>{
|
||||
// reset({
|
||||
// activityName:"",
|
||||
// unitOfMeasurement:""
|
||||
// })
|
||||
// }
|
||||
|
||||
// useEffect(()=>{
|
||||
// return ()=>resetForm()
|
||||
// }, [] )
|
||||
|
||||
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',
|
||||
});
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
const removeChecklistItem = (index) => {
|
||||
remove(index);
|
||||
};
|
||||
|
||||
// Handle checklist item input change
|
||||
const handleChecklistChange = (index, value) => {
|
||||
setValue(`checkList.${index}`, value);
|
||||
};
|
||||
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=" align-items-center my-1">
|
||||
<div className='d-flex align-items-center gap-2'>
|
||||
<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 class='icon-base bx bx bx-x'></span>
|
||||
</button>
|
||||
</div>
|
||||
{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={() => reset()}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
export default CreateActivity
|
175
src/components/master/EditActivity.jsx
Normal file
175
src/components/master/EditActivity.jsx
Normal file
@ -0,0 +1,175 @@
|
||||
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"></span>
|
||||
</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;
|
@ -5,53 +5,62 @@ import DeleteMaster from "./DeleteMaster";
|
||||
import EditRole from "./EditRole";
|
||||
import CreateJobRole from "./CreateJobRole";
|
||||
import EditJobRole from "./EditJobRole";
|
||||
import CreateActivity from "./CreateActivity";
|
||||
import EditActivity from "./EditActivity";
|
||||
|
||||
const MasterModal = ({ modaldata ,closeModal}) => {
|
||||
|
||||
const MasterModal = ({ modaldata, closeModal }) => {
|
||||
return (
|
||||
|
||||
<div
|
||||
className="modal fade"
|
||||
id="master-modal"
|
||||
tabIndex="-1"
|
||||
aria-hidden="true"
|
||||
role="dialog"
|
||||
<div
|
||||
className="modal fade"
|
||||
id="master-modal"
|
||||
tabIndex="-1"
|
||||
aria-hidden="true"
|
||||
role="dialog"
|
||||
aria-labelledby="modalToggleLabel"
|
||||
>
|
||||
<div
|
||||
className={`modal-dialog mx-sm-auto mx-1 ${
|
||||
modaldata?.modalType === "delete" ? "modal-md" : "modal-lg"
|
||||
} modal-simple ` }
|
||||
>
|
||||
<div className="modal-content">
|
||||
<div className="modal-body p-sm-4 p-0">
|
||||
<button
|
||||
type="button"
|
||||
className="btn-close"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"
|
||||
onClick={closeModal}
|
||||
></button>
|
||||
<div className="text-center mb-2"></div>
|
||||
{modaldata?.modalType === "Role" &&
|
||||
<CreateRole masmodalType={modaldata.masterType} onClose={closeModal} />}
|
||||
{modaldata?.modalType === "Edit-Role" && (
|
||||
<EditRole master={modaldata} onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "delete" && (
|
||||
<DeleteMaster master={modaldata} onClose={closeModal}/>
|
||||
)}
|
||||
{modaldata?.modalType === "Job Role" && (
|
||||
<CreateJobRole onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "Edit-Job Role" && (
|
||||
<EditJobRole data ={modaldata.item} onClose={closeModal} />
|
||||
)}
|
||||
|
||||
<div
|
||||
className={`modal-dialog mx-sm-auto mx-1 ${
|
||||
modaldata?.modalType === "delete" || `Ativity` ? "modal-md" : "modal-lg"
|
||||
} modal-simple `}
|
||||
>
|
||||
<div className="modal-content">
|
||||
<div className="modal-body p-sm-4 p-0">
|
||||
<button
|
||||
type="button"
|
||||
className="btn-close"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"
|
||||
onClick={closeModal}
|
||||
></button>
|
||||
<div className="text-center mb-2"></div>
|
||||
{modaldata?.modalType === "Role" && (
|
||||
<CreateRole
|
||||
masmodalType={modaldata.masterType}
|
||||
onClose={closeModal}
|
||||
/>
|
||||
)}
|
||||
{modaldata?.modalType === "Edit-Role" && (
|
||||
<EditRole master={modaldata} onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "delete" && (
|
||||
<DeleteMaster master={modaldata} onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "Job Role" && (
|
||||
<CreateJobRole onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "Edit-Job Role" && (
|
||||
<EditJobRole data={modaldata.item} onClose={closeModal} />
|
||||
)}
|
||||
{modaldata?.modalType === "Activity" && (
|
||||
<CreateActivity onClose={closeModal} /> )
|
||||
}
|
||||
{modaldata?.modalType === 'Edit-Activity' && (
|
||||
<EditActivity onClose={closeModal} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -53,10 +53,8 @@ const MasterPage = () => {
|
||||
|
||||
};
|
||||
|
||||
|
||||
const {data:masterData, loading,error , RecallApi} = useMaster();
|
||||
|
||||
|
||||
|
||||
const handleSearch = (e) => {
|
||||
const value = e.target.value.toLowerCase();
|
||||
|
@ -29,7 +29,9 @@ export const MasterRespository = {
|
||||
getJobRole :()=>api.get("/api/roles/jobrole"),
|
||||
updateJobRole: ( id, data ) => api.put( `/api/roles/jobrole/${ id }`, data ),
|
||||
|
||||
getActivites: () => api.get( 'api/task/activities' ),
|
||||
getActivites: () => api.get( 'api/master/activities' ),
|
||||
createActivities: () => api.post( 'api/master/activity' ),
|
||||
updateActivity:(id) =>api.post(`api/master/edit/${id}`),
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user