feat(FE-208): add confirmation modal for manager approval with notes functionality

This commit is contained in:
rstubryan
2025-11-14 10:52:36 +07:00
parent 3d49947c1e
commit 00e0202be2
@@ -1,6 +1,6 @@
'use client';
import { useMemo } from 'react';
import { useCallback, useMemo } from 'react';
import { ColumnDef } from '@tanstack/react-table';
import ApprovalSteps, {
@@ -11,13 +11,18 @@ import Button from '@/components/Button';
import { Icon } from '@iconify/react';
import { useModal } from '@/components/Modal';
import Modal from '@/components/Modal';
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
import PurchaseOrderStaffApprovalForm from '@/components/pages/purchase/form/order/PurchaseOrderStaffApprovalForm';
import PurchaseOrderAcceptApprovalForm from '@/components/pages/purchase/form/order/PurchaseOrderAcceptApprovalForm';
import { BaseGroupedApproval } from '@/types/api/api-general';
import { PURCHASE_ORDER_APPROVAL_LINE } from '@/config/approval-line';
import Card from '@/components/Card';
import { Purchase, PurchaseItem } from '@/types/api/purchase/purchase';
import {
CreateManagerApprovalRequisitionsPayload,
Purchase,
PurchaseItem,
} from '@/types/api/purchase/purchase';
import {
createdUser,
dummyAreas,
@@ -25,6 +30,10 @@ import {
dummyProductWarehouses,
dummyWarehouses,
} from '@/dummy/marketing.dummy';
import { ManagerApprovalApi } from '@/services/api/purchase';
import { isResponseError } from '@/lib/api-helper';
import { toast } from 'react-hot-toast';
import { useSearchParams } from 'next/navigation';
interface PurchaseOrderDetailProps {
type?: 'detail' | 'edit';
@@ -290,6 +299,8 @@ const PurchaseOrderDetail = ({
data,
}: PurchaseOrderDetailProps) => {
// ===== MODAL HOOKS =====
const searchParams = useSearchParams();
const confirmationModalWithNotes = useModal();
const staffApprovalModal = useModal();
const acceptApprovalModal = useModal();
@@ -301,6 +312,32 @@ const PurchaseOrderDetail = ({
const latestApproval =
groupedApprovals[groupedApprovals.length - 1]?.approvals[0];
// ===== SUBMISSION HANDLER =====
const createManagerApprovalHandler = useCallback(
async (payload: CreateManagerApprovalRequisitionsPayload) => {
const purchaseRequisitionId = searchParams.get('purchaseId')
? parseInt(searchParams.get('purchaseId')!)
: purchaseData?.id || 1;
if (!purchaseRequisitionId) {
toast.error('Purchase Requisition ID is required');
return;
}
const res = await ManagerApprovalApi.createManagerApproval(
purchaseRequisitionId,
payload
);
if (isResponseError(res)) {
toast.error(res.message);
return;
}
toast.success(res?.message as string);
},
[purchaseData?.id, searchParams]
);
// ===== COMPUTED VALUES =====
const approvalSteps = useMemo(() => {
if (!groupedApprovals.length || !latestApproval) return [];
@@ -470,6 +507,16 @@ const PurchaseOrderDetail = ({
<section className='w-full'>
{/* Approval Action Buttons */}
<div className='flex flex-wrap gap-3 my-6'>
<Button
onClick={() => confirmationModalWithNotes.openModal()}
variant='outline'
color='warning'
className='w-full sm:w-fit'
>
<Icon icon='mdi:note-edit-outline' width={20} height={20} />
Approve
</Button>
<Button
onClick={() => staffApprovalModal.openModal()}
variant='outline'
@@ -516,7 +563,7 @@ const PurchaseOrderDetail = ({
}}
>
{/* Order Information */}
<div className='bg-gray-50 rounded-lg p-6 mb-8'>
<div className='my-8'>
<h3 className='text-lg font-semibold text-gray-800 mb-6 pb-3 border-b border-gray-200'>
Informasi Pesanan
</h3>
@@ -713,6 +760,31 @@ const PurchaseOrderDetail = ({
</div>
</Card>
{/* Confirmation Modal with Notes */}
<ConfirmationModalWithNotes
ref={confirmationModalWithNotes.ref}
type='success'
text='Apakah Anda yakin ingin melanjutkan approval ini?'
placeholder='(Opsional) Tambahkan catatan untuk approval ini...'
rows={4}
closeOnBackdrop
primaryButton={{
text: 'Ya, Lanjutkan',
color: 'success',
onClick: async (notes) => {
const payload: CreateManagerApprovalRequisitionsPayload = {
notes: notes || null,
};
await createManagerApprovalHandler(payload);
confirmationModalWithNotes.closeModal();
},
}}
secondaryButton={{
text: 'Batal',
}}
/>
{/* Staff Approval Modal */}
<Modal
ref={staffApprovalModal.ref}