diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-09-09 10:32:34 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-09-09 10:32:34 +0000 |
| commit | c62ec046327fd388ebce04571b55910747e69a3b (patch) | |
| tree | 41ccdc4a8dea99808622f6d5d52014ac59a2d7ab /lib/bidding/list | |
| parent | ebcec3f296d1d27943caf8a3aed26efef117cdc5 (diff) | |
(정희성, 최겸, 대표님) formatDate 변경 등
Diffstat (limited to 'lib/bidding/list')
| -rw-r--r-- | lib/bidding/list/bidding-detail-dialogs.tsx | 16 | ||||
| -rw-r--r-- | lib/bidding/list/biddings-table-toolbar-actions.tsx | 52 | ||||
| -rw-r--r-- | lib/bidding/list/create-bidding-dialog.tsx | 24 | ||||
| -rw-r--r-- | lib/bidding/list/edit-bidding-sheet.tsx | 33 |
4 files changed, 24 insertions, 101 deletions
diff --git a/lib/bidding/list/bidding-detail-dialogs.tsx b/lib/bidding/list/bidding-detail-dialogs.tsx index 2e58d676..4fbca616 100644 --- a/lib/bidding/list/bidding-detail-dialogs.tsx +++ b/lib/bidding/list/bidding-detail-dialogs.tsx @@ -45,6 +45,7 @@ import { toast } from "sonner" import { BiddingListItem } from "@/db/schema" import { downloadFile, formatFileSize, getFileInfo } from "@/lib/file-download" import { getPRDetailsAction, getSpecificationMeetingDetailsAction } from "../service" +import { formatDate } from "@/lib/utils" // 타입 정의 interface SpecificationMeetingDetails { @@ -301,19 +302,6 @@ export function SpecificationMeetingDialog({ } }; - const formatDate = (dateString: string) => { - try { - return new Date(dateString).toLocaleDateString('ko-KR', { - year: 'numeric', - month: 'long', - day: 'numeric', - weekday: 'long' - }); - } catch { - return dateString; - } - }; - return ( <Dialog open={open} onOpenChange={onOpenChange}> <DialogContent className="max-w-4xl max-h-[90vh]"> @@ -355,7 +343,7 @@ export function SpecificationMeetingDialog({ <div className="text-sm space-y-1"> <div> <CalendarIcon className="inline h-3 w-3 text-muted-foreground mr-2" /> - <span className="font-medium">날짜:</span> {formatDate(data.meetingDate)} + <span className="font-medium">날짜:</span> {formatDate(data.meetingDate, "kr")} {data.meetingTime && <span className="ml-4"><ClockIcon className="inline h-3 w-3 text-muted-foreground mr-1" />{data.meetingTime}</span>} </div> diff --git a/lib/bidding/list/biddings-table-toolbar-actions.tsx b/lib/bidding/list/biddings-table-toolbar-actions.tsx index 81982a43..70b48a36 100644 --- a/lib/bidding/list/biddings-table-toolbar-actions.tsx +++ b/lib/bidding/list/biddings-table-toolbar-actions.tsx @@ -8,7 +8,6 @@ import { } from "lucide-react" import { toast } from "sonner" import { useRouter } from "next/navigation" - import { exportTableToExcel } from "@/lib/export" import { Button } from "@/components/ui/button" import { @@ -37,41 +36,6 @@ export function BiddingsTableToolbarActions({ table }: BiddingsTableToolbarActio .map(row => row.original) }, [table.getFilteredSelectedRowModel().rows]) - // 사전견적 요청 가능한 입찰들 (입찰생성 상태) - const preQuoteEligibleBiddings = React.useMemo(() => { - return selectedBiddings.filter(bidding => - bidding.status === 'bidding_generated' - ) - }, [selectedBiddings]) - - // 개찰 가능한 입찰들 (내정가 산정 완료) - const openEligibleBiddings = React.useMemo(() => { - return selectedBiddings.filter(bidding => - bidding.status === 'set_target_price' - ) - }, [selectedBiddings]) - - - const handlePreQuoteRequest = () => { - if (preQuoteEligibleBiddings.length === 0) { - toast.warning("사전견적 요청 가능한 입찰을 선택해주세요.") - return - } - - toast.success(`${preQuoteEligibleBiddings.length}개 입찰의 사전견적을 요청했습니다.`) - // TODO: 실제 사전견적 요청 로직 구현 - } - - const handleBiddingOpen = () => { - if (openEligibleBiddings.length === 0) { - toast.warning("개찰 가능한 입찰을 선택해주세요.") - return - } - - toast.success(`${openEligibleBiddings.length}개 입찰을 개찰했습니다.`) - // TODO: 실제 개찰 로직 구현 - } - const handleExport = async () => { try { setIsExporting(true) @@ -92,20 +56,8 @@ export function BiddingsTableToolbarActions({ table }: BiddingsTableToolbarActio {/* 신규 생성 */} <CreateBiddingDialog/> - {/* 사전견적 요청 */} - {preQuoteEligibleBiddings.length > 0 && ( - <Button - variant="outline" - size="sm" - onClick={handlePreQuoteRequest} - > - <Send className="mr-2 h-4 w-4" /> - 사전견적 요청 ({preQuoteEligibleBiddings.length}) - </Button> - )} - {/* 개찰 (입찰 오픈) */} - {openEligibleBiddings.length > 0 && ( + {/* {openEligibleBiddings.length > 0 && ( <Button variant="outline" size="sm" @@ -114,7 +66,7 @@ export function BiddingsTableToolbarActions({ table }: BiddingsTableToolbarActio <Gavel className="mr-2 h-4 w-4" /> 개찰 ({openEligibleBiddings.length}) </Button> - )} + )} */} {/* Export */} <DropdownMenu> diff --git a/lib/bidding/list/create-bidding-dialog.tsx b/lib/bidding/list/create-bidding-dialog.tsx index 88697903..f21782ff 100644 --- a/lib/bidding/list/create-bidding-dialog.tsx +++ b/lib/bidding/list/create-bidding-dialog.tsx @@ -274,7 +274,10 @@ export function CreateBiddingDialog() { conditions: { isValid: biddingConditions.paymentTerms.trim() !== "" && biddingConditions.taxConditions.trim() !== "" && - biddingConditions.incoterms.trim() !== "", + biddingConditions.incoterms.trim() !== "" && + biddingConditions.contractDeliveryDate.trim() !== "" && + biddingConditions.shippingPort.trim() !== "" && + biddingConditions.destinationPort.trim() !== "", hasErrors: false }, details: { @@ -286,7 +289,7 @@ export function CreateBiddingDialog() { hasErrors: !!(formErrors.managerName || formErrors.managerEmail || formErrors.managerPhone) } } - }, [form, specMeetingInfo.meetingDate, specMeetingInfo.location, specMeetingInfo.contactPerson]) + }, [form, specMeetingInfo.meetingDate, specMeetingInfo.location, specMeetingInfo.contactPerson, biddingConditions]) const tabValidation = getTabValidationState() @@ -428,7 +431,7 @@ export function CreateBiddingDialog() { toast.error("제출 시작일시와 마감일시를 입력해주세요") } } else if (activeTab === "conditions") { - toast.error("입찰 조건을 모두 입력해주세요 (지급조건, 세금조건, 운송조건)") + toast.error("입찰 조건을 모두 입력해주세요 (지급조건, 세금조건, 운송조건, 계약납품일, 선적지, 도착지)") } return } @@ -474,17 +477,18 @@ export function CreateBiddingDialog() { const result = await createBidding(extendedData, userId) if (result.success) { - toast.success(result.message) + toast.success(result.message || "입찰이 성공적으로 생성되었습니다.") setOpen(false) router.refresh() // 생성된 입찰 상세페이지로 이동할지 묻기 - if (result.data?.id) { + if (result.success && 'data' in result && result.data?.id) { setCreatedBiddingId(result.data.id) setShowSuccessDialog(true) } } else { - toast.error(result.error || "입찰 생성에 실패했습니다.") + const errorMessage = result.success === false && 'error' in result ? result.error : "입찰 생성에 실패했습니다." + toast.error(errorMessage) } } catch (error) { console.error("Error creating bidding:", error) @@ -1316,7 +1320,7 @@ export function CreateBiddingDialog() { 세금조건 <span className="text-red-500">*</span> </label> <Input - + placeholder="예: 부가세 별도" value={biddingConditions.taxConditions} onChange={(e) => setBiddingConditions(prev => ({ ...prev, @@ -1341,7 +1345,7 @@ export function CreateBiddingDialog() { <div className="space-y-2"> <label className="text-sm font-medium"> - 계약 납품일 + 계약 납품일 <span className="text-red-500">*</span> </label> <Input type="date" @@ -1354,7 +1358,7 @@ export function CreateBiddingDialog() { </div> <div className="space-y-2"> - <label className="text-sm font-medium">선적지</label> + <label className="text-sm font-medium">선적지 <span className="text-red-500">*</span></label> <Input placeholder="예: 부산항, 인천항" value={biddingConditions.shippingPort} @@ -1366,7 +1370,7 @@ export function CreateBiddingDialog() { </div> <div className="space-y-2"> - <label className="text-sm font-medium">도착지</label> + <label className="text-sm font-medium">도착지 <span className="text-red-500">*</span></label> <Input placeholder="예: 현장 직납, 창고 납품" value={biddingConditions.destinationPort} diff --git a/lib/bidding/list/edit-bidding-sheet.tsx b/lib/bidding/list/edit-bidding-sheet.tsx index f3bc1805..71eeed2b 100644 --- a/lib/bidding/list/edit-bidding-sheet.tsx +++ b/lib/bidding/list/edit-bidding-sheet.tsx @@ -49,6 +49,7 @@ import { biddingTypeLabels, awardCountLabels } from "@/db/schema" +import { formatDate } from "@/lib/utils" interface EditBiddingSheetProps { open: boolean @@ -111,28 +112,6 @@ export function EditBiddingSheet({ // 시트가 열릴 때 기존 데이터로 폼 초기화 React.useEffect(() => { if (open && bidding) { - const formatDateForInput = (date: Date | string | null): string => { - if (!date) return "" - try { - const d = new Date(date) - if (isNaN(d.getTime())) return "" - return d.toISOString().slice(0, 16) // YYYY-MM-DDTHH:mm - } catch { - return "" - } - } - - const formatDateOnlyForInput = (date: Date | string | null): string => { - if (!date) return "" - try { - const d = new Date(date) - if (isNaN(d.getTime())) return "" - return d.toISOString().slice(0, 10) // YYYY-MM-DD - } catch { - return "" - } - } - form.reset({ biddingNumber: bidding.biddingNumber || "", revision: bidding.revision || 0, @@ -147,11 +126,11 @@ export function EditBiddingSheet({ awardCount: bidding.awardCount || "single", contractPeriod: bidding.contractPeriod || "", - preQuoteDate: formatDateOnlyForInput(bidding.preQuoteDate), - biddingRegistrationDate: formatDateOnlyForInput(bidding.biddingRegistrationDate), - submissionStartDate: formatDateForInput(bidding.submissionStartDate), - submissionEndDate: formatDateForInput(bidding.submissionEndDate), - evaluationDate: formatDateForInput(bidding.evaluationDate), + preQuoteDate: formatDate(bidding.preQuoteDate, "kr"), + biddingRegistrationDate: formatDate(bidding.biddingRegistrationDate, "kr"), + submissionStartDate: formatDate(bidding.submissionStartDate, "kr"), + submissionEndDate: formatDate(bidding.submissionEndDate, "kr"), + evaluationDate: formatDate(bidding.evaluationDate, "kr"), hasSpecificationMeeting: bidding.hasSpecificationMeeting || false, hasPrDocument: bidding.hasPrDocument || false, |
