From d47334639bd717aa860563ec1020a29827524fd4 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Fri, 5 Dec 2025 06:29:23 +0000 Subject: (최겸)구매 결재일 기준 공고 수정 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/bidding/receive/biddings-receive-columns.tsx | 808 +++++++++++------------ 1 file changed, 404 insertions(+), 404 deletions(-) (limited to 'lib/bidding/receive/biddings-receive-columns.tsx') diff --git a/lib/bidding/receive/biddings-receive-columns.tsx b/lib/bidding/receive/biddings-receive-columns.tsx index 9650574a..f2e2df17 100644 --- a/lib/bidding/receive/biddings-receive-columns.tsx +++ b/lib/bidding/receive/biddings-receive-columns.tsx @@ -1,404 +1,404 @@ -"use client" - -import * as React from "react" -import { type ColumnDef } from "@tanstack/react-table" -import { Badge } from "@/components/ui/badge" -import { Button } from "@/components/ui/button" -import { Checkbox } from "@/components/ui/checkbox" -import { - Eye, Calendar, Users, CheckCircle, XCircle, Clock, AlertTriangle -} from "lucide-react" -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from "@/components/ui/tooltip" -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuSeparator, - DropdownMenuTrigger, -} from "@/components/ui/dropdown-menu" -import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" -import { - biddingStatusLabels, - contractTypeLabels, -} from "@/db/schema" -import { formatDate } from "@/lib/utils" -import { DataTableRowAction } from "@/types/table" - -type BiddingReceiveItem = { - id: number - biddingNumber: string - originalBiddingNumber: string | null - title: string - status: string - contractType: string - prNumber: string | null - submissionStartDate: Date | null - submissionEndDate: Date | null - bidPicName: string | null - supplyPicName: string | null - createdBy: string | null - createdAt: Date | null - updatedAt: Date | null - - // 참여 현황 - participantExpected: number - participantParticipated: number - participantDeclined: number - participantPending: number - - // 개찰 정보 - openedAt: Date | null - openedBy: string | null -} - -interface GetColumnsProps { - setRowAction: React.Dispatch | null>> - onParticipantClick?: (biddingId: number, participantType: 'expected' | 'participated' | 'declined' | 'pending') => void -} - -// 상태별 배지 색상 -const getStatusBadgeVariant = (status: string) => { - switch (status) { - case 'received_quotation': - return 'secondary' - case 'bidding_opened': - return 'default' - case 'bidding_closed': - return 'outline' - default: - return 'outline' - } -} - -// 금액 포맷팅 -const formatCurrency = (amount: string | number | null, currency = 'KRW') => { - if (!amount) return '-' - - const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount - if (isNaN(numAmount)) return '-' - - return new Intl.NumberFormat('ko-KR', { - style: 'currency', - currency: currency, - minimumFractionDigits: 0, - maximumFractionDigits: 0, - }).format(numAmount) -} - -export function getBiddingsReceiveColumns({ setRowAction, onParticipantClick }: GetColumnsProps): ColumnDef[] { - - return [ - // ░░░ 선택 ░░░ - { - id: "select", - header: "", - cell: ({ row }) => ( - { - // single select 모드에서는 다른 행들의 선택을 해제 - row.toggleSelected(!!value) - }} - aria-label="행 선택" - /> - ), - size: 50, - enableSorting: false, - enableHiding: false, - }, - - // ░░░ 입찰번호 ░░░ - { - accessorKey: "biddingNumber", - header: ({ column }) => , - cell: ({ row }) => ( -
- {row.original.biddingNumber} -
- ), - size: 120, - meta: { excelHeader: "입찰번호" }, - }, - - // ░░░ 입찰명 ░░░ - { - accessorKey: "title", - header: ({ column }) => , - cell: ({ row }) => ( -
- {/* */} - {row.original.title} -
- ), - size: 200, - meta: { excelHeader: "입찰명" }, - }, - - // ░░░ 원입찰번호 ░░░ - { - accessorKey: "originalBiddingNumber", - header: ({ column }) => , - cell: ({ row }) => ( -
- {row.original.originalBiddingNumber || '-'} -
- ), - size: 120, - meta: { excelHeader: "원입찰번호" }, - }, - - // ░░░ 진행상태 ░░░ - { - accessorKey: "status", - header: ({ column }) => , - cell: ({ row }) => ( - - {biddingStatusLabels[row.original.status]} - - ), - size: 120, - meta: { excelHeader: "진행상태" }, - }, - - // ░░░ 계약구분 ░░░ - { - accessorKey: "contractType", - header: ({ column }) => , - cell: ({ row }) => ( - - {contractTypeLabels[row.original.contractType]} - - ), - size: 100, - meta: { excelHeader: "계약구분" }, - }, - - // ░░░ 입찰서제출기간 ░░░ - { - id: "submissionPeriod", - header: ({ column }) => , - cell: ({ row }) => { - const startDate = row.original.submissionStartDate - const endDate = row.original.submissionEndDate - - if (!startDate || !endDate) return - - - const startObj = new Date(startDate) - const endObj = new Date(endDate) - - // UI 표시용 KST 변환 - const formatKst = (d: Date) => new Date(d.getTime() + 9 * 60 * 60 * 1000).toISOString().slice(0, 16).replace('T', ' ') - - return ( -
-
- {formatKst(startObj)} ~ {formatKst(endObj)} -
-
- ) - }, - size: 140, - meta: { excelHeader: "입찰서제출기간" }, - }, - - // ░░░ P/R번호 ░░░ - { - accessorKey: "prNumber", - header: ({ column }) => , - cell: ({ row }) => ( - {row.original.prNumber || '-'} - ), - size: 100, - meta: { excelHeader: "P/R번호" }, - }, - - // ░░░ 입찰담당자 ░░░ - { - accessorKey: "bidPicName", - header: ({ column }) => , - cell: ({ row }) => { - const bidPic = row.original.bidPicName - const supplyPic = row.original.supplyPicName - - const displayName = bidPic || supplyPic || "-" - return {displayName} - }, - size: 100, - meta: { excelHeader: "입찰담당자" }, - }, - - // ░░░ 참여예정협력사 ░░░ - { - id: "participantExpected", - header: ({ column }) => , - cell: ({ row }) => ( - - ), - size: 100, - meta: { excelHeader: "참여예정협력사" }, - }, - - // ░░░ 참여협력사 ░░░ - { - id: "participantParticipated", - header: ({ column }) => , - cell: ({ row }) => ( - - ), - size: 100, - meta: { excelHeader: "참여협력사" }, - }, - - // ░░░ 포기협력사 ░░░ - { - id: "participantDeclined", - header: ({ column }) => , - cell: ({ row }) => ( - - ), - size: 100, - meta: { excelHeader: "포기협력사" }, - }, - - // ░░░ 미제출협력사 ░░░ - { - id: "participantPending", - header: ({ column }) => , - cell: ({ row }) => ( - - ), - size: 100, - meta: { excelHeader: "미제출협력사" }, - }, - - // ░░░ 개찰자명 ░░░ - { - id: "openedBy", - header: ({ column }) => , - cell: ({ row }) => { - const openedBy = row.original.openedBy - return {openedBy || '-'} - }, - size: 100, - meta: { excelHeader: "개찰자명" }, - }, - - // ░░░ 개찰일 ░░░ - { - id: "openedAt", - header: ({ column }) => , - cell: ({ row }) => { - const openedAt = row.original.openedAt - return {openedAt ? formatDate(openedAt, "KR") : '-'} - }, - size: 100, - meta: { excelHeader: "개찰일" }, - }, - - // ░░░ 등록자 ░░░ - { - accessorKey: "createdBy", - header: ({ column }) => , - cell: ({ row }) => ( - {row.original.createdBy || '-'} - ), - size: 100, - meta: { excelHeader: "등록자" }, - }, - - // ░░░ 등록일시 ░░░ - { - accessorKey: "createdAt", - header: ({ column }) => , - cell: ({ row }) => ( - {row.original.createdAt ? formatDate(row.original.createdAt, "KR") : '-'} - ), - size: 100, - meta: { excelHeader: "등록일시" }, - }, - - // ═══════════════════════════════════════════════════════════════ - // 액션 - // ═══════════════════════════════════════════════════════════════ - // { - // id: "actions", - // header: "액션", - // cell: ({ row }) => ( - // - // - // - // - // - // setRowAction({ row, type: "view" })}> - // - // 상세보기 - // - // - // - // ), - // size: 50, - // enableSorting: false, - // enableHiding: false, - // }, - ] -} +"use client" + +import * as React from "react" +import { type ColumnDef } from "@tanstack/react-table" +import { Badge } from "@/components/ui/badge" +import { Button } from "@/components/ui/button" +import { Checkbox } from "@/components/ui/checkbox" +import { + Eye, Calendar, Users, CheckCircle, XCircle, Clock, AlertTriangle +} from "lucide-react" +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from "@/components/ui/tooltip" +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuSeparator, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu" +import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" +import { + biddingStatusLabels, + contractTypeLabels, +} from "@/db/schema" +import { formatDate } from "@/lib/utils" +import { DataTableRowAction } from "@/types/table" + +type BiddingReceiveItem = { + id: number + biddingNumber: string + originalBiddingNumber: string | null + title: string + status: string + contractType: string + prNumber: string | null + submissionStartDate: Date | null + submissionEndDate: Date | null + bidPicName: string | null + supplyPicName: string | null + createdBy: string | null + createdAt: Date | null + updatedAt: Date | null + + // 참여 현황 + participantExpected: number + participantParticipated: number + participantDeclined: number + participantPending: number + + // 개찰 정보 + openedAt: Date | null + openedBy: string | null +} + +interface GetColumnsProps { + setRowAction: React.Dispatch | null>> + onParticipantClick?: (biddingId: number, participantType: 'expected' | 'participated' | 'declined' | 'pending') => void +} + +// 상태별 배지 색상 +const getStatusBadgeVariant = (status: string) => { + switch (status) { + case 'received_quotation': + return 'secondary' + case 'bidding_opened': + return 'default' + case 'bidding_closed': + return 'outline' + default: + return 'outline' + } +} + +// 금액 포맷팅 +const formatCurrency = (amount: string | number | null, currency = 'KRW') => { + if (!amount) return '-' + + const numAmount = typeof amount === 'string' ? parseFloat(amount) : amount + if (isNaN(numAmount)) return '-' + + return new Intl.NumberFormat('ko-KR', { + style: 'currency', + currency: currency, + minimumFractionDigits: 0, + maximumFractionDigits: 0, + }).format(numAmount) +} + +export function getBiddingsReceiveColumns({ setRowAction, onParticipantClick }: GetColumnsProps): ColumnDef[] { + + return [ + // ░░░ 선택 ░░░ + { + id: "select", + header: "", + cell: ({ row }) => ( + { + // single select 모드에서는 다른 행들의 선택을 해제 + row.toggleSelected(!!value) + }} + aria-label="행 선택" + /> + ), + size: 50, + enableSorting: false, + enableHiding: false, + }, + + // ░░░ 입찰번호 ░░░ + { + accessorKey: "biddingNumber", + header: ({ column }) => , + cell: ({ row }) => ( +
+ {row.original.biddingNumber} +
+ ), + size: 120, + meta: { excelHeader: "입찰번호" }, + }, + + // ░░░ 입찰명 ░░░ + { + accessorKey: "title", + header: ({ column }) => , + cell: ({ row }) => ( +
+ {/* */} + {row.original.title} +
+ ), + size: 200, + meta: { excelHeader: "입찰명" }, + }, + + // ░░░ 원입찰번호 ░░░ + { + accessorKey: "originalBiddingNumber", + header: ({ column }) => , + cell: ({ row }) => ( +
+ {row.original.originalBiddingNumber || '-'} +
+ ), + size: 120, + meta: { excelHeader: "원입찰번호" }, + }, + + // ░░░ 진행상태 ░░░ + { + accessorKey: "status", + header: ({ column }) => , + cell: ({ row }) => ( + + {biddingStatusLabels[row.original.status]} + + ), + size: 120, + meta: { excelHeader: "진행상태" }, + }, + + // ░░░ 계약구분 ░░░ + { + accessorKey: "contractType", + header: ({ column }) => , + cell: ({ row }) => ( + + {contractTypeLabels[row.original.contractType]} + + ), + size: 100, + meta: { excelHeader: "계약구분" }, + }, + + // ░░░ 입찰서제출기간 ░░░ + { + id: "submissionPeriod", + header: ({ column }) => , + cell: ({ row }) => { + const startDate = row.original.submissionStartDate + const endDate = row.original.submissionEndDate + + if (!startDate || !endDate) return - + + const startObj = new Date(startDate) + const endObj = new Date(endDate) + + // UI 표시용 KST 변환 + const formatKst = (d: Date) => new Date(d.getTime() + 9 * 60 * 60 * 1000).toISOString().slice(0, 16).replace('T', ' ') + + return ( +
+
+ {formatKst(startObj)} ~ {formatKst(endObj)} +
+
+ ) + }, + size: 140, + meta: { excelHeader: "입찰서제출기간" }, + }, + + // ░░░ P/R번호 ░░░ + { + accessorKey: "prNumber", + header: ({ column }) => , + cell: ({ row }) => ( + {row.original.prNumber || '-'} + ), + size: 100, + meta: { excelHeader: "P/R번호" }, + }, + + // ░░░ 입찰담당자 ░░░ + { + accessorKey: "bidPicName", + header: ({ column }) => , + cell: ({ row }) => { + const bidPic = row.original.bidPicName + const supplyPic = row.original.supplyPicName + + const displayName = bidPic || supplyPic || "-" + return {displayName} + }, + size: 100, + meta: { excelHeader: "입찰담당자" }, + }, + + // ░░░ 참여예정협력사 ░░░ + { + id: "participantExpected", + header: ({ column }) => , + cell: ({ row }) => ( + + ), + size: 100, + meta: { excelHeader: "참여예정협력사" }, + }, + + // ░░░ 참여협력사 ░░░ + { + id: "participantParticipated", + header: ({ column }) => , + cell: ({ row }) => ( + + ), + size: 100, + meta: { excelHeader: "참여협력사" }, + }, + + // ░░░ 포기협력사 ░░░ + { + id: "participantDeclined", + header: ({ column }) => , + cell: ({ row }) => ( + + ), + size: 100, + meta: { excelHeader: "포기협력사" }, + }, + + // ░░░ 미제출협력사 ░░░ + { + id: "participantPending", + header: ({ column }) => , + cell: ({ row }) => ( + + ), + size: 100, + meta: { excelHeader: "미제출협력사" }, + }, + + // ░░░ 개찰자명 ░░░ + { + id: "openedBy", + header: ({ column }) => , + cell: ({ row }) => { + const openedBy = row.original.openedBy + return {openedBy || '-'} + }, + size: 100, + meta: { excelHeader: "개찰자명" }, + }, + + // ░░░ 개찰일 ░░░ + { + id: "openedAt", + header: ({ column }) => , + cell: ({ row }) => { + const openedAt = row.original.openedAt + return {openedAt ? formatDate(openedAt, "KR") : '-'} + }, + size: 100, + meta: { excelHeader: "개찰일" }, + }, + + // ░░░ 등록자 ░░░ + { + accessorKey: "createdBy", + header: ({ column }) => , + cell: ({ row }) => ( + {row.original.createdBy || '-'} + ), + size: 100, + meta: { excelHeader: "등록자" }, + }, + + // ░░░ 등록일시 ░░░ + { + accessorKey: "createdAt", + header: ({ column }) => , + cell: ({ row }) => ( + {row.original.createdAt ? formatDate(row.original.createdAt, "KR") : '-'} + ), + size: 100, + meta: { excelHeader: "등록일시" }, + }, + + // ═══════════════════════════════════════════════════════════════ + // 액션 + // ═══════════════════════════════════════════════════════════════ + // { + // id: "actions", + // header: "액션", + // cell: ({ row }) => ( + // + // + // + // + // + // setRowAction({ row, type: "view" })}> + // + // 상세보기 + // + // + // + // ), + // size: 50, + // enableSorting: false, + // enableHiding: false, + // }, + ] +} -- cgit v1.2.3