From 2e858dc90166fe256fdc7ba4733bb85cab81a6e2 Mon Sep 17 00:00:00 2001 From: bicochan Date: Wed, 22 Apr 2026 13:28:32 +0900 Subject: [PATCH] =?UTF-8?q?[st]=20feat:=20=ED=86=B5=EA=B3=84=20=EA=B2=80?= =?UTF-8?q?=EC=A6=9D=20=EC=8A=B9=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EC=9E=91?= =?UTF-8?q?=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../verification/ApprovalInputDialog.tsx | 177 ++++++++++++++++++ .../StatisticsVerificationReport.tsx | 29 ++- .../statistics-input-status-interface.ts | 1 + 3 files changed, 199 insertions(+), 8 deletions(-) create mode 100644 apps/st/src/components/statistics/verification/ApprovalInputDialog.tsx diff --git a/apps/st/src/components/statistics/verification/ApprovalInputDialog.tsx b/apps/st/src/components/statistics/verification/ApprovalInputDialog.tsx new file mode 100644 index 000000000..49170e7ae --- /dev/null +++ b/apps/st/src/components/statistics/verification/ApprovalInputDialog.tsx @@ -0,0 +1,177 @@ +"use client"; + +import { useEffect, useState } from "react"; + +import { + Button, + Dialog, + DialogClose, + DialogContent, + DialogFooter, + DialogHeader, + DialogTitle, + Input, + Label, + Textarea, +} from "@common/components"; + +export interface ApprovalFormData { + rjctOpnnCn: string; + lastCfmtnPicNm: string; + lastCfmtnPicTelNo: string; + lastCfmtnPicDeptNm: string; + lastCfmtnPicJbgdNm: string; +} + +export interface ApprovalInputDialogProps { + open: boolean; + onOpenChange: (open: boolean) => void; + onConfirm?: (data: ApprovalFormData) => void | Promise; +} + +export function ApprovalInputDialog({ + open, + onOpenChange, + onConfirm, +}: ApprovalInputDialogProps) { + const [rjctOpnnCn, setRjctOpnnCn] = useState(""); + const [lastCfmtnPicNm, setLastCfmtnPicNm] = useState(""); + const [lastCfmtnPicTelNo, setLastCfmtnPicTelNo] = useState(""); + const [lastCfmtnPicDeptNm, setLastCfmtnPicDeptNm] = useState(""); + const [lastCfmtnPicJbgdNm, setLastCfmtnPicJbgdNm] = useState(""); + + const [isSubmitting, setIsSubmitting] = useState(false); + + const resetForm = () => { + setRjctOpnnCn(""); + setLastCfmtnPicNm(""); + setLastCfmtnPicTelNo(""); + setLastCfmtnPicDeptNm(""); + setLastCfmtnPicJbgdNm(""); + }; + + const handleDialogOpenChange = (nextOpen: boolean) => { + if (!nextOpen) resetForm(); + onOpenChange(nextOpen); + }; + + useEffect(() => { + if (!open) { + resetForm(); + } + }, [open]); + + const handleConfirm = async () => { + try { + setIsSubmitting(true); + const formData: ApprovalFormData = { + rjctOpnnCn: rjctOpnnCn.trim(), + lastCfmtnPicNm: lastCfmtnPicNm.trim(), + lastCfmtnPicTelNo: lastCfmtnPicTelNo.trim(), + lastCfmtnPicDeptNm: lastCfmtnPicDeptNm.trim(), + lastCfmtnPicJbgdNm: lastCfmtnPicJbgdNm.trim(), + }; + await onConfirm?.(formData); + } finally { + setIsSubmitting(false); + } + }; + + return ( + + + + 승인 정보 입력 + +
+
+ + { + setLastCfmtnPicNm(e.target.value); + }} + className="!text-[1.3rem]" + placeholder="담당자명을 입력하세요." + disabled={isSubmitting} + /> +
+
+ + { + setLastCfmtnPicTelNo(e.target.value); + }} + className="!text-[1.3rem]" + placeholder="전화번호를 입력하세요." + disabled={isSubmitting} + /> +
+
+ + { + setLastCfmtnPicDeptNm(e.target.value); + }} + className="!text-[1.3rem]" + placeholder="부서명을 입력하세요." + disabled={isSubmitting} + /> +
+
+ + { + setLastCfmtnPicJbgdNm(e.target.value); + }} + className="!text-[1.3rem]" + placeholder="직급명을 입력하세요." + disabled={isSubmitting} + /> +
+
+ +