summaryrefslogtreecommitdiff
path: root/lib/bidding/pre-quote/table/bidding-pre-quote-selection-dialog.tsx
blob: e0194f2a654dd8854ca37d5bef59c15010e88f79 (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
'use client'

import * as React from 'react'
import { BiddingCompany } from './bidding-pre-quote-vendor-columns'
import { updatePreQuoteSelection } from '../service'
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { CheckCircle, XCircle, AlertCircle } from 'lucide-react'
import { useToast } from '@/hooks/use-toast'
import { useTransition } from 'react'

interface BiddingPreQuoteSelectionDialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  selectedCompanies: BiddingCompany[]
  onSuccess: () => void
}

export function BiddingPreQuoteSelectionDialog({
  open,
  onOpenChange,
  selectedCompanies,
  onSuccess
}: BiddingPreQuoteSelectionDialogProps) {
  const { toast } = useToast()
  const [isPending, startTransition] = useTransition()
  // 선택된 업체들의 현재 상태 분석 (선정만 가능)
  const unselectedCompanies = selectedCompanies.filter(c => !c.isPreQuoteSelected)
  const hasQuotationCompanies = selectedCompanies.filter(c => c.preQuoteAmount && Number(c.preQuoteAmount) > 0)

  const handleConfirm = () => {
    const companyIds = selectedCompanies.map(c => c.id)
    const isSelected = true // 항상 선정으로 고정

    startTransition(async () => {
      const result = await updatePreQuoteSelection(
        companyIds,
        isSelected
      )

      if (result.success) {
        toast({
          title: '성공',
          description: result.message,
        })
        onSuccess()
        onOpenChange(false)
      } else {
        toast({
          title: '오류',
          description: result.error,
          variant: 'destructive',
        })
      }
    })
  }

  const getActionIcon = (isSelected: boolean) => {
    return isSelected ? 
      <CheckCircle className="h-4 w-4 text-muted-foreground" /> : 
      <CheckCircle className="h-4 w-4 text-green-600" />
  }

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="sm:max-w-[600px]">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <AlertCircle className="h-5 w-5 text-amber-500" />
            본입찰 선정 상태 변경
          </DialogTitle>
          <DialogDescription>
            선택된 {selectedCompanies.length}개 업체의 본입찰 선정 상태를 변경합니다.
          </DialogDescription>
        </DialogHeader>

        <div className="space-y-4">
          {/* 견적 제출 여부 안내 */}
          {hasQuotationCompanies.length !== selectedCompanies.length && (
            <div className="bg-amber-50 border border-amber-200 rounded-lg p-3">
              <div className="flex items-center gap-2 text-amber-800">
                <AlertCircle className="h-4 w-4" />
                <span className="text-sm font-medium">알림</span>
              </div>
              <p className="text-sm text-amber-700 mt-1">
                사전견적을 제출하지 않은 업체도 포함되어 있습니다. 
                견적 미제출 업체도 본입찰에 참여시키시겠습니까?
              </p>
            </div>
          )}

          {/* 업체 목록 */}
          <div className="border rounded-lg">
            <div className="p-3 bg-muted/50 border-b">
              <h4 className="font-medium">대상 업체 목록</h4>
            </div>
            <div className="max-h-64 overflow-y-auto">
              {selectedCompanies.map((company) => (
                <div key={company.id} className="flex items-center justify-between p-3 border-b last:border-b-0">
                  <div className="flex items-center gap-3">
                    {getActionIcon(company.isPreQuoteSelected)}
                    <div>
                      <div className="font-medium">{company.companyName}</div>
                      <div className="text-sm text-muted-foreground">{company.companyCode}</div>
                    </div>
                  </div>
                  <div className="flex items-center gap-2">
                    <Badge variant={company.isPreQuoteSelected ? 'default' : 'secondary'}>
                      {company.isPreQuoteSelected ? '현재 선정' : '현재 미선정'}
                    </Badge>
                    {company.preQuoteAmount && Number(company.preQuoteAmount) > 0 ? (
                      <Badge variant="outline" className="text-green-600">
                        견적 제출
                      </Badge>
                    ) : (
                      <Badge variant="outline" className="text-muted-foreground">
                        견적 미제출
                      </Badge>
                    )}
                  </div>
                </div>
              ))}
            </div>
          </div>

          {/* 결과 요약 */}
          <div className="bg-blue-50 border border-blue-200 rounded-lg p-3">
            <h5 className="font-medium text-blue-900 mb-2">변경 결과</h5>
            <div className="text-sm text-blue-800">
              <p>• {unselectedCompanies.length}개 업체가 본입찰 대상으로 <span className="font-medium text-green-600">선정</span>됩니다.</p>
              {selectedCompanies.length > unselectedCompanies.length && (
                <p>• {selectedCompanies.length - unselectedCompanies.length}개 업체는 이미 선정 상태이므로 변경되지 않습니다.</p>
              )}
            </div>
          </div>
        </div>

        <DialogFooter>
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            취소
          </Button>
          <Button onClick={handleConfirm} disabled={isPending}>
            {isPending ? '처리 중...' : '확인'}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  )
}