summaryrefslogtreecommitdiff
path: root/lib/vendor-registration-status/vendor-registration-status-view.tsx
blob: 850dd7773b977c1e8ae84f7d8ca2c1af9440c765 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
"use client"

import { useState, useEffect } from "react"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"

import { 
  CheckCircle, 
  XCircle, 
  FileText, 
  AlertCircle,
  Eye,
  Upload
} from "lucide-react"
import { DocumentStatusDialog } from "@/components/vendor-regular-registrations/document-status-dialog"
import { AdditionalInfoDialog } from "@/components/vendor-regular-registrations/additional-info-dialog"
import { format } from "date-fns"
import { toast } from "sonner"
import { fetchVendorRegistrationStatus } from "@/lib/vendor-regular-registrations/service"

// 세션에서 벤더아이디 가져오기 위한 훅
import { useSession } from "next-auth/react"

// 상태별 정의
const statusConfig = {
  audit_pass: {
    label: "실사통과",
    color: "bg-blue-100 text-blue-800",
    description: "품질담당자(QM) 최종 의견에 따라 실사 통과로 결정된 상태"
  },
  cp_submitted: {
    label: "CP등록",
    color: "bg-green-100 text-green-800", 
    description: "협력업체에서 실사 통과 후 기본계약문서에 대한 답변 제출/서약 완료한 상태"
  },
  cp_review: {
    label: "CP검토",
    color: "bg-yellow-100 text-yellow-800",
    description: "협력업체에서 제출한 CP/GTC에 대한 법무검토 의뢰한 상태"
  },
  cp_finished: {
    label: "CP완료",
    color: "bg-purple-100 text-purple-800",
    description: "CP 답변에 대한 법무검토 완료되어 정규업체 등록 가능한 상태"
  },
  approval_ready: {
    label: "조건충족",
    color: "bg-emerald-100 text-emerald-800",
    description: "정규업체 등록 문서/자료 접수현황에 누락이 없는 상태"
  },
  in_review: {
    label: "정규등록검토",
    color: "bg-orange-100 text-orange-800",
    description: "구매담당자 요청에 따라 정규업체 등록 관리자가 정규업체 등록 가능여부 검토"
  },
  pending_approval: {
    label: "장기미등록",
    color: "bg-red-100 text-red-800",
    description: "정규업체로 등록 요청되어 3개월 이내 정규업체 등록되지 않은 상태"
  }
}

// 필수문서 목록
const requiredDocuments = [
  { key: "businessRegistration", label: "사업자등록증" },
  { key: "creditEvaluation", label: "신용평가서" },
  { key: "bankCopy", label: "통장사본" },
  { key: "cpDocument", label: "CP문서" },
  { key: "gtc", label: "GTC" },
  { key: "standardSubcontract", label: "표준하도급" },
  { key: "safetyHealth", label: "안전보건관리" },
  { key: "ethics", label: "윤리규범준수" },
  { key: "domesticCredit", label: "내국신용장" },
  { key: "safetyQualification", label: "안전적격성평가" },
]

