share job
This commit is contained in:
99
frontend/src/app/(main)/tam/0020/[docId]/page.tsx
Normal file
99
frontend/src/app/(main)/tam/0020/[docId]/page.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
'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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user