From 90f79a7a691943a496f67f01c1e493256070e4de Mon Sep 17 00:00:00 2001 From: dujinkim Date: Mon, 7 Jul 2025 01:44:45 +0000 Subject: (대표님) 변경사항 20250707 10시 43분 - unstaged 변경사항 추가 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../table/evaluation-submit-dialog.tsx | 353 +++++++++++++++++++++ 1 file changed, 353 insertions(+) create mode 100644 lib/evaluation-submit/table/evaluation-submit-dialog.tsx (limited to 'lib/evaluation-submit/table/evaluation-submit-dialog.tsx') diff --git a/lib/evaluation-submit/table/evaluation-submit-dialog.tsx b/lib/evaluation-submit/table/evaluation-submit-dialog.tsx new file mode 100644 index 00000000..20ed5f30 --- /dev/null +++ b/lib/evaluation-submit/table/evaluation-submit-dialog.tsx @@ -0,0 +1,353 @@ +"use client" + +import * as React from "react" +import { + AlertTriangleIcon, + CheckCircleIcon, + SendIcon, + XCircleIcon, + FileTextIcon, + ClipboardListIcon, + LoaderIcon +} from "lucide-react" + +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" +import { + Alert, + AlertDescription, + AlertTitle, +} from "@/components/ui/alert" +import { Button } from "@/components/ui/button" +import { Badge } from "@/components/ui/badge" +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" +import { toast } from "sonner" + +// Progress 컴포넌트 (간단한 구현) +function Progress({ value, className }: { value: number; className?: string }) { + return ( +
+
= 50 ? 'bg-blue-500' : 'bg-yellow-500' + }`} + style={{ width: `${Math.min(100, Math.max(0, value))}%` }} + /> +
+ ) +} + +import { + getEvaluationSubmissionCompleteness, + updateEvaluationSubmissionStatus +} from "../service" +import type { EvaluationSubmissionWithVendor } from "../service" + +interface EvaluationSubmissionDialogProps { + open: boolean + onOpenChange: (open: boolean) => void + submission: EvaluationSubmissionWithVendor | null + onSuccess: () => void +} + +type CompletenessData = { + general: { + total: number + completed: number + percentage: number + isComplete: boolean + } + esg: { + total: number + completed: number + percentage: number + averageScore: number + isComplete: boolean + } + overall: { + isComplete: boolean + totalItems: number + completedItems: number + } +} + +export function EvaluationSubmissionDialog({ + open, + onOpenChange, + submission, + onSuccess, +}: EvaluationSubmissionDialogProps) { + const [isLoading, setIsLoading] = React.useState(false) + const [isSubmitting, setIsSubmitting] = React.useState(false) + const [completeness, setCompleteness] = React.useState(null) + + // 완성도 데이터 로딩 + React.useEffect(() => { + if (open && submission?.id) { + loadCompleteness() + } + }, [open, submission?.id]) + + const loadCompleteness = async () => { + if (!submission?.id) return + + setIsLoading(true) + try { + const data = await getEvaluationSubmissionCompleteness(submission.id) + setCompleteness(data) + } catch (error) { + console.error('Error loading completeness:', error) + toast.error('완성도 정보를 불러오는데 실패했습니다.') + } finally { + setIsLoading(false) + } + } + + // 제출하기 + const handleSubmit = async () => { + if (!submission?.id || !completeness) return + + if (!completeness.overall.isComplete) { + toast.error('모든 평가 항목을 완료해야 제출할 수 있습니다.') + return + } + + setIsSubmitting(true) + try { + await updateEvaluationSubmissionStatus(submission.id, 'submitted') + toast.success('평가가 성공적으로 제출되었습니다.') + onSuccess() + } catch (error: any) { + console.error('Error submitting evaluation:', error) + toast.error(error.message || '제출에 실패했습니다.') + } finally { + setIsSubmitting(false) + } + } + + const isKorean = submission?.vendor.countryCode === 'KR' + + if (isLoading) { + return ( + + +
+
+ +

완성도를 확인하는 중...

+
+
+
+
+ ) + } + + return ( + + + + + + 평가 제출하기 + + + {submission?.vendor.vendorName}의 {submission?.evaluationYear}년 평가를 제출합니다. + + + + {completeness && ( +
+ {/* 전체 완성도 카드 */} + + + + 전체 완성도 + + {completeness.overall.isComplete ? "완료" : "미완료"} + + + + +
+
+ 전체 진행률 + + {completeness.overall.completedItems}/{completeness.overall.totalItems}개 완료 + +
+ 0 + ? (completeness.overall.completedItems / completeness.overall.totalItems) * 100 + : 0 + } + className="h-2" + /> +

+ {completeness.overall.totalItems > 0 + ? Math.round((completeness.overall.completedItems / completeness.overall.totalItems) * 100) + : 0}% 완료 +

+
+
+
+ + {/* 세부 완성도 */} +
+ {/* 일반평가 */} + + + + + 일반평가 + {completeness.general.isComplete ? ( + + ) : ( + + )} + + + +
+
+ 응답 완료 + + {completeness.general.completed}/{completeness.general.total}개 + +
+ +

+ {completeness.general.percentage.toFixed(0)}% 완료 +

+
+ + {!completeness.general.isComplete && ( +

+ {completeness.general.total - completeness.general.completed}개 항목이 미완료입니다. +

+ )} +
+
+ + {/* ESG평가 */} + {isKorean ? ( + + + + + ESG평가 + {completeness.esg.isComplete ? ( + + ) : ( + + )} + + + +
+
+ 응답 완료 + + {completeness.esg.completed}/{completeness.esg.total}개 + +
+ +

+ {completeness.esg.percentage.toFixed(0)}% 완료 +

+
+ + {completeness.esg.completed > 0 && ( +
+ 평균 점수: + + {completeness.esg.averageScore.toFixed(1)}점 + +
+ )} + + {!completeness.esg.isComplete && ( +

+ {completeness.esg.total - completeness.esg.completed}개 항목이 미완료입니다. +

+ )} +
+
+ ) : ( + + + + + ESG평가 + + + +
+ 해당없음 +

한국 업체가 아니므로 ESG 평가가 제외됩니다.

+
+
+
+ )} +
+ + {/* 제출 상태 알림 */} + {completeness.overall.isComplete ? ( + + + 제출 준비 완료 + + 모든 평가 항목이 완료되었습니다. 제출하시겠습니까? + + + ) : ( + + + 제출 불가 + + 아직 완료되지 않은 평가 항목이 있습니다. 모든 항목을 완료한 후 제출해 주세요. + + + )} +
+ )} + + + + + +
+
+ ) +} \ No newline at end of file -- cgit v1.2.3