mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-24 15:25:46 +00:00
feat(FE-208): add confirmation modal for manager approval with notes functionality
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { ColumnDef } from '@tanstack/react-table';
|
import { ColumnDef } from '@tanstack/react-table';
|
||||||
|
|
||||||
import ApprovalSteps, {
|
import ApprovalSteps, {
|
||||||
@@ -11,13 +11,18 @@ import Button from '@/components/Button';
|
|||||||
import { Icon } from '@iconify/react';
|
import { Icon } from '@iconify/react';
|
||||||
import { useModal } from '@/components/Modal';
|
import { useModal } from '@/components/Modal';
|
||||||
import Modal from '@/components/Modal';
|
import Modal from '@/components/Modal';
|
||||||
|
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
|
||||||
import PurchaseOrderStaffApprovalForm from '@/components/pages/purchase/form/order/PurchaseOrderStaffApprovalForm';
|
import PurchaseOrderStaffApprovalForm from '@/components/pages/purchase/form/order/PurchaseOrderStaffApprovalForm';
|
||||||
import PurchaseOrderAcceptApprovalForm from '@/components/pages/purchase/form/order/PurchaseOrderAcceptApprovalForm';
|
import PurchaseOrderAcceptApprovalForm from '@/components/pages/purchase/form/order/PurchaseOrderAcceptApprovalForm';
|
||||||
|
|
||||||
import { BaseGroupedApproval } from '@/types/api/api-general';
|
import { BaseGroupedApproval } from '@/types/api/api-general';
|
||||||
import { PURCHASE_ORDER_APPROVAL_LINE } from '@/config/approval-line';
|
import { PURCHASE_ORDER_APPROVAL_LINE } from '@/config/approval-line';
|
||||||
import Card from '@/components/Card';
|
import Card from '@/components/Card';
|
||||||
import { Purchase, PurchaseItem } from '@/types/api/purchase/purchase';
|
import {
|
||||||
|
CreateManagerApprovalRequisitionsPayload,
|
||||||
|
Purchase,
|
||||||
|
PurchaseItem,
|
||||||
|
} from '@/types/api/purchase/purchase';
|
||||||
import {
|
import {
|
||||||
createdUser,
|
createdUser,
|
||||||
dummyAreas,
|
dummyAreas,
|
||||||
@@ -25,6 +30,10 @@ import {
|
|||||||
dummyProductWarehouses,
|
dummyProductWarehouses,
|
||||||
dummyWarehouses,
|
dummyWarehouses,
|
||||||
} from '@/dummy/marketing.dummy';
|
} 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 {
|
interface PurchaseOrderDetailProps {
|
||||||
type?: 'detail' | 'edit';
|
type?: 'detail' | 'edit';
|
||||||
@@ -290,6 +299,8 @@ const PurchaseOrderDetail = ({
|
|||||||
data,
|
data,
|
||||||
}: PurchaseOrderDetailProps) => {
|
}: PurchaseOrderDetailProps) => {
|
||||||
// ===== MODAL HOOKS =====
|
// ===== MODAL HOOKS =====
|
||||||
|
const searchParams = useSearchParams();
|
||||||
|
const confirmationModalWithNotes = useModal();
|
||||||
const staffApprovalModal = useModal();
|
const staffApprovalModal = useModal();
|
||||||
const acceptApprovalModal = useModal();
|
const acceptApprovalModal = useModal();
|
||||||
|
|
||||||
@@ -301,6 +312,32 @@ const PurchaseOrderDetail = ({
|
|||||||
const latestApproval =
|
const latestApproval =
|
||||||
groupedApprovals[groupedApprovals.length - 1]?.approvals[0];
|
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 =====
|
// ===== COMPUTED VALUES =====
|
||||||
const approvalSteps = useMemo(() => {
|
const approvalSteps = useMemo(() => {
|
||||||
if (!groupedApprovals.length || !latestApproval) return [];
|
if (!groupedApprovals.length || !latestApproval) return [];
|
||||||
@@ -470,6 +507,16 @@ const PurchaseOrderDetail = ({
|
|||||||
<section className='w-full'>
|
<section className='w-full'>
|
||||||
{/* Approval Action Buttons */}
|
{/* Approval Action Buttons */}
|
||||||
<div className='flex flex-wrap gap-3 my-6'>
|
<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
|
<Button
|
||||||
onClick={() => staffApprovalModal.openModal()}
|
onClick={() => staffApprovalModal.openModal()}
|
||||||
variant='outline'
|
variant='outline'
|
||||||
@@ -516,7 +563,7 @@ const PurchaseOrderDetail = ({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* Order Information */}
|
{/* 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'>
|
<h3 className='text-lg font-semibold text-gray-800 mb-6 pb-3 border-b border-gray-200'>
|
||||||
Informasi Pesanan
|
Informasi Pesanan
|
||||||
</h3>
|
</h3>
|
||||||
@@ -713,6 +760,31 @@ const PurchaseOrderDetail = ({
|
|||||||
</div>
|
</div>
|
||||||
</Card>
|
</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 */}
|
{/* Staff Approval Modal */}
|
||||||
<Modal
|
<Modal
|
||||||
ref={staffApprovalModal.ref}
|
ref={staffApprovalModal.ref}
|
||||||
|
|||||||
Reference in New Issue
Block a user