diff --git a/src/components/helper/form/FormActions.tsx b/src/components/helper/form/FormActions.tsx index 92c2a92c..111b052f 100644 --- a/src/components/helper/form/FormActions.tsx +++ b/src/components/helper/form/FormActions.tsx @@ -9,6 +9,11 @@ interface FormActionsProps { editUrl?: string; onDelete?: () => void; disableSubmit?: boolean; + onApprove?: () => void; + onReject?: () => void; + isApproveLoading?: boolean; + isRejectLoading?: boolean; + showApproveReject?: boolean; } export const FormActions = ({ @@ -17,25 +22,32 @@ export const FormActions = ({ editUrl, onDelete, disableSubmit = false, + onApprove, + onReject, + isApproveLoading = false, + isRejectLoading = false, + showApproveReject = false, }: FormActionsProps) => { return (
- {type !== 'add' && onDelete && ( + {type !== 'add' && (
- + {onDelete && ( + + )} {type !== 'edit' && editUrl && ( )} + {type === 'detail' && showApproveReject && (onApprove || onReject) && ( + <> + {onApprove && ( + + )} + {onReject && ( + + )} + + )}
)} {type !== 'detail' && ( diff --git a/src/components/pages/production/recording/form/RecordingForm.tsx b/src/components/pages/production/recording/form/RecordingForm.tsx index e8853545..f63d6298 100644 --- a/src/components/pages/production/recording/form/RecordingForm.tsx +++ b/src/components/pages/production/recording/form/RecordingForm.tsx @@ -12,10 +12,12 @@ import CheckboxInput from '@/components/input/CheckboxInput'; import ConfirmationModal from '@/components/modal/ConfirmationModal'; import { FormHeader } from '@/components/helper/form/FormHeader'; import { FormActions } from '@/components/helper/form/FormActions'; +import { RecordingApi } from '@/services/api/production'; import { CreateRecordingPayload, Recording, } from '@/types/api/production/recording'; +import { type BaseApiResponse } from '@/types/api/api-general'; import { RecordingFormSchema, RecordingFormValues, @@ -28,6 +30,8 @@ import { LocationApi } from '@/services/api/master-data'; import { ProductWarehouseApi } from '@/services/api/inventory'; import { isResponseSuccess } from '@/lib/api-helper'; import { RECORDING_FLAG_OPTIONS } from '@/config/constant'; +import { useModal } from '@/components/Modal'; +import toast from 'react-hot-toast'; import Card from '@/components/Card'; @@ -130,6 +134,73 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { confirmationModalDeleteClickHandler, } = useRecordingFormHandlers(initialValues?.id); + const [isApproveLoading, setIsApproveLoading] = useState(false); + const [isRejectLoading, setIsRejectLoading] = useState(false); + + // Modals for approve/reject actions + const approveModal = useModal(); + const rejectModal = useModal(); + + // Approve handler + const approveHandler = async () => { + setIsApproveLoading(true); + + const approveResponse = await RecordingApi.customRequest< + BaseApiResponse + >('approvals', { + method: 'POST', + payload: { + action: 'APPROVED', + approvable_ids: [initialValues?.id as number], + notes: 'Approved via Form', + }, + }); + + if (isResponseSuccess(approveResponse)) { + toast.success('Recording berhasil disetujui!'); + approveModal.closeModal(); + // Optional: redirect or refresh data + if (typeof window !== 'undefined') { + window.location.href = '/production/recording'; + } + } else { + toast.error(approveResponse?.message as string || 'Gagal menyetujui recording'); + approveModal.closeModal(); + } + + setIsApproveLoading(false); + }; + + // Reject handler + const rejectHandler = async () => { + setIsRejectLoading(true); + + const rejectResponse = await RecordingApi.customRequest< + BaseApiResponse + >('approvals', { + method: 'POST', + payload: { + action: 'REJECTED', + approvable_ids: [initialValues?.id as number], + notes: 'Rejected via Form', + }, + }); + + if (isResponseSuccess(rejectResponse)) { + toast.success('Recording berhasil ditolak!'); + rejectModal.closeModal(); + // Optional: redirect or refresh data + if (typeof window !== 'undefined') { + window.location.href = '/production/recording'; + } + } else { + toast.error(rejectResponse?.message as string || 'Gagal menolak recording'); + rejectModal.closeModal(); + } + + setIsRejectLoading(false); + }; + const formikInitialValues = useMemo( () => getRecordingFormInitialValues(initialValues), [initialValues] @@ -1305,6 +1376,11 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { : undefined } onDelete={deleteRecordingClickHandler} + onApprove={() => approveModal.openModal()} + onReject={() => rejectModal.openModal()} + isApproveLoading={isApproveLoading} + isRejectLoading={isRejectLoading} + showApproveReject={type === 'detail'} disableSubmit={hasExceededStock} /> {recordingFormErrorMessage && ( @@ -1321,20 +1397,58 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { {type !== 'add' && ( - + <> + + + {/* Approve Confirmation Modal */} + {type === 'detail' && ( + + )} + + {/* Reject Confirmation Modal */} + {type === 'detail' && ( + + )} + )} );