"use client"; import { useState, useEffect } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Checkbox } from "@/components/ui/checkbox"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; import { toast } from "sonner"; import { FileText, Building2, User, Phone, Mail } from "lucide-react"; import type { VendorRegularRegistration } from "@/config/vendorRegularRegistrationsColumnsConfig"; import { fetchRegistrationRequestData } from "@/lib/vendor-regular-registrations/service"; interface RegistrationRequestDialogProps { open: boolean; onOpenChange: (open: boolean) => void; registration: VendorRegularRegistration | null; onSubmit?: (data: RegistrationRequestData) => void; } export interface RegistrationRequestData { // 업체정보 companyNameKor: string; companyNameEng: string; businessNumber: string; corporateNumber: string; majorItems: string; establishmentDate: string; // 소재지 headOfficeAddress: string; headOfficePhone: string; factoryAddress: string; factoryPhone: string; salesOfficeAddress: string; salesOfficePhone: string; // 대표자 정보 representativeNameKor: string; representativeNameEng: string; representativeContact: string; representativeBirthDate: string; representativeEmail: string; isWorkingAtCompany: boolean; isInternalPartner: boolean; // 대표자 경력 representativeCareer: Array<{ date: string; content: string; }>; // 업무담당자 businessContacts: { sales: { name: string; position: string; department: string; responsibility: string; email: string; }; design: { name: string; position: string; department: string; responsibility: string; email: string; }; delivery: { name: string; position: string; department: string; responsibility: string; email: string; }; quality: { name: string; position: string; department: string; responsibility: string; email: string; }; taxInvoice: { name: string; position: string; department: string; responsibility: string; email: string; }; }; } export function RegistrationRequestDialog({ open, onOpenChange, registration, onSubmit, }: RegistrationRequestDialogProps) { const [loading, setLoading] = useState(false); const [dataLoading, setDataLoading] = useState(false); const [formData, setFormData] = useState({ // 업체정보 (기본값 설정) companyNameKor: "", companyNameEng: "", businessNumber: "", corporateNumber: "", majorItems: "", establishmentDate: "", // 소재지 headOfficeAddress: "", headOfficePhone: "", factoryAddress: "", factoryPhone: "", salesOfficeAddress: "", salesOfficePhone: "", // 대표자 정보 representativeNameKor: "", representativeNameEng: "", representativeContact: "", representativeBirthDate: "", representativeEmail: "", isWorkingAtCompany: false, isInternalPartner: false, // 대표자 경력 representativeCareer: [{ date: "", content: "" }], // 업무담당자 businessContacts: { sales: { name: "", position: "", department: "", responsibility: "", email: "" }, design: { name: "", position: "", department: "", responsibility: "", email: "" }, delivery: { name: "", position: "", department: "", responsibility: "", email: "" }, quality: { name: "", position: "", department: "", responsibility: "", email: "" }, taxInvoice: { name: "", position: "", department: "", responsibility: "", email: "" }, }, }); // 기존 데이터 로드 및 자동 입력 useEffect(() => { if (open && registration?.id) { loadExistingData(); } }, [open, registration?.id]); const loadExistingData = async () => { if (!registration?.id) return; setDataLoading(true); try { const result = await fetchRegistrationRequestData(registration.id); if (result.success && result.data) { const { vendor, businessContacts, additionalInfo } = result.data; // 업무담당자 데이터 변환 const contactsMap = { sales: { name: "", position: "", department: "", responsibility: "", email: "" }, design: { name: "", position: "", department: "", responsibility: "", email: "" }, delivery: { name: "", position: "", department: "", responsibility: "", email: "" }, quality: { name: "", position: "", department: "", responsibility: "", email: "" }, taxInvoice: { name: "", position: "", department: "", responsibility: "", email: "" }, }; console.log("🔍 업무담당자 데이터 매핑:", { businessContacts: businessContacts.map(c => ({ contactType: c.contactType, contactName: c.contactName })), contactsMapKeys: Object.keys(contactsMap) }); businessContacts.forEach(contact => { let mappedType = contact.contactType; // DB의 snake_case를 camelCase로 변환 if (contact.contactType === 'tax_invoice') { mappedType = 'taxInvoice'; } if (mappedType in contactsMap) { contactsMap[mappedType as keyof typeof contactsMap] = { name: contact.contactName || "", position: contact.position || "", department: contact.department || "", responsibility: contact.responsibility || "", email: contact.email || "", }; console.log(`✅ 매핑 성공: ${contact.contactType} -> ${mappedType}`, { name: contact.contactName, position: contact.position }); } else { console.warn(`❌ 매핑 실패: ${contact.contactType} -> ${mappedType} not found in contactsMap`); } }); // 날짜 포맷팅 함수 const formatDate = (date: Date | string | null) => { if (!date) return ""; try { const d = new Date(date); // Invalid Date 체크 if (isNaN(d.getTime())) return ""; return d.toISOString().split('T')[0]; // YYYY-MM-DD 형식 } catch (error) { console.warn("날짜 포맷팅 오류:", date, error); return ""; } }; // 폼 데이터 업데이트 setFormData({ // 업체정보 companyNameKor: vendor.vendorName || "", companyNameEng: "", // TODO: 영문명이 있다면 추가 businessNumber: vendor.taxId || "", corporateNumber: vendor.corporateRegistrationNumber || "", majorItems: registration.majorItems || "", establishmentDate: "", // vendors 테이블에 establishmentDate 필드가 없음 // 소재지 (vendors 테이블에는 address, phone만 있음) headOfficeAddress: vendor.address || "", headOfficePhone: vendor.phone || "", factoryAddress: "", // vendors 테이블에 공장주소 필드가 없음 factoryPhone: "", // vendors 테이블에 공장전화 필드가 없음 salesOfficeAddress: "", // vendors 테이블에 영업소주소 필드가 없음 salesOfficePhone: "", // vendors 테이블에 영업소전화 필드가 없음 // 대표자 정보 representativeNameKor: vendor.representativeName || "", representativeNameEng: "", // vendors 테이블에 영문명 필드가 없음 representativeContact: vendor.representativePhone || "", representativeBirthDate: vendor.representativeBirth || "", // 문자열로 직접 사용 representativeEmail: vendor.representativeEmail || "", isWorkingAtCompany: vendor.representativeWorkExpirence || false, isInternalPartner: false, // vendors 테이블에 해당 필드가 없음 // 대표자 경력 (기본값 유지) representativeCareer: [{ date: "", content: "" }], // 업무담당자 businessContacts: contactsMap, }); console.log("✅ 기존 데이터 로드 완료:", { vendor: vendor.vendorName, contactsCount: businessContacts.length, hasAdditionalInfo: !!additionalInfo, vendorData: { representativeBirth: vendor.representativeBirth, representativeBirthType: typeof vendor.representativeBirth, createdAt: vendor.createdAt, createdAtType: typeof vendor.createdAt } }); } else { toast.error(result.error || "데이터 로드 실패"); } } catch (error) { console.error("데이터 로드 오류:", error); toast.error("데이터 로드 중 오류가 발생했습니다."); } finally { setDataLoading(false); } }; if (!registration) return null; const handleInputChange = (field: string, value: any) => { setFormData(prev => ({ ...prev, [field]: value })); }; const handleBusinessContactChange = (type: keyof typeof formData.businessContacts, field: 'name' | 'position' | 'department' | 'responsibility' | 'email', value: string) => { setFormData(prev => ({ ...prev, businessContacts: { ...prev.businessContacts, [type]: { ...prev.businessContacts[type], [field]: value } } })); }; const handleCareerChange = (index: number, field: 'date' | 'content', value: string) => { setFormData(prev => ({ ...prev, representativeCareer: prev.representativeCareer.map((career, i) => i === index ? { ...career, [field]: value } : career ) })); }; const addCareerEntry = () => { setFormData(prev => ({ ...prev, representativeCareer: [...prev.representativeCareer, { date: "", content: "" }] })); }; const removeCareerEntry = (index: number) => { if (formData.representativeCareer.length > 1) { setFormData(prev => ({ ...prev, representativeCareer: prev.representativeCareer.filter((_, i) => i !== index) })); } }; const handleSubmit = async () => { setLoading(true); try { // 필수 필드 검증 const requiredFields = [ { field: formData.companyNameKor, name: "업체명(국문)" }, { field: formData.businessNumber, name: "사업자번호" }, { field: formData.representativeNameKor, name: "대표자 성명(국문)" }, { field: formData.representativeContact, name: "대표자 연락처" }, { field: formData.representativeBirthDate, name: "대표자 생년월일" }, { field: formData.representativeEmail, name: "대표자 이메일" }, ]; const missingFields = requiredFields.filter(({ field }) => !field?.trim()); if (missingFields.length > 0) { toast.error(`다음 필수 항목을 입력해주세요: ${missingFields.map(f => f.name).join(", ")}`); return; } if (onSubmit) { await onSubmit(formData); } else { // TODO: 실제 정규업체 등록 요청 API 호출 toast.success("정규업체 등록 요청이 제출되었습니다."); onOpenChange(false); } } catch (error) { console.error("정규업체 등록 요청 오류:", error); toast.error("정규업체 등록 요청 중 오류가 발생했습니다."); } finally { setLoading(false); } }; return ( 정규업체 등록 요청

정규업체 등록을 요청할 협력업체 정보 확인 및 누락정보를 입력하세요.

{dataLoading ? (

기존 데이터를 불러오는 중...

) : (
{/* 신규 협력사 등록 카드 */} 신규 협력사 등록 카드 {/* 업체정보 */}

업체정보

handleInputChange('companyNameKor', e.target.value)} className="bg-yellow-50" />
handleInputChange('businessNumber', e.target.value)} className="bg-yellow-50" />
handleInputChange('companyNameEng', e.target.value)} />
handleInputChange('corporateNumber', e.target.value)} />
{/*
handleInputChange('majorItems', e.target.value)} />
*/} {/*
handleInputChange('establishmentDate', e.target.value)} />
*/}
{/* 소재지 */}

소재지

handleInputChange('headOfficeAddress', e.target.value)} placeholder="PQ 내 회사주소" />
handleInputChange('headOfficePhone', e.target.value)} placeholder="PQ 내 회사전화" />
{/*
handleInputChange('factoryAddress', e.target.value)} placeholder="PQ 내 공장주소" />
handleInputChange('factoryPhone', e.target.value)} placeholder="PQ 내 공장전화" />
handleInputChange('salesOfficeAddress', e.target.value)} placeholder="필요시 입력" />
handleInputChange('salesOfficePhone', e.target.value)} placeholder="필요시 입력" />
*/}
{/* 대표자 정보 */}

대표자 정보

handleInputChange('representativeNameKor', e.target.value)} className="bg-yellow-50" />
handleInputChange('representativeContact', e.target.value)} className="bg-yellow-50" placeholder="010-0000-0000" />
handleInputChange('representativeNameEng', e.target.value)} />
handleInputChange('representativeBirthDate', e.target.value)} className="bg-yellow-50" />
handleInputChange('representativeEmail', e.target.value)} className="bg-yellow-50" />
{/*
handleInputChange('isWorkingAtCompany', checked)} />
handleInputChange('isInternalPartner', checked)} />
*/}
{/* 대표자 경력 */}

대표자 경력

{formData.representativeCareer.map((career, index) => (
handleCareerChange(index, 'date', e.target.value)} />
handleCareerChange(index, 'content', e.target.value)} />
{formData.representativeCareer.length > 1 && ( )}
))}
{/* 업무담당자 */}

업무담당자

{Object.entries(formData.businessContacts).map(([type, contact]) => { const labels = { sales: "영업", design: "설계", delivery: "납기", quality: "품질", taxInvoice: "세금계산서" }; return (
{labels[type as keyof typeof labels]} 담당자
handleBusinessContactChange(type as keyof typeof formData.businessContacts, 'name', e.target.value)} />
handleBusinessContactChange(type as keyof typeof formData.businessContacts, 'position', e.target.value)} placeholder="예: 부장, 과장" />
handleBusinessContactChange(type as keyof typeof formData.businessContacts, 'department', e.target.value)} placeholder="예: 영업부, 기술부" />
handleBusinessContactChange(type as keyof typeof formData.businessContacts, 'responsibility', e.target.value)} placeholder="예: 고객 대응, 품질 관리" />
handleBusinessContactChange(type as keyof typeof formData.businessContacts, 'email', e.target.value)} placeholder="example@company.com" />
); })}
)}
); }