100 lines
3.4 KiB
TypeScript
100 lines
3.4 KiB
TypeScript
'use client';
|
|
|
|
import { use } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
import {
|
|
getApvreqDetail, requestApvreq, deleteApvreq,
|
|
APRVL_STUS, APRVL_STUS_LABEL, APRVL_KIND_LABEL,
|
|
} from '@/lib/api/tam';
|
|
import { useAuthStore } from '@/lib/store/authStore';
|
|
import ApvreqForm from '@/components/tam/ApvreqForm';
|
|
import ApproverSection from '@/components/tam/ApproverSection';
|
|
import ApvdocInfo from '@/components/tam/ApvdocInfo';
|
|
|
|
export default function Tam0020DetailPage({ params }: { params: Promise<{ docId: string }> }) {
|
|
const { docId } = use(params);
|
|
const router = useRouter();
|
|
const qc = useQueryClient();
|
|
const usrId = useAuthStore((s) => s.user?.usrId);
|
|
|
|
const { data, isLoading } = useQuery({
|
|
queryKey: ['apvreq', docId],
|
|
queryFn: () => getApvreqDetail(docId),
|
|
});
|
|
|
|
const requestMut = useMutation({
|
|
mutationFn: (apprList: Array<{ apprId: string }>) => requestApvreq(docId, apprList),
|
|
onSuccess: () => {
|
|
qc.invalidateQueries({ queryKey: ['apvreq'] });
|
|
qc.invalidateQueries({ queryKey: ['apvreq', docId] });
|
|
alert('결재 상신이 완료되었습니다.');
|
|
},
|
|
onError: (e: any) => alert(e?.response?.data?.message ?? '상신 오류'),
|
|
});
|
|
|
|
const delMut = useMutation({
|
|
mutationFn: () => deleteApvreq(docId),
|
|
onSuccess: () => router.push('/tam/0020/list'),
|
|
onError: (e: any) => alert(e?.response?.data?.message ?? '삭제 오류'),
|
|
});
|
|
|
|
if (isLoading) return <div className="p-4 text-gray-400">불러오는 중...</div>;
|
|
if (!data) return <div className="p-4 text-gray-400">문서를 찾을 수 없습니다.</div>;
|
|
|
|
const isOwner = data.aplntId === usrId;
|
|
const isWriting = data.aprvlStusCd === APRVL_STUS.WRITING;
|
|
|
|
const handleRequest = (apprList: Array<{ apprId: string }>) => {
|
|
if (apprList.length < 2) { alert('결재자를 2명 이상 지정해주세요.'); return; }
|
|
if (!confirm(`결재자 ${apprList.length}명으로 상신하시겠습니까?`)) return;
|
|
requestMut.mutate(apprList);
|
|
};
|
|
|
|
const handleDelete = () => {
|
|
if (!confirm('신청서를 삭제하시겠습니까?')) return;
|
|
delMut.mutate();
|
|
};
|
|
|
|
return (
|
|
<div className="p-4 max-w-3xl">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<h2 className="text-lg font-semibold">결재 신청 상세</h2>
|
|
<button onClick={() => router.back()} className="text-sm text-gray-500 hover:underline">← 목록</button>
|
|
</div>
|
|
|
|
{/* 문서 정보 (읽기전용 or 편집) */}
|
|
{isOwner && isWriting ? (
|
|
<ApvreqForm
|
|
initialData={data}
|
|
onSuccess={() => qc.invalidateQueries({ queryKey: ['apvreq', docId] })}
|
|
onCancel={() => router.back()}
|
|
/>
|
|
) : (
|
|
<ApvdocInfo data={data} />
|
|
)}
|
|
|
|
{/* 결재선 */}
|
|
<ApproverSection
|
|
apprList={data.apprList}
|
|
editable={isOwner && isWriting}
|
|
onRequest={handleRequest}
|
|
requesting={requestMut.isPending}
|
|
/>
|
|
|
|
{/* 버튼 영역 */}
|
|
{isOwner && isWriting && (
|
|
<div className="flex gap-2 mt-4">
|
|
<button
|
|
onClick={handleDelete}
|
|
disabled={delMut.isPending}
|
|
className="px-4 py-2 bg-red-500 text-white text-sm rounded hover:bg-red-600 disabled:opacity-50"
|
|
>
|
|
삭제
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|