diff options
| author | joonhoekim <26rote@gmail.com> | 2025-09-15 18:59:41 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-09-15 18:59:41 +0900 |
| commit | d5f26d34c4ac6f3eaac16fbc6069de2c2341a6ff (patch) | |
| tree | ad4ecb476a6fd3b754e741e795bd7a3adbbe03ea /lib/avl/table/standard-avl-add-dialog.tsx | |
| parent | 25b916d040a512cd5248dff319d727ae144d0652 (diff) | |
| parent | 2b490956c9752c1b756780a3461bc1c37b6fe0a7 (diff) | |
[Merge] AVL 및 Vendor-Pool 기능 1차 구현
Diffstat (limited to 'lib/avl/table/standard-avl-add-dialog.tsx')
| -rw-r--r-- | lib/avl/table/standard-avl-add-dialog.tsx | 960 |
1 files changed, 960 insertions, 0 deletions
diff --git a/lib/avl/table/standard-avl-add-dialog.tsx b/lib/avl/table/standard-avl-add-dialog.tsx new file mode 100644 index 00000000..9e8b016c --- /dev/null +++ b/lib/avl/table/standard-avl-add-dialog.tsx @@ -0,0 +1,960 @@ +"use client" + +import * as React from "react" +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { Button } from "@/components/ui/button" +import { Input } from "@/components/ui/input" +import { Label } from "@/components/ui/label" +import { Checkbox } from "@/components/ui/checkbox" +import { Textarea } from "@/components/ui/textarea" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" +import { toast } from "sonner" +import type { AvlVendorInfoInput, AvlDetailItem } from "../types" + +interface StandardAvlAddDialogProps { + open: boolean + onOpenChange: (open: boolean) => void + onAddItem: (item: Omit<AvlVendorInfoInput, 'avlListId'>) => Promise<void> + editingItem?: AvlDetailItem // 수정할 항목 (없으면 추가 모드) + onUpdateItem?: (id: number, item: Omit<AvlVendorInfoInput, 'avlListId'>) => Promise<void> // 수정 핸들러 + // 검색 조건에서 선택한 값들을 초기값으로 사용 + initialConstructionSector?: string + initialShipType?: string + initialAvlKind?: string + initialHtDivision?: string +} + +export function StandardAvlAddDialog({ + open, + onOpenChange, + onAddItem, + editingItem, + onUpdateItem, + initialConstructionSector, + initialShipType, + initialAvlKind, + initialHtDivision +}: StandardAvlAddDialogProps) { + const [formData, setFormData] = React.useState<Omit<AvlVendorInfoInput, 'avlListId'>>({ + // 표준 AVL용 기본 설정 + isTemplate: true, + + // 표준 AVL 필수 필드들 (검색 조건에서 선택한 값들로 초기화) + constructionSector: initialConstructionSector || "", + shipType: initialShipType || "", + avlKind: initialAvlKind || "", + htDivision: initialHtDivision || "", + + // 설계 정보 + equipBulkDivision: "EQUIP", + disciplineCode: "", + disciplineName: "", + + // 자재 정보 + materialNameCustomerSide: "", + + // 패키지 정보 + packageCode: "", + packageName: "", + + // 자재그룹 정보 + materialGroupCode: "", + materialGroupName: "", + + // 협력업체 정보 + vendorName: "", + vendorCode: "", + + // AVL 정보 + avlVendorName: "", + tier: "", + + // 제안방향 + ownerSuggestion: false, + shiSuggestion: false, + + // 위치 정보 + headquarterLocation: "", + manufacturingLocation: "", + + // FA 정보 + faTarget: false, + faStatus: "", + + // Agent 정보 + isAgent: false, + + // 계약 서명주체 + contractSignerName: "", + contractSignerCode: "", + + // SHI Qualification + shiAvl: false, + shiBlacklist: false, + shiBcc: false, + + // 기술영업 견적결과 + salesQuoteNumber: "", + quoteCode: "", + salesVendorInfo: "", + salesCountry: "", + totalAmount: "", + quoteReceivedDate: "", + + // 업체 실적 현황 + recentQuoteDate: "", + recentQuoteNumber: "", + recentOrderDate: "", + recentOrderNumber: "", + + // 기타 + remarks: "" + }) + + // 수정 모드일 때 폼 데이터 초기화 + React.useEffect(() => { + if (editingItem) { + setFormData({ + // 표준 AVL용 기본 설정 + isTemplate: true, + + // 표준 AVL 필수 필드들 (기존 값 우선, 없으면 검색 조건 값 사용) + constructionSector: editingItem.constructionSector || initialConstructionSector || "", + shipType: editingItem.shipType || initialShipType || "", + avlKind: editingItem.avlKind || initialAvlKind || "", + htDivision: editingItem.htDivision || initialHtDivision || "", + + // 설계 정보 + equipBulkDivision: editingItem.equipBulkDivision === "EQUIP" ? "EQUIP" : "BULK", + disciplineCode: editingItem.disciplineCode || "", + disciplineName: editingItem.disciplineName || "", + + // 자재 정보 + materialNameCustomerSide: editingItem.materialNameCustomerSide || "", + + // 패키지 정보 + packageCode: editingItem.packageCode || "", + packageName: editingItem.packageName || "", + + // 자재그룹 정보 + materialGroupCode: editingItem.materialGroupCode || "", + materialGroupName: editingItem.materialGroupName || "", + + // 협력업체 정보 + vendorName: editingItem.vendorName || "", + vendorCode: editingItem.vendorCode || "", + + // AVL 정보 + avlVendorName: editingItem.avlVendorName || "", + tier: editingItem.tier || "", + + // 제안방향 + ownerSuggestion: editingItem.ownerSuggestion || false, + shiSuggestion: editingItem.shiSuggestion || false, + + // 위치 정보 + headquarterLocation: editingItem.headquarterLocation || "", + manufacturingLocation: editingItem.manufacturingLocation || "", + + // FA 정보 + faTarget: editingItem.faTarget || false, + faStatus: editingItem.faStatus || "", + + // Agent 정보 + isAgent: editingItem.isAgent || false, + + // 계약 서명주체 + contractSignerName: editingItem.contractSignerName || "", + contractSignerCode: editingItem.contractSignerCode || "", + + // SHI Qualification + shiAvl: editingItem.shiAvl || false, + shiBlacklist: editingItem.shiBlacklist || false, + shiBcc: editingItem.shiBcc || false, + + // 기술영업 견적결과 + salesQuoteNumber: editingItem.salesQuoteNumber || "", + quoteCode: editingItem.quoteCode || "", + salesVendorInfo: editingItem.salesVendorInfo || "", + salesCountry: editingItem.salesCountry || "", + totalAmount: editingItem.totalAmount || "", + quoteReceivedDate: editingItem.quoteReceivedDate || "", + + // 업체 실적 현황 + recentQuoteDate: editingItem.recentQuoteDate || "", + recentQuoteNumber: editingItem.recentQuoteNumber || "", + recentOrderDate: editingItem.recentOrderDate || "", + recentOrderNumber: editingItem.recentOrderNumber || "", + + // 기타 + remarks: editingItem.remarks || "" + }) + } + }, [editingItem, initialConstructionSector, initialShipType, initialAvlKind, initialHtDivision]) + + // 다이얼로그가 열릴 때 초기값 재설정 (수정 모드가 아닐 때만) + React.useEffect(() => { + if (open && !editingItem) { + setFormData(prev => ({ + ...prev, + constructionSector: initialConstructionSector || "", + shipType: initialShipType || "", + avlKind: initialAvlKind || "", + htDivision: initialHtDivision || "", + })) + } + }, [open, editingItem, initialConstructionSector, initialShipType, initialAvlKind, initialHtDivision]) + + const handleSubmit = async () => { + // 필수 필드 검증 (표준 AVL용) + if (!formData.constructionSector || !formData.shipType || !formData.avlKind || !formData.htDivision) { + toast.error("공사부문, 선종, AVL종류, H/T 구분은 필수 입력 항목입니다.") + return + } + + if (!formData.disciplineName || !formData.materialNameCustomerSide) { + toast.error("설계공종과 고객사 AVL 자재명은 필수 입력 항목입니다.") + return + } + + try { + if (editingItem && onUpdateItem) { + // 수정 모드 + await onUpdateItem(editingItem.id, formData) + } else { + // 추가 모드 + await onAddItem(formData) + } + + // 폼 초기화 (onAddItem에서 성공적으로 처리된 경우에만) + setFormData({ + // 표준 AVL용 기본 설정 + isTemplate: true, + + // 표준 AVL 필수 필드들 + constructionSector: "", + shipType: "", + avlKind: "", + htDivision: "", + + // 설계 정보 + equipBulkDivision: "EQUIP", + disciplineCode: "", + disciplineName: "", + + // 자재 정보 + materialNameCustomerSide: "", + + // 패키지 정보 + packageCode: "", + packageName: "", + + // 자재그룹 정보 + materialGroupCode: "", + materialGroupName: "", + + // 협력업체 정보 + vendorName: "", + vendorCode: "", + + // AVL 정보 + avlVendorName: "", + tier: "", + + // 제안방향 + ownerSuggestion: false, + shiSuggestion: false, + + // 위치 정보 + headquarterLocation: "", + manufacturingLocation: "", + + // FA 정보 + faTarget: false, + faStatus: "", + + // Agent 정보 + isAgent: false, + + // 계약 서명주체 + contractSignerName: "", + contractSignerCode: "", + + // SHI Qualification + shiAvl: false, + shiBlacklist: false, + shiBcc: false, + + // 기술영업 견적결과 + salesQuoteNumber: "", + quoteCode: "", + salesVendorInfo: "", + salesCountry: "", + totalAmount: "", + quoteReceivedDate: "", + + // 업체 실적 현황 + recentQuoteDate: "", + recentQuoteNumber: "", + recentOrderDate: "", + recentOrderNumber: "", + + // 기타 + remarks: "" + } as Omit<AvlVendorInfoInput, 'avlListId'>) + + onOpenChange(false) + } catch (error) { + // 에러 처리는 onAddItem에서 담당하므로 여기서는 아무것도 하지 않음 + } + } + + const handleCancel = () => { + setFormData({ + // 표준 AVL용 기본 설정 + isTemplate: true, + + // 표준 AVL 필수 필드들 + constructionSector: "", + shipType: "", + avlKind: "", + htDivision: "", + + // 설계 정보 + equipBulkDivision: "EQUIP", + disciplineCode: "", + disciplineName: "", + + // 자재 정보 + materialNameCustomerSide: "", + + // 패키지 정보 + packageCode: "", + packageName: "", + + // 자재그룹 정보 + materialGroupCode: "", + materialGroupName: "", + + // 협력업체 정보 + vendorName: "", + vendorCode: "", + + // AVL 정보 + avlVendorName: "", + tier: "", + + // 제안방향 + ownerSuggestion: false, + shiSuggestion: false, + + // 위치 정보 + headquarterLocation: "", + manufacturingLocation: "", + + // FA 정보 + faTarget: false, + faStatus: "", + + // Agent 정보 + isAgent: false, + + // 계약 서명주체 + contractSignerName: "", + contractSignerCode: "", + + // SHI Qualification + shiAvl: false, + shiBlacklist: false, + shiBcc: false, + + // 기술영업 견적결과 + salesQuoteNumber: "", + quoteCode: "", + salesVendorInfo: "", + salesCountry: "", + totalAmount: "", + quoteReceivedDate: "", + + // 업체 실적 현황 + recentQuoteDate: "", + recentQuoteNumber: "", + recentOrderDate: "", + recentOrderNumber: "", + + // 기타 + remarks: "" + } as Omit<AvlVendorInfoInput, 'avlListId'>) + onOpenChange(false) + } + + // 선종 옵션들 (공사부문에 따라 다름) + const getShipTypeOptions = (constructionSector: string) => { + if (constructionSector === "조선") { + return [ + { value: "A-max", label: "A-max" }, + { value: "S-max", label: "S-max" }, + { value: "VLCC", label: "VLCC" }, + { value: "LNGC", label: "LNGC" }, + { value: "CONT", label: "CONT" }, + ] + } else if (constructionSector === "해양") { + return [ + { value: "FPSO", label: "FPSO" }, + { value: "FLNG", label: "FLNG" }, + { value: "FPU", label: "FPU" }, + { value: "Platform", label: "Platform" }, + { value: "WTIV", label: "WTIV" }, + { value: "GOM", label: "GOM" }, + ] + } else { + return [] + } + } + + const shipTypeOptions = getShipTypeOptions(formData.constructionSector) + + return ( + <Dialog open={open} onOpenChange={onOpenChange}> + <DialogContent className="sm:max-w-[800px] max-h-[90vh] overflow-y-auto"> + <DialogHeader> + <DialogTitle>{editingItem ? "표준 AVL 항목 수정" : "표준 AVL 항목 추가"}</DialogTitle> + <DialogDescription> + {editingItem + ? "표준 AVL 항목을 수정합니다. 필수 항목을 입력해주세요." + : "새로운 표준 AVL 항목을 추가합니다. 필수 항목을 입력해주세요." + } * 표시된 항목은 필수 입력사항입니다. + </DialogDescription> + </DialogHeader> + <div className="space-y-6 py-4"> + {/* 표준 AVL 기본 정보 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">표준 AVL 기본 정보 *</h4> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="constructionSector">공사부문 *</Label> + <Select + value={formData.constructionSector} + onValueChange={(value) => { + setFormData(prev => ({ + ...prev, + constructionSector: value, + shipType: "" // 공사부문 변경 시 선종 초기화 + })) + }} + > + <SelectTrigger> + <SelectValue placeholder="공사부문을 선택하세요" /> + </SelectTrigger> + <SelectContent> + <SelectItem value="조선">조선</SelectItem> + <SelectItem value="해양">해양</SelectItem> + </SelectContent> + </Select> + </div> + <div className="space-y-2"> + <Label htmlFor="shipType">선종 *</Label> + <Select + value={formData.shipType} + onValueChange={(value) => + setFormData(prev => ({ ...prev, shipType: value })) + } + disabled={!formData.constructionSector} + > + <SelectTrigger> + <SelectValue placeholder="선종을 선택하세요" /> + </SelectTrigger> + <SelectContent> + {shipTypeOptions.map((option) => ( + <SelectItem key={option.value} value={option.value}> + {option.label} + </SelectItem> + ))} + </SelectContent> + </Select> + </div> + <div className="space-y-2"> + <Label htmlFor="avlKind">AVL종류 *</Label> + <Select + value={formData.avlKind} + onValueChange={(value) => + setFormData(prev => ({ ...prev, avlKind: value })) + } + > + <SelectTrigger> + <SelectValue placeholder="AVL종류를 선택하세요" /> + </SelectTrigger> + <SelectContent> + <SelectItem value="Nearshore">Nearshore</SelectItem> + <SelectItem value="Offshore">Offshore</SelectItem> + <SelectItem value="IOC">IOC</SelectItem> + <SelectItem value="NOC">NOC</SelectItem> + </SelectContent> + </Select> + </div> + <div className="space-y-2"> + <Label htmlFor="htDivision">H/T 구분 *</Label> + <Select + value={formData.htDivision} + onValueChange={(value) => + setFormData(prev => ({ ...prev, htDivision: value })) + } + > + <SelectTrigger> + <SelectValue placeholder="H/T 구분을 선택하세요" /> + </SelectTrigger> + <SelectContent> + <SelectItem value="공통">공통</SelectItem> + <SelectItem value="H">Hull (H)</SelectItem> + <SelectItem value="T">Topside (T)</SelectItem> + </SelectContent> + </Select> + </div> + </div> + </div> + + {/* 기본 정보 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">기본 정보</h4> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="equipBulkDivision">EQUIP/BULK 구분</Label> + <Select + value={formData.equipBulkDivision} + onValueChange={(value: "EQUIP" | "BULK") => + setFormData(prev => ({ ...prev, equipBulkDivision: value })) + } + > + <SelectTrigger> + <SelectValue /> + </SelectTrigger> + <SelectContent> + <SelectItem value="EQUIP">EQUIP</SelectItem> + <SelectItem value="BULK">BULK</SelectItem> + </SelectContent> + </Select> + </div> + <div className="space-y-2"> + <Label htmlFor="disciplineCode">설계공종코드</Label> + <Input + id="disciplineCode" + value={formData.disciplineCode} + onChange={(e) => setFormData(prev => ({ ...prev, disciplineCode: e.target.value }))} + placeholder="설계공종코드를 입력하세요" + /> + </div> + <div className="space-y-2 col-span-2"> + <Label htmlFor="disciplineName">설계공종명 *</Label> + <Input + id="disciplineName" + value={formData.disciplineName} + onChange={(e) => setFormData(prev => ({ ...prev, disciplineName: e.target.value }))} + placeholder="설계공종명을 입력하세요" + /> + </div> + <div className="space-y-2 col-span-2"> + <Label htmlFor="materialNameCustomerSide">고객사 AVL 자재명 *</Label> + <Input + id="materialNameCustomerSide" + value={formData.materialNameCustomerSide} + onChange={(e) => setFormData(prev => ({ ...prev, materialNameCustomerSide: e.target.value }))} + placeholder="고객사 AVL 자재명을 입력하세요" + /> + </div> + </div> + </div> + + {/* 패키지 정보 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">패키지 정보</h4> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="packageCode">패키지 코드</Label> + <Input + id="packageCode" + value={formData.packageCode} + onChange={(e) => setFormData(prev => ({ ...prev, packageCode: e.target.value }))} + placeholder="패키지 코드를 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="packageName">패키지 명</Label> + <Input + id="packageName" + value={formData.packageName} + onChange={(e) => setFormData(prev => ({ ...prev, packageName: e.target.value }))} + placeholder="패키지 명을 입력하세요" + /> + </div> + </div> + </div> + + {/* 자재그룹 정보 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">자재그룹 정보</h4> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="materialGroupCode">자재그룹 코드</Label> + <Input + id="materialGroupCode" + value={formData.materialGroupCode} + onChange={(e) => setFormData(prev => ({ ...prev, materialGroupCode: e.target.value }))} + placeholder="자재그룹 코드를 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="materialGroupName">자재그룹 명</Label> + <Input + id="materialGroupName" + value={formData.materialGroupName} + onChange={(e) => setFormData(prev => ({ ...prev, materialGroupName: e.target.value }))} + placeholder="자재그룹 명을 입력하세요" + /> + </div> + </div> + </div> + + {/* 협력업체 정보 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">협력업체 정보</h4> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="vendorCode">협력업체 코드</Label> + <Input + id="vendorCode" + value={formData.vendorCode} + onChange={(e) => setFormData(prev => ({ ...prev, vendorCode: e.target.value }))} + placeholder="협력업체 코드를 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="vendorName">협력업체 명</Label> + <Input + id="vendorName" + value={formData.vendorName} + onChange={(e) => setFormData(prev => ({ ...prev, vendorName: e.target.value }))} + placeholder="협력업체 명을 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="avlVendorName">AVL 등재업체명</Label> + <Input + id="avlVendorName" + value={formData.avlVendorName} + onChange={(e) => setFormData(prev => ({ ...prev, avlVendorName: e.target.value }))} + placeholder="AVL 등재업체명을 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="tier">등급 (Tier)</Label> + <Input + id="tier" + value={formData.tier} + onChange={(e) => setFormData(prev => ({ ...prev, tier: e.target.value }))} + placeholder="등급을 입력하세요" + /> + </div> + </div> + </div> + + {/* 제안방향 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">제안방향</h4> + <div className="flex gap-6"> + <div className="flex items-center space-x-2"> + <Checkbox + id="ownerSuggestion" + checked={formData.ownerSuggestion} + onCheckedChange={(checked) => + setFormData(prev => ({ ...prev, ownerSuggestion: !!checked })) + } + /> + <Label htmlFor="ownerSuggestion">선주제안</Label> + </div> + <div className="flex items-center space-x-2"> + <Checkbox + id="shiSuggestion" + checked={formData.shiSuggestion} + onCheckedChange={(checked) => + setFormData(prev => ({ ...prev, shiSuggestion: !!checked })) + } + /> + <Label htmlFor="shiSuggestion">SHI 제안</Label> + </div> + </div> + </div> + + {/* 위치 정보 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">위치 정보</h4> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="headquarterLocation">본사 위치 (국가)</Label> + <Input + id="headquarterLocation" + value={formData.headquarterLocation} + onChange={(e) => setFormData(prev => ({ ...prev, headquarterLocation: e.target.value }))} + placeholder="본사 위치를 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="manufacturingLocation">제작/선적지 (국가)</Label> + <Input + id="manufacturingLocation" + value={formData.manufacturingLocation} + onChange={(e) => setFormData(prev => ({ ...prev, manufacturingLocation: e.target.value }))} + placeholder="제작/선적지를 입력하세요" + /> + </div> + </div> + </div> + + {/* FA 정보 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">FA 정보</h4> + <div className="grid grid-cols-2 gap-4"> + <div className="flex items-center space-x-2"> + <Checkbox + id="faTarget" + checked={formData.faTarget} + onCheckedChange={(checked) => + setFormData(prev => ({ ...prev, faTarget: !!checked })) + } + /> + <Label htmlFor="faTarget">FA 대상</Label> + </div> + <div className="space-y-2"> + <Label htmlFor="faStatus">FA 현황</Label> + <Input + id="faStatus" + value={formData.faStatus} + onChange={(e) => setFormData(prev => ({ ...prev, faStatus: e.target.value }))} + placeholder="FA 현황을 입력하세요" + /> + </div> + </div> + </div> + + {/* Agent 정보 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">Agent 정보</h4> + <div className="flex items-center space-x-2"> + <Checkbox + id="isAgent" + checked={formData.isAgent} + onCheckedChange={(checked) => + setFormData(prev => ({ ...prev, isAgent: !!checked })) + } + /> + <Label htmlFor="isAgent">Agent 여부</Label> + </div> + </div> + + {/* 계약 서명주체 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">계약 서명주체</h4> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="contractSignerCode">계약서명주체 코드</Label> + <Input + id="contractSignerCode" + value={formData.contractSignerCode} + onChange={(e) => setFormData(prev => ({ ...prev, contractSignerCode: e.target.value }))} + placeholder="계약서명주체 코드를 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="contractSignerName">계약서명주체 명</Label> + <Input + id="contractSignerName" + value={formData.contractSignerName} + onChange={(e) => setFormData(prev => ({ ...prev, contractSignerName: e.target.value }))} + placeholder="계약서명주체 명을 입력하세요" + /> + </div> + </div> + </div> + + {/* SHI Qualification */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">SHI Qualification</h4> + <div className="flex gap-6"> + <div className="flex items-center space-x-2"> + <Checkbox + id="shiAvl" + checked={formData.shiAvl} + onCheckedChange={(checked) => + setFormData(prev => ({ ...prev, shiAvl: !!checked })) + } + /> + <Label htmlFor="shiAvl">AVL</Label> + </div> + <div className="flex items-center space-x-2"> + <Checkbox + id="shiBlacklist" + checked={formData.shiBlacklist} + onCheckedChange={(checked) => + setFormData(prev => ({ ...prev, shiBlacklist: !!checked })) + } + /> + <Label htmlFor="shiBlacklist">Blacklist</Label> + </div> + <div className="flex items-center space-x-2"> + <Checkbox + id="shiBcc" + checked={formData.shiBcc} + onCheckedChange={(checked) => + setFormData(prev => ({ ...prev, shiBcc: !!checked })) + } + /> + <Label htmlFor="shiBcc">BCC</Label> + </div> + </div> + </div> + + {/* 기술영업 견적결과 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">기술영업 견적결과</h4> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="salesQuoteNumber">기술영업 견적번호</Label> + <Input + id="salesQuoteNumber" + value={formData.salesQuoteNumber} + onChange={(e) => setFormData(prev => ({ ...prev, salesQuoteNumber: e.target.value }))} + placeholder="기술영업 견적번호를 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="quoteCode">견적서 Code</Label> + <Input + id="quoteCode" + value={formData.quoteCode} + onChange={(e) => setFormData(prev => ({ ...prev, quoteCode: e.target.value }))} + placeholder="견적서 Code를 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="salesVendorInfo">견적 협력업체 명</Label> + <Input + id="salesVendorInfo" + value={formData.salesVendorInfo} + onChange={(e) => setFormData(prev => ({ ...prev, salesVendorInfo: e.target.value }))} + placeholder="견적 협력업체 명을 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="salesCountry">국가</Label> + <Input + id="salesCountry" + value={formData.salesCountry} + onChange={(e) => setFormData(prev => ({ ...prev, salesCountry: e.target.value }))} + placeholder="국가를 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="totalAmount">총 금액</Label> + <Input + id="totalAmount" + type="number" + value={formData.totalAmount} + onChange={(e) => setFormData(prev => ({ ...prev, totalAmount: e.target.value }))} + placeholder="총 금액을 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="quoteReceivedDate">견적접수일 (YYYY-MM-DD)</Label> + <Input + id="quoteReceivedDate" + value={formData.quoteReceivedDate} + onChange={(e) => setFormData(prev => ({ ...prev, quoteReceivedDate: e.target.value }))} + placeholder="YYYY-MM-DD" + /> + </div> + </div> + </div> + + {/* 업체 실적 현황 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">업체 실적 현황</h4> + <div className="grid grid-cols-2 gap-4"> + <div className="space-y-2"> + <Label htmlFor="recentQuoteNumber">최근견적번호</Label> + <Input + id="recentQuoteNumber" + value={formData.recentQuoteNumber} + onChange={(e) => setFormData(prev => ({ ...prev, recentQuoteNumber: e.target.value }))} + placeholder="최근견적번호를 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="recentQuoteDate">최근견적일 (YYYY-MM-DD)</Label> + <Input + id="recentQuoteDate" + value={formData.recentQuoteDate} + onChange={(e) => setFormData(prev => ({ ...prev, recentQuoteDate: e.target.value }))} + placeholder="YYYY-MM-DD" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="recentOrderNumber">최근발주번호</Label> + <Input + id="recentOrderNumber" + value={formData.recentOrderNumber} + onChange={(e) => setFormData(prev => ({ ...prev, recentOrderNumber: e.target.value }))} + placeholder="최근발주번호를 입력하세요" + /> + </div> + <div className="space-y-2"> + <Label htmlFor="recentOrderDate">최근발주일 (YYYY-MM-DD)</Label> + <Input + id="recentOrderDate" + value={formData.recentOrderDate} + onChange={(e) => setFormData(prev => ({ ...prev, recentOrderDate: e.target.value }))} + placeholder="YYYY-MM-DD" + /> + </div> + </div> + </div> + + {/* 기타 */} + <div className="space-y-4"> + <h4 className="text-sm font-semibold text-muted-foreground border-b pb-2">기타</h4> + <div className="space-y-2"> + <Label htmlFor="remarks">비고</Label> + <Textarea + id="remarks" + value={formData.remarks} + onChange={(e) => setFormData(prev => ({ ...prev, remarks: e.target.value }))} + placeholder="비고를 입력하세요" + rows={3} + /> + </div> + </div> + </div> + <DialogFooter> + <Button type="button" variant="outline" onClick={handleCancel}> + 취소 + </Button> + <Button type="button" onClick={handleSubmit}> + {editingItem ? "수정" : "추가"} + </Button> + </DialogFooter> + </DialogContent> + </Dialog> + ) +} |
