diff options
Diffstat (limited to 'lib/evaluation-submit/table')
| -rw-r--r-- | lib/evaluation-submit/table/evaluation-submit-dialog.tsx | 353 |
1 files changed, 0 insertions, 353 deletions
diff --git a/lib/evaluation-submit/table/evaluation-submit-dialog.tsx b/lib/evaluation-submit/table/evaluation-submit-dialog.tsx deleted file mode 100644 index 20ed5f30..00000000 --- a/lib/evaluation-submit/table/evaluation-submit-dialog.tsx +++ /dev/null @@ -1,353 +0,0 @@ -"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 ( - <div className={`w-full bg-gray-200 rounded-full overflow-hidden ${className}`}> - <div - className={`h-full bg-blue-600 transition-all duration-300 ${ - value === 100 ? 'bg-green-500' : value >= 50 ? 'bg-blue-500' : 'bg-yellow-500' - }`} - style={{ width: `${Math.min(100, Math.max(0, value))}%` }} - /> - </div> - ) -} - -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<CompletenessData | null>(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 ( - <Dialog open={open} onOpenChange={onOpenChange}> - <DialogContent className="sm:max-w-[500px]"> - <div className="flex items-center justify-center py-8"> - <div className="text-center space-y-4"> - <LoaderIcon className="h-8 w-8 animate-spin mx-auto" /> - <p>완성도를 확인하는 중...</p> - </div> - </div> - </DialogContent> - </Dialog> - ) - } - - return ( - <Dialog open={open} onOpenChange={onOpenChange}> - <DialogContent className="sm:max-w-[600px]"> - <DialogHeader> - <DialogTitle className="flex items-center gap-2"> - <SendIcon className="h-5 w-5" /> - 평가 제출하기 - </DialogTitle> - <DialogDescription> - {submission?.vendor.vendorName}의 {submission?.evaluationYear}년 평가를 제출합니다. - </DialogDescription> - </DialogHeader> - - {completeness && ( - <div className="space-y-6"> - {/* 전체 완성도 카드 */} - <Card> - <CardHeader> - <CardTitle className="text-base flex items-center justify-between"> - <span>전체 완성도</span> - <Badge - variant={completeness.overall.isComplete ? "default" : "secondary"} - className={ - completeness.overall.isComplete - ? "bg-green-100 text-green-800 border-green-200" - : "" - } - > - {completeness.overall.isComplete ? "완료" : "미완료"} - </Badge> - </CardTitle> - </CardHeader> - <CardContent className="space-y-4"> - <div className="space-y-2"> - <div className="flex items-center justify-between text-sm"> - <span>전체 진행률</span> - <span className="font-medium"> - {completeness.overall.completedItems}/{completeness.overall.totalItems}개 완료 - </span> - </div> - <Progress - value={ - completeness.overall.totalItems > 0 - ? (completeness.overall.completedItems / completeness.overall.totalItems) * 100 - : 0 - } - className="h-2" - /> - <p className="text-xs text-muted-foreground"> - {completeness.overall.totalItems > 0 - ? Math.round((completeness.overall.completedItems / completeness.overall.totalItems) * 100) - : 0}% 완료 - </p> - </div> - </CardContent> - </Card> - - {/* 세부 완성도 */} - <div className="grid grid-cols-1 md:grid-cols-2 gap-4"> - {/* 일반평가 */} - <Card> - <CardHeader className="pb-3"> - <CardTitle className="text-sm flex items-center gap-2"> - <FileTextIcon className="h-4 w-4" /> - 일반평가 - {completeness.general.isComplete ? ( - <CheckCircleIcon className="h-4 w-4 text-green-600" /> - ) : ( - <XCircleIcon className="h-4 w-4 text-red-600" /> - )} - </CardTitle> - </CardHeader> - <CardContent className="space-y-3"> - <div className="space-y-1"> - <div className="flex items-center justify-between text-xs"> - <span>응답 완료</span> - <span className="font-medium"> - {completeness.general.completed}/{completeness.general.total}개 - </span> - </div> - <Progress value={completeness.general.percentage} className="h-1" /> - <p className="text-xs text-muted-foreground"> - {completeness.general.percentage.toFixed(0)}% 완료 - </p> - </div> - - {!completeness.general.isComplete && ( - <p className="text-xs text-red-600"> - {completeness.general.total - completeness.general.completed}개 항목이 미완료입니다. - </p> - )} - </CardContent> - </Card> - - {/* ESG평가 */} - {isKorean ? ( - <Card> - <CardHeader className="pb-3"> - <CardTitle className="text-sm flex items-center gap-2"> - <ClipboardListIcon className="h-4 w-4" /> - ESG평가 - {completeness.esg.isComplete ? ( - <CheckCircleIcon className="h-4 w-4 text-green-600" /> - ) : ( - <XCircleIcon className="h-4 w-4 text-red-600" /> - )} - </CardTitle> - </CardHeader> - <CardContent className="space-y-3"> - <div className="space-y-1"> - <div className="flex items-center justify-between text-xs"> - <span>응답 완료</span> - <span className="font-medium"> - {completeness.esg.completed}/{completeness.esg.total}개 - </span> - </div> - <Progress value={completeness.esg.percentage} className="h-1" /> - <p className="text-xs text-muted-foreground"> - {completeness.esg.percentage.toFixed(0)}% 완료 - </p> - </div> - - {completeness.esg.completed > 0 && ( - <div className="text-xs"> - <span className="text-muted-foreground">평균 점수: </span> - <span className="font-medium text-blue-600"> - {completeness.esg.averageScore.toFixed(1)}점 - </span> - </div> - )} - - {!completeness.esg.isComplete && ( - <p className="text-xs text-red-600"> - {completeness.esg.total - completeness.esg.completed}개 항목이 미완료입니다. - </p> - )} - </CardContent> - </Card> - ) : ( - <Card> - <CardHeader className="pb-3"> - <CardTitle className="text-sm flex items-center gap-2"> - <ClipboardListIcon className="h-4 w-4" /> - ESG평가 - </CardTitle> - </CardHeader> - <CardContent> - <div className="text-center text-muted-foreground"> - <Badge variant="outline">해당없음</Badge> - <p className="text-xs mt-2">한국 업체가 아니므로 ESG 평가가 제외됩니다.</p> - </div> - </CardContent> - </Card> - )} - </div> - - {/* 제출 상태 알림 */} - {completeness.overall.isComplete ? ( - <Alert> - <CheckCircleIcon className="h-4 w-4" /> - <AlertTitle>제출 준비 완료</AlertTitle> - <AlertDescription> - 모든 평가 항목이 완료되었습니다. 제출하시겠습니까? - </AlertDescription> - </Alert> - ) : ( - <Alert variant="destructive"> - <AlertTriangleIcon className="h-4 w-4" /> - <AlertTitle>제출 불가</AlertTitle> - <AlertDescription> - 아직 완료되지 않은 평가 항목이 있습니다. 모든 항목을 완료한 후 제출해 주세요. - </AlertDescription> - </Alert> - )} - </div> - )} - - <DialogFooter> - <Button variant="outline" onClick={() => onOpenChange(false)}> - 취소 - </Button> - <Button - onClick={handleSubmit} - disabled={!completeness?.overall.isComplete || isSubmitting} - className="min-w-[100px]" - > - {isSubmitting ? ( - <> - <LoaderIcon className="mr-2 h-4 w-4 animate-spin" /> - 제출 중... - </> - ) : ( - <> - <SendIcon className="mr-2 h-4 w-4" /> - 제출하기 - </> - )} - </Button> - </DialogFooter> - </DialogContent> - </Dialog> - ) -}
\ No newline at end of file |
