summaryrefslogtreecommitdiff
path: root/lib/bidding/list
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-09-09 10:32:34 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-09-09 10:32:34 +0000
commitc62ec046327fd388ebce04571b55910747e69a3b (patch)
tree41ccdc4a8dea99808622f6d5d52014ac59a2d7ab /lib/bidding/list
parentebcec3f296d1d27943caf8a3aed26efef117cdc5 (diff)
(정희성, 최겸, 대표님) formatDate 변경 등
Diffstat (limited to 'lib/bidding/list')
-rw-r--r--lib/bidding/list/bidding-detail-dialogs.tsx16
-rw-r--r--lib/bidding/list/biddings-table-toolbar-actions.tsx52
-rw-r--r--lib/bidding/list/create-bidding-dialog.tsx24
-rw-r--r--lib/bidding/list/edit-bidding-sheet.tsx33
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,