export function VendorRegistrationStatusView() {
  const [additionalInfoDialogOpen, setAdditionalInfoDialogOpen] = useState(false)
  const [documentDialogOpen, setDocumentDialogOpen] = useState(false)
  const [hasSignature, setHasSignature] = useState(false)
  const [data, setData] = useState<any>(null)
  const [loading, setLoading] = useState(true)

  // 세션에서 vendorId 가져오기
  const { data: session, status: sessionStatus } = useSession()
  const vendorId = session?.user?.companyId
  console.log(vendorId)

  // 데이터 로드
  useEffect(() => {
    if (!vendorId) return

    const initialLoad = async () => {
      try {
        const result = await fetchVendorRegistrationStatus(vendorId)
        if (result.success) {
          setData(result.data)
        } else {
          toast.error(result.error)
        }
      } catch {
        toast.error("데이터 로드 중 오류가 발생했습니다.")
      } finally {
        setLoading(false)
      }
    }
    
    initialLoad()
  }, [vendorId])

  if (sessionStatus === "loading" || loading) {
    return <div className="p-8 text-center">로딩 중...</div>
  }

  if (!vendorId) {
    return <div className="p-8 text-center">벤더 정보가 없습니다. 다시 로그인 해주세요.</div>
  }

  if (!data) {
    return <div className="p-8 text-center">데이터를 불러올 수 없습니다.</div>
  }

  const currentStatusConfig = statusConfig[data.registration?.status as keyof typeof statusConfig] || statusConfig.audit_pass

  // 미완성 항목 계산
  const missingDocuments = requiredDocuments.filter(
    doc => !data.documentStatus[doc.key as keyof typeof data.documentStatus]
  )

  // Document Status Dialog에 전달할 registration 데이터 구성
  const registrationForDialog: any = {
    id: data.registration?.id || 0,
    vendorId: data.vendor.id,
    companyName: data.vendor.vendorName,
    businessNumber: data.vendor.taxId,
    representative: data.vendor.representativeName || "",
    country: data.vendor.country || "KR", // 기본값 KR
    potentialCode: data.registration?.potentialCode || "",
    status: data.registration?.status || "audit_pass",
    majorItems: "[]", // 빈 JSON 문자열
    establishmentDate: data.vendor.createdAt || new Date(),
    registrationRequestDate: data.registration?.registrationRequestDate,
    assignedDepartment: data.registration?.assignedDepartment,
    assignedDepartmentCode: data.registration?.assignedDepartmentCode,
    assignedUser: data.registration?.assignedUser,
    assignedUserCode: data.registration?.assignedUserCode,
    remarks: data.registration?.remarks,
    safetyQualificationContent: data.registration?.safetyQualificationContent || null,
    gtcSkipped: data.registration?.gtcSkipped || false,
    additionalInfo: data.additionalInfo,
    documentSubmissions: data.documentStatus, // documentSubmissions를 documentStatus로 설정
    contractAgreements: [],
    basicContracts: data.basicContracts || [], // 실제 데이터 사용
    documentSubmissionsStatus: data.documentStatus,
    contractAgreementsStatus: {
      cpDocument: data.documentStatus.cpDocument,
      gtc: data.documentStatus.gtc,
      standardSubcontract: data.documentStatus.standardSubcontract,
      safetyHealth: data.documentStatus.safetyHealth,
      ethics: data.documentStatus.ethics,
      domesticCredit: data.documentStatus.domesticCredit,
    },
    createdAt: data.registration?.createdAt || new Date(),
    updatedAt: data.registration?.updatedAt || new Date(),
  }

  const handleSignatureUpload = () => {
    // TODO: 서명/직인 업로드 기능 구현
    setHasSignature(true)
    toast.success("서명/직인이 등록되었습니다.")
  }

  const handleAdditionalInfoSave = () => {
    // 데이터 새로고침
    loadData()
  }

  const loadData = async () => {
    if (!vendorId) return
    try {
      const result = await fetchVendorRegistrationStatus(vendorId)
      if (result.success) {
        setData(result.data)
        toast.success("데이터가 새로고침되었습니다.")
      } else {
        toast.error(result.error)
      }
    } catch {
      toast.error("데이터 로드 중 오류가 발생했습니다.")
    }
  }

  return (
    <div className="space-y-6">
      {/* 헤더 섹션 */}
      <div className="space-y-4">
        <div className="flex items-center justify-between">
          <div>
            <h1 className="text-3xl font-bold">정규업체 등록관리 현황</h1>
            <p className="text-muted-foreground">
              {data.registration?.potentialCode || "미등록"} | {data.vendor.companyName}
            </p>
            <p className="text-sm text-muted-foreground mt-1">
              정규업체 등록 진행현황을 확인하세요.
            </p>
          </div>
          <Badge className={currentStatusConfig.color} variant="secondary">
            {currentStatusConfig.label}
          </Badge>
        </div>
      </div>

      {/* 회사 서명/직인 등록 */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <FileText className="w-5 h-5" />
            회사 서명/직인 등록
            <Badge variant="destructive" className="text-xs">필수</Badge>
          </CardTitle>
        </CardHeader>
        <CardContent>
          {hasSignature ? (
            <div className="flex items-center gap-3 p-4 border rounded-lg bg-green-50">
              <CheckCircle className="w-5 h-5 text-green-600" />
              <span className="text-green-800">서명/직인이 등록되었습니다.</span>
            </div>
          ) : (
            <Button 
              onClick={handleSignatureUpload}
              className="w-full h-20 border-2 border-dashed border-muted-foreground/25 bg-muted/25"
              variant="outline"
            >
              <div className="text-center">
                <Upload className="w-6 h-6 mx-auto mb-2" />
                <span>서명/직인 등록하기</span>
              </div>
            </Button>
          )}
        </CardContent>
      </Card>

      {/* 간소화된 액션 버튼들 */}
      <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
        <Button
          onClick={() => setDocumentDialogOpen(true)}
          variant="outline"
          size="lg"
          className="h-16 flex flex-col items-center gap-2"
        >
          <Eye className="w-6 h-6" />
          <span>문서 현황 확인</span>
        </Button>
        <Button
          onClick={() => setAdditionalInfoDialogOpen(true)}
          variant={data.additionalInfo ? "outline" : "default"}
          size="lg"
          className="h-16 flex flex-col items-center gap-2"
        >
          <FileText className="w-6 h-6" />
          <span>{data.additionalInfo ? "추가정보 수정" : "추가정보 등록"}</span>
        </Button>
      </div>

      {/* 상태 설명 */}
      <Card>
        <CardHeader>
          <CardTitle>현재 상태 안내</CardTitle>
        </CardHeader>
        <CardContent>
          <div className="flex items-start gap-3">
            <Badge className={currentStatusConfig.color} variant="secondary">
              {currentStatusConfig.label}
            </Badge>
            <p className="text-sm text-muted-foreground">
              {currentStatusConfig.description}
            </p>
          </div>
        </CardContent>
      </Card>

      {/* 문서 현황 Dialog */}
      <DocumentStatusDialog
        open={documentDialogOpen}
        onOpenChange={setDocumentDialogOpen}
        registration={registrationForDialog}
        onRefresh={loadData}
      />

      {/* 추가정보 입력 Dialog */}
      <AdditionalInfoDialog
        open={additionalInfoDialogOpen}
        onOpenChange={setAdditionalInfoDialogOpen}
        vendorId={vendorId}
        onSave={handleAdditionalInfoSave}
      />
    </div>
  )
}