"use client" import * as React from "react" import { useForm } from "react-hook-form" import { zodResolver } from "@hookform/resolvers/zod" import { Button } from "@/components/ui/button" import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, } from "@/components/ui/sheet" import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form" import { Input } from "@/components/ui/input" import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" import { Textarea } from "@/components/ui/textarea" import { Separator } from "@/components/ui/separator" import { toast } from "sonner" import { Loader2 } from "lucide-react" import { createApprovalLine } from "../service" import { type ApprovalLineFormData, ApprovalLineSchema } from "../validations" import { ApprovalLineSelector } from "@/components/knox/approval/ApprovalLineSelector" import { OrganizationManagerSelector, type OrganizationManagerItem } from "@/components/common/organization/organization-manager-selector" import { useSession } from "next-auth/react" import { getActiveApprovalTemplateCategories, type ApprovalTemplateCategory } from "@/lib/approval-template/category-service" interface CreateApprovalLineSheetProps { open: boolean onOpenChange: (open: boolean) => void } export function CreateApprovalLineSheet({ open, onOpenChange }: CreateApprovalLineSheetProps) { const { data: session } = useSession(); const [isSubmitting, setIsSubmitting] = React.useState(false); const [categories, setCategories] = React.useState([]); const [isLoadingCategories, setIsLoadingCategories] = React.useState(false); // 고유 ID 생성 함수 (조직 관리자 추가 시 사용) const generateUniqueId = () => `apln-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`; const form = useForm({ resolver: zodResolver(ApprovalLineSchema), defaultValues: { name: "", category: "", description: "", aplns: [ // 기안자는 항상 첫 번째로 고정 (플레이스홀더) { id: generateUniqueId(), epId: undefined, userId: undefined, emailAddress: undefined, name: "기안자", deptName: undefined, role: "0", seq: "0", opinion: "", }, ], }, }); const aplns = form.watch("aplns"); // 카테고리 목록 로드 React.useEffect(() => { let active = true; const loadCategories = async () => { if (!open) return; setIsLoadingCategories(true); try { const data = await getActiveApprovalTemplateCategories(); if (active) { setCategories(data); } } catch (error) { console.error('카테고리 로드 실패:', error); } finally { if (active) setIsLoadingCategories(false); } }; loadCategories(); return () => { active = false; }; }, [open]); // 조직 관리자 추가 (공용 선택기 외 보조 입력 경로) const addOrganizationManagers = (managers: OrganizationManagerItem[]) => { const next = [...aplns]; const uniqueSeqs = Array.from(new Set(next.map((a) => parseInt(a.seq)))); const maxSeq = uniqueSeqs.length ? Math.max(...uniqueSeqs) : 0; managers.forEach((manager, idx) => { const exists = next.findIndex((a) => a.epId === manager.managerId); if (exists === -1) { const newSeqNum = Math.max(1, maxSeq + 1 + idx); const newSeq = newSeqNum.toString(); next.push({ id: generateUniqueId(), epId: manager.managerId, userId: undefined, emailAddress: undefined, name: manager.managerName, deptName: manager.departmentName, role: "1", seq: newSeq, opinion: "", }); } }); form.setValue("aplns", next, { shouldDirty: true }); }; const onSubmit = async (data: ApprovalLineFormData) => { setIsSubmitting(true); try { if (!session?.user?.id) { toast.error("로그인이 필요합니다."); return; } await createApprovalLine({ name: data.name, category: data.category || undefined, description: data.description, aplns: data.aplns, createdBy: Number(session.user.id), }); toast.success("결재선이 성공적으로 생성되었습니다."); form.reset(); onOpenChange(false); } catch { toast.error("결재선 생성 중 오류가 발생했습니다."); } finally { setIsSubmitting(false); } }; return ( 결재선 생성 새로운 결재선을 생성합니다. 결재자를 추가하고 순서를 조정할 수 있습니다.
{/* 기본 정보 */}
( 결재선 이름 * )} /> ( 카테고리 )} /> ( 설명