"use client"; import * as React from "react"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { Loader2, FileText, AlertCircle } from "lucide-react"; import { toast } from "sonner"; import { Separator } from "@/components/ui/separator"; import ApprovalLineSelector, { type ApprovalLineItem, } from "@/components/knox/approval/ApprovalLineSelector"; import { getApprovalTemplateByName, replaceTemplateVariables } from "@/lib/approval/template-utils"; import { debugLog, debugError, debugSuccess } from "@/lib/debug-utils"; interface ApprovalPreviewDialogProps { open: boolean; onOpenChange: (open: boolean) => void; templateName: string; variables: Record; title: string; description?: string; currentUser: { id: number; epId: string | null; name?: string | null; email?: string }; onSubmit: (approvers: ApprovalLineItem[]) => Promise; } export function ApprovalPreviewDialog({ open, onOpenChange, templateName, variables, title, description, currentUser, onSubmit, }: ApprovalPreviewDialogProps) { const [approvalLines, setApprovalLines] = React.useState([]); const [isSubmitting, setIsSubmitting] = React.useState(false); const [templateContent, setTemplateContent] = React.useState(""); const [isLoadingTemplate, setIsLoadingTemplate] = React.useState(false); const [templateError, setTemplateError] = React.useState(null); // 상신자 초기화 React.useEffect(() => { if (open && currentUser.epId) { const drafterLine: ApprovalLineItem = { id: `drafter-${Date.now()}`, epId: currentUser.epId, userId: currentUser.id.toString(), emailAddress: currentUser.email, name: currentUser.name || undefined, role: "0", // 기안 seq: "0", opinion: "", }; setApprovalLines([drafterLine]); } }, [open, currentUser]); // 템플릿 로드 및 변수 치환 React.useEffect(() => { if (!open) return; const loadTemplate = async () => { setIsLoadingTemplate(true); setTemplateError(null); try { const template = await getApprovalTemplateByName(templateName); if (!template) { setTemplateError(`템플릿 "${templateName}"을 찾을 수 없습니다.`); setTemplateContent(`

${description || "결재 요청"}

`); } else { // 변수 치환 const replaced = await replaceTemplateVariables(template.content, variables); setTemplateContent(replaced); } } catch (error) { console.error("Template load error:", error); setTemplateError("템플릿을 불러오는 중 오류가 발생했습니다."); setTemplateContent(`

${description || "결재 요청"}

`); } finally { setIsLoadingTemplate(false); } }; loadTemplate(); }, [open, templateName, variables, description]); const handleSubmit = async () => { debugLog('[ApprovalPreviewDialog] 결재 제출 시작', { templateName, approvalLineCount: approvalLines.length, }); // 결재자가 있는지 확인 (상신자 제외) const approvers = approvalLines.filter((line) => line.seq !== "0"); if (approvers.length === 0) { debugError('[ApprovalPreviewDialog] 결재자가 없음'); toast.error("결재자를 최소 1명 이상 추가해주세요."); return; } setIsSubmitting(true); try { debugLog('[ApprovalPreviewDialog] onSubmit 호출', { approversCount: approvers.length, }); await onSubmit(approvalLines); debugSuccess('[ApprovalPreviewDialog] 결재 요청 성공'); toast.success("결재가 성공적으로 요청되었습니다."); onOpenChange(false); } catch (error) { debugError('[ApprovalPreviewDialog] 결재 요청 실패', error); const errorMessage = error instanceof Error ? error.message : "결재 요청에 실패했습니다."; toast.error(errorMessage); // 에러 발생 시 dialog를 닫지 않음 } finally { setIsSubmitting(false); } }; return ( {title} {description && {description}}
{/* 템플릿 미리보기 */} 결재 내용 미리보기 템플릿: {templateName} {isLoadingTemplate ? (
템플릿을 불러오는 중...
) : templateError ? (
경고

{templateError}

기본 내용으로 대체되었습니다. 결재는 정상적으로 진행됩니다.

) : null}
{/* 결재선 선택 */}
); }