Files
GW-renewal/frontend/src/app/(main)/tam/0020/[docId]/page.tsx
JAE SIK CHO f8427ee1d0 share job
2026-04-09 11:12:12 +09:00

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>
);
}