summaryrefslogtreecommitdiff
path: root/lib/bidding/pre-quote/table/bidding-pre-quote-vendor-table.tsx
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-09-04 08:31:31 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-09-04 08:31:31 +0000
commitb67e36df49f067cbd5ba899f9fbcc755f38d4b4f (patch)
tree5a71c5960f90d988cd509e3ef26bff497a277661 /lib/bidding/pre-quote/table/bidding-pre-quote-vendor-table.tsx
parentb7f54b06c1ef9e619f5358fb0a5caad9703c8905 (diff)
(대표님, 최겸, 임수민) 작업사항 커밋
Diffstat (limited to 'lib/bidding/pre-quote/table/bidding-pre-quote-vendor-table.tsx')
-rw-r--r--lib/bidding/pre-quote/table/bidding-pre-quote-vendor-table.tsx189
1 files changed, 189 insertions, 0 deletions
diff --git a/lib/bidding/pre-quote/table/bidding-pre-quote-vendor-table.tsx b/lib/bidding/pre-quote/table/bidding-pre-quote-vendor-table.tsx
new file mode 100644
index 00000000..a9d12629
--- /dev/null
+++ b/lib/bidding/pre-quote/table/bidding-pre-quote-vendor-table.tsx
@@ -0,0 +1,189 @@
+'use client'
+
+import * as React from 'react'
+import { type DataTableAdvancedFilterField, type DataTableFilterField } from '@/types/table'
+import { useDataTable } from '@/hooks/use-data-table'
+import { DataTable } from '@/components/data-table/data-table'
+import { DataTableAdvancedToolbar } from '@/components/data-table/data-table-advanced-toolbar'
+import { BiddingPreQuoteVendorToolbarActions } from './bidding-pre-quote-vendor-toolbar-actions'
+import { BiddingPreQuoteVendorEditDialog } from './bidding-pre-quote-vendor-edit-dialog'
+import { getBiddingPreQuoteVendorColumns, BiddingCompany } from './bidding-pre-quote-vendor-columns'
+import { Bidding } from '@/db/schema'
+import {
+ deleteBiddingCompany
+} from '../service'
+import { useToast } from '@/hooks/use-toast'
+import { useTransition } from 'react'
+
+interface BiddingPreQuoteVendorTableContentProps {
+ biddingId: number
+ bidding: Bidding
+ vendors: any[] // 사용하지 않음
+ biddingCompanies: BiddingCompany[]
+ onRefresh: () => void
+ onOpenItemsDialog: () => void
+ onOpenTargetPriceDialog: () => void
+ onOpenSelectionReasonDialog: () => void
+ onEdit?: (company: BiddingCompany) => void
+ onDelete?: (company: BiddingCompany) => void
+ onSelectWinner?: (company: BiddingCompany) => void
+}
+
+const filterFields: DataTableFilterField<BiddingCompany>[] = [
+ {
+ id: 'companyName',
+ label: '업체명',
+ placeholder: '업체명으로 검색...',
+ },
+ {
+ id: 'companyCode',
+ label: '업체코드',
+ placeholder: '업체코드로 검색...',
+ },
+ {
+ id: 'contactPerson',
+ label: '담당자',
+ placeholder: '담당자로 검색...',
+ },
+]
+
+const advancedFilterFields: DataTableAdvancedFilterField<BiddingCompany>[] = [
+ {
+ id: 'companyName',
+ label: '업체명',
+ type: 'text',
+ },
+ {
+ id: 'companyCode',
+ label: '업체코드',
+ type: 'text',
+ },
+ {
+ id: 'contactPerson',
+ label: '담당자',
+ type: 'text',
+ },
+ {
+ id: 'preQuoteAmount',
+ label: '사전견적금액',
+ type: 'number',
+ },
+ {
+ id: 'invitationStatus',
+ label: '초대 상태',
+ type: 'multi-select',
+ options: [
+ { label: '수락', value: 'accepted' },
+ { label: '거절', value: 'declined' },
+ { label: '대기중', value: 'pending' },
+ ],
+ },
+]
+
+export function BiddingPreQuoteVendorTableContent({
+ biddingId,
+ bidding,
+ vendors,
+ biddingCompanies,
+ onRefresh,
+ onOpenItemsDialog,
+ onOpenTargetPriceDialog,
+ onOpenSelectionReasonDialog,
+ onEdit,
+ onDelete,
+ onSelectWinner
+}: BiddingPreQuoteVendorTableContentProps) {
+ const { toast } = useToast()
+ const [isPending, startTransition] = useTransition()
+ const [selectedCompany, setSelectedCompany] = React.useState<BiddingCompany | null>(null)
+ const [isEditDialogOpen, setIsEditDialogOpen] = React.useState(false)
+
+ const handleDelete = (company: BiddingCompany) => {
+ if (!confirm(`${company.companyName} 업체를 삭제하시겠습니까?`)) return
+
+ startTransition(async () => {
+ const response = await deleteBiddingCompany(company.id)
+
+ if (response.success) {
+ toast({
+ title: '성공',
+ description: response.message,
+ })
+ onRefresh()
+ } else {
+ toast({
+ title: '오류',
+ description: response.error,
+ variant: 'destructive',
+ })
+ }
+ })
+ }
+
+ const handleEdit = (company: BiddingCompany) => {
+ setSelectedCompany(company)
+ setIsEditDialogOpen(true)
+ }
+
+ const handleInvite = (company: BiddingCompany) => {
+ // TODO: 초대 발송 로직 구현
+ toast({
+ title: '알림',
+ description: `${company.companyName} 업체에 초대를 발송했습니다.`,
+ })
+ }
+
+ const columns = React.useMemo(
+ () => getBiddingPreQuoteVendorColumns({
+ onEdit: onEdit || handleEdit,
+ onDelete: onDelete || handleDelete,
+ onInvite: handleInvite
+ }),
+ [onEdit, onDelete, handleEdit, handleDelete, handleInvite]
+ )
+
+ const { table } = useDataTable({
+ data: biddingCompanies,
+ columns,
+ pageCount: 1,
+ filterFields,
+ enableAdvancedFilter: true,
+ initialState: {
+ sorting: [{ id: 'companyName', desc: false }],
+ columnPinning: { right: ['actions'] },
+ },
+ getRowId: (originalRow) => originalRow.id.toString(),
+ shallow: false,
+ clearOnDefault: true,
+ })
+
+ return (
+ <>
+ <DataTable table={table}>
+ <DataTableAdvancedToolbar
+ table={table}
+ filterFields={advancedFilterFields}
+ shallow={false}
+ >
+ <BiddingPreQuoteVendorToolbarActions
+ table={table}
+ biddingId={biddingId}
+ bidding={bidding}
+ biddingCompanies={biddingCompanies}
+ onOpenItemsDialog={onOpenItemsDialog}
+ onOpenTargetPriceDialog={onOpenTargetPriceDialog}
+ onOpenSelectionReasonDialog={onOpenSelectionReasonDialog}
+ onSuccess={onRefresh}
+ />
+ </DataTableAdvancedToolbar>
+ </DataTable>
+
+ <BiddingPreQuoteVendorEditDialog
+ company={selectedCompany}
+ open={isEditDialogOpen}
+ onOpenChange={setIsEditDialogOpen}
+ onSuccess={onRefresh}
+ />
+ </>
+ )
+}