summaryrefslogtreecommitdiff
path: root/components/investigation/supplement-request-dialog.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'components/investigation/supplement-request-dialog.tsx')
-rw-r--r--components/investigation/supplement-request-dialog.tsx336
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>
+ )
+}