diff options
Diffstat (limited to 'components/investigation/supplement-request-dialog.tsx')
| -rw-r--r-- | components/investigation/supplement-request-dialog.tsx | 336 |
1 files changed, 336 insertions, 0 deletions
diff --git a/components/investigation/supplement-request-dialog.tsx b/components/investigation/supplement-request-dialog.tsx new file mode 100644 index 00000000..c0af36c7 --- /dev/null +++ b/components/investigation/supplement-request-dialog.tsx @@ -0,0 +1,336 @@ +"use client" + +import * as React from "react" +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog" +import { Button } from "@/components/ui/button" +import { Textarea } from "@/components/ui/textarea" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" +import { Badge } from "@/components/ui/badge" +import { useToast } from "@/hooks/use-toast" +import { + requestSupplementReinspectionAction, + requestSupplementDocumentAction +} from "@/lib/vendor-investigation/service" + +interface SupplementRequestDialogProps { + open: boolean + onOpenChange: (open: boolean) => void + investigationId: number + investigationMethod: string + vendorName: string +} + +export function SupplementRequestDialog({ + open, + onOpenChange, + investigationId, + investigationMethod, + vendorName +}: SupplementRequestDialogProps) { + const { toast } = useToast() + const [isSubmitting, setIsSubmitting] = React.useState(false) + const [requestType, setRequestType] = React.useState<"REINSPECT" | "DOCUMENT">("REINSPECT") + + // 재실사 요청 데이터 + const [reinspectData, setReinspectData] = React.useState({ + inspectionDuration: 1.0, + requestedStartDate: "", + requestedEndDate: "", + additionalRequests: "" + }) + + // 서류제출 요청 데이터 + const [documentData, setDocumentData] = React.useState({ + requiredDocuments: [""], + additionalRequests: "" + }) + + // 보완 요청이 가능한 실사 방법인지 확인 + const canRequestSupplement = investigationMethod === "PRODUCT_INSPECTION" || + investigationMethod === "SITE_VISIT_EVAL" + + const handleSubmit = async () => { + if (!canRequestSupplement) { + toast({ + title: "보완 요청 불가", + description: "현재 실사 방법에서는 보완 요청을 할 수 없습니다.", + variant: "destructive" + }) + return + } + + try { + setIsSubmitting(true) + + if (requestType === "REINSPECT") { + const result = await requestSupplementReinspectionAction({ + investigationId, + siteVisitData: { + inspectionDuration: reinspectData.inspectionDuration, + requestedStartDate: reinspectData.requestedStartDate ? new Date(reinspectData.requestedStartDate) : undefined, + requestedEndDate: reinspectData.requestedEndDate ? new Date(reinspectData.requestedEndDate) : undefined, + additionalRequests: reinspectData.additionalRequests + } + }) + + if (result.success) { + toast({ + title: "보완-재실사 요청 완료", + description: "재실사 요청이 성공적으로 생성되었습니다.", + }) + onOpenChange(false) + } else { + toast({ + title: "요청 실패", + description: result.error || "재실사 요청 중 오류가 발생했습니다.", + variant: "destructive" + }) + } + } else { + const result = await requestSupplementDocumentAction({ + investigationId, + documentRequests: { + requiredDocuments: documentData.requiredDocuments.filter(doc => doc.trim() !== ""), + additionalRequests: documentData.additionalRequests + } + }) + + if (result.success) { + toast({ + title: "보완-서류제출 요청 완료", + description: "서류제출 요청이 성공적으로 생성되었습니다.", + }) + onOpenChange(false) + } else { + toast({ + title: "요청 실패", + description: result.error || "서류제출 요청 중 오류가 발생했습니다.", + variant: "destructive" + }) + } + } + } catch (error) { + console.error("보완 요청 오류:", error) + toast({ + title: "요청 실패", + description: "보완 요청 중 오류가 발생했습니다.", + variant: "destructive" + }) + } finally { + setIsSubmitting(false) + } + } + + const addDocument = () => { + setDocumentData(prev => ({ + ...prev, + requiredDocuments: [...prev.requiredDocuments, ""] + })) + } + + const removeDocument = (index: number) => { + setDocumentData(prev => ({ + ...prev, + requiredDocuments: prev.requiredDocuments.filter((_, i) => i !== index) + })) + } + + const updateDocument = (index: number, value: string) => { + setDocumentData(prev => ({ + ...prev, + requiredDocuments: prev.requiredDocuments.map((doc, i) => i === index ? value : doc) + })) + } + + if (!canRequestSupplement) { + return ( + <Dialog open={open} onOpenChange={onOpenChange}> + <DialogContent> + <DialogHeader> + <DialogTitle>보완 요청 불가</DialogTitle> + <DialogDescription> + 현재 실사 방법({investigationMethod})에서는 보완 요청을 할 수 없습니다. + 보완 요청은 제품검사평가(PRODUCT_INSPECTION) 또는 방문실사평가(SITE_VISIT_EVAL)에서만 가능합니다. + </DialogDescription> + </DialogHeader> + <DialogFooter> + <Button variant="outline" onClick={() => onOpenChange(false)}> + 확인 + </Button> + </DialogFooter> + </DialogContent> + </Dialog> + ) + } + + return ( + <Dialog open={open} onOpenChange={onOpenChange}> + <DialogContent className="max-w-2xl"> + <DialogHeader> + <DialogTitle>보완 요청</DialogTitle> + <DialogDescription> + {vendorName}에 대한 보완 요청을 생성합니다. + </DialogDescription> + </DialogHeader> + + <div className="space-y-6"> + {/* 요청 유형 선택 */} + <div className="space-y-2"> + <Label>보완 요청 유형</Label> + <div className="flex gap-4"> + <Button + type="button" + variant={requestType === "REINSPECT" ? "default" : "outline"} + onClick={() => setRequestType("REINSPECT")} + > + 보완-재실사 + </Button> + <Button + type="button" + variant={requestType === "DOCUMENT" ? "default" : "outline"} + onClick={() => setRequestType("DOCUMENT")} + > + 보완-서류제출 + </Button> + </div> + </div> + + {/* 재실사 요청 폼 */} + {requestType === "REINSPECT" && ( + <div className="space-y-4"> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="duration">실사 기간 (일)</Label> + <Input + id="duration" + type="number" + step="0.1" + min="0.1" + value={reinspectData.inspectionDuration} + onChange={(e) => setReinspectData(prev => ({ + ...prev, + inspectionDuration: parseFloat(e.target.value) || 0 + }))} + /> + </div> + <div className="space-y-2"> + <Label>실사 방법</Label> + <Badge variant="outline"> + {investigationMethod === "PRODUCT_INSPECTION" ? "제품검사평가" : "방문실사평가"} + </Badge> + </div> + </div> + + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="startDate">요청 시작일</Label> + <Input + id="startDate" + type="date" + value={reinspectData.requestedStartDate} + onChange={(e) => setReinspectData(prev => ({ + ...prev, + requestedStartDate: e.target.value + }))} + /> + </div> + <div className="space-y-2"> + <Label htmlFor="endDate">요청 종료일</Label> + <Input + id="endDate" + type="date" + value={reinspectData.requestedEndDate} + onChange={(e) => setReinspectData(prev => ({ + ...prev, + requestedEndDate: e.target.value + }))} + /> + </div> + </div> + + <div className="space-y-2"> + <Label htmlFor="reinspectRequests">추가 요청사항</Label> + <Textarea + id="reinspectRequests" + placeholder="재실사에 대한 추가 요청사항을 입력하세요" + value={reinspectData.additionalRequests} + onChange={(e) => setReinspectData(prev => ({ + ...prev, + additionalRequests: e.target.value + }))} + className="min-h-20" + /> + </div> + </div> + )} + + {/* 서류제출 요청 폼 */} + {requestType === "DOCUMENT" && ( + <div className="space-y-4"> + <div className="space-y-2"> + <Label>필요 서류 목록</Label> + {documentData.requiredDocuments.map((doc, index) => ( + <div key={index} className="flex gap-2"> + <Input + placeholder="필요한 서류명을 입력하세요" + value={doc} + onChange={(e) => updateDocument(index, e.target.value)} + /> + <Button + type="button" + variant="outline" + size="sm" + onClick={() => removeDocument(index)} + disabled={documentData.requiredDocuments.length === 1} + > + 삭제 + </Button> + </div> + ))} + <Button + type="button" + variant="outline" + size="sm" + onClick={addDocument} + > + 서류 추가 + </Button> + </div> + + <div className="space-y-2"> + <Label htmlFor="documentRequests">추가 요청사항</Label> + <Textarea + id="documentRequests" + placeholder="서류제출에 대한 추가 요청사항을 입력하세요" + value={documentData.additionalRequests} + onChange={(e) => setDocumentData(prev => ({ + ...prev, + additionalRequests: e.target.value + }))} + className="min-h-20" + /> + </div> + </div> + )} + </div> + + <DialogFooter> + <Button variant="outline" onClick={() => onOpenChange(false)}> + 취소 + </Button> + <Button onClick={handleSubmit} disabled={isSubmitting}> + {isSubmitting ? "요청 중..." : "보완 요청"} + </Button> + </DialogFooter> + </DialogContent> + </Dialog> + ) +} |
