summaryrefslogtreecommitdiff
path: root/lib/techsales-rfq/table/update-rfq-sheet.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/techsales-rfq/table/update-rfq-sheet.tsx')
-rw-r--r--lib/techsales-rfq/table/update-rfq-sheet.tsx156
1 files changed, 154 insertions, 2 deletions
diff --git a/lib/techsales-rfq/table/update-rfq-sheet.tsx b/lib/techsales-rfq/table/update-rfq-sheet.tsx
index 7dcc0e0e..f7bcbf9d 100644
--- a/lib/techsales-rfq/table/update-rfq-sheet.tsx
+++ b/lib/techsales-rfq/table/update-rfq-sheet.tsx
@@ -11,16 +11,20 @@ import { Loader2, CalendarIcon } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
+import { Textarea } from "@/components/ui/textarea";
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetDescription, SheetFooter, SheetClose } from "@/components/ui/sheet";
import { Popover, PopoverTrigger, PopoverContent } from "@/components/ui/popover";
import { Calendar } from "@/components/ui/calendar";
import { cn } from "@/lib/utils";
import { updateTechSalesRfq, getTechSalesRfqById } from "@/lib/techsales-rfq/service";
+import { getProjectSeriesForProject } from "@/lib/bidding-projects/service";
+import { type ProjectSeries } from "@/db/schema/projects";
// Zod schema for form validation
const updateRfqSchema = z.object({
rfqId: z.number().min(1, "RFQ ID is required"),
description: z.string(),
+ remark: z.string(),
dueDate: z.string(),
});
@@ -41,8 +45,39 @@ export default function UpdateSheet({ open, onOpenChange, rfqId, onUpdated }: Up
projMsrm: "",
ptypeNm: "",
rfqNo: "",
+ pspid: "",
});
+ const [rfqInfo, setRfqInfo] = React.useState({
+ status: "",
+ createdAt: "",
+ updatedAt: "",
+ createdByName: "",
+ updatedByName: "",
+ sentByName: "",
+ rfqSendDate: "",
+ });
+ const [seriesInfo, setSeriesInfo] = React.useState<ProjectSeries[]>([]);
const [isLoading, setIsLoading] = React.useState(false);
+ const [isLoadingSeries, setIsLoadingSeries] = React.useState(false);
+
+ // K/L 날짜를 4분기로 변환하는 함수
+ const convertKLToQuarter = React.useCallback((klDate: string | null): string => {
+ if (!klDate) return "정보 없음"
+
+ try {
+ // YYYYMMDD 형식의 날짜를 파싱
+ const year = parseInt(klDate.substring(0, 4))
+ const month = parseInt(klDate.substring(4, 6))
+
+ // 4분기 계산 (1-3월: 1Q, 4-6월: 2Q, 7-9월: 3Q, 10-12월: 4Q)
+ const quarter = Math.ceil(month / 3)
+
+ return `${year} ${quarter}Q`
+ } catch (error) {
+ console.error("K/L 날짜 변환 오류:", error)
+ return "날짜 오류"
+ }
+ }, [])
// Initialize form with React Hook Form and Zod
const form = useForm<UpdateRfqSchema>({
@@ -50,6 +85,7 @@ export default function UpdateSheet({ open, onOpenChange, rfqId, onUpdated }: Up
defaultValues: {
rfqId,
description: "",
+ remark: "",
dueDate: "",
},
});
@@ -74,15 +110,43 @@ export default function UpdateSheet({ open, onOpenChange, rfqId, onUpdated }: Up
form.reset({
rfqId,
description: result.data.description || "",
+ remark: result.data.remark || "",
dueDate: result.data.dueDate ? new Date(result.data.dueDate).toISOString().slice(0, 10) : "",
});
+ const pspid = result.data.project[0].pspid || "";
setProjectInfo({
projNm: result.data.project[0].projectName || "",
sector: result.data.project[0].pjtType || "",
projMsrm: result.data.project[0].projMsrm || "",
ptypeNm: result.data.project[0].ptypeNm || "",
rfqNo: result.data.rfqCode || "",
+ pspid: pspid,
+ });
+ setRfqInfo({
+ status: result.data.status || "",
+ createdAt: result.data.createdAt ? format(new Date(result.data.createdAt), "yyyy-MM-dd HH:mm") : "",
+ updatedAt: result.data.updatedAt ? format(new Date(result.data.updatedAt), "yyyy-MM-dd HH:mm") : "",
+ createdByName: (result.data as any).createdByName || (result.data as any).createdBy || "",
+ updatedByName: (result.data as any).updatedByName || (result.data as any).updatedBy || "",
+ sentByName: (result.data as any).sentByName || (result.data as any).sentBy || "",
+ rfqSendDate: result.data.rfqSendDate ? format(new Date(result.data.rfqSendDate), "yyyy-MM-dd HH:mm") : "",
});
+
+ // 시리즈 정보 로드
+ if (pspid) {
+ setIsLoadingSeries(true);
+ try {
+ const seriesResult = await getProjectSeriesForProject(pspid);
+ setSeriesInfo(seriesResult);
+ } catch (error) {
+ console.error("시리즈 정보 로드 오류:", error);
+ setSeriesInfo([]);
+ } finally {
+ setIsLoadingSeries(false);
+ }
+ } else {
+ setSeriesInfo([]);
+ }
}
} catch (error: any) {
toast.error("RFQ 정보를 불러오는 중 오류가 발생했습니다: " + error.message);
@@ -101,6 +165,7 @@ export default function UpdateSheet({ open, onOpenChange, rfqId, onUpdated }: Up
const result = await updateTechSalesRfq({
id: values.rfqId,
description: values.description,
+ remark: values.remark,
dueDate: new Date(values.dueDate),
updatedBy: 1, // Replace with actual user ID
});
@@ -134,9 +199,9 @@ export default function UpdateSheet({ open, onOpenChange, rfqId, onUpdated }: Up
<Sheet open={open} onOpenChange={onOpenChange}>
<SheetContent className="flex flex-col h-full sm:max-w-xl bg-gray-50">
<SheetHeader className="text-left flex-shrink-0">
- <SheetTitle className="text-2xl font-bold">RFQ 수정</SheetTitle>
+ <SheetTitle className="text-2xl font-bold">RFQ 미리보기</SheetTitle>
<SheetDescription className="">
- RFQ 정보를 수정합니다. 모든 필드를 입력한 후 저장 버튼을 클릭하세요.
+ RFQ 정보를 확인하고 필요한 항목을 수정하세요. RFQ Title, Context, 마감일만 수정 가능합니다.
</SheetDescription>
</SheetHeader>
@@ -147,7 +212,9 @@ export default function UpdateSheet({ open, onOpenChange, rfqId, onUpdated }: Up
</div>
) : (
<div className="space-y-6">
+ {/* 프로젝트 정보 */}
<div className="bg-white shadow-sm rounded-lg p-5 border border-gray-200">
+ <h3 className="text-lg font-semibold mb-3 text-gray-800">프로젝트 정보</h3>
<div className="grid grid-cols-2 gap-4 text-sm">
<div>
<span className="font-semibold text-gray-700">프로젝트명:</span> {projectInfo.projNm}
@@ -167,6 +234,73 @@ export default function UpdateSheet({ open, onOpenChange, rfqId, onUpdated }: Up
</div>
</div>
+ {/* 시리즈 정보 - 프로젝트 정보 아래에 배치 */}
+ <div className="bg-white shadow-sm rounded-lg p-5 border border-gray-200">
+ <h3 className="text-lg font-semibold mb-3 text-gray-800">시리즈 정보</h3>
+ {isLoadingSeries ? (
+ <div className="text-center py-4 text-gray-500">
+ 시리즈 정보 로딩 중...
+ </div>
+ ) : seriesInfo && seriesInfo.length > 0 ? (
+ <div className="grid grid-cols-1 gap-3">
+ {seriesInfo.map((series) => (
+ <div key={series.sersNo} className="bg-gray-50 rounded border p-3">
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-4 text-sm">
+ <div>
+ <span className="font-medium text-gray-700">시리즈번호:</span>
+ <div className="text-gray-900">{series.sersNo}</div>
+ </div>
+ <div>
+ <span className="font-medium text-gray-700">K/L (Keel Laying):</span>
+ <div className="text-gray-900">{convertKLToQuarter(series.klDt)}</div>
+ </div>
+ <div>
+ <span className="font-medium text-gray-700">도크코드:</span>
+ <div className="text-gray-900">{series.dockNo || "N/A"}</div>
+ </div>
+ <div>
+ <span className="font-medium text-gray-700">도크명:</span>
+ <div className="text-gray-900">{series.dockNm || "N/A"}</div>
+ </div>
+ </div>
+ </div>
+ ))}
+ </div>
+ ) : (
+ <div className="text-center py-4 text-gray-500">
+ 시리즈 데이터가 없습니다.
+ </div>
+ )}
+ </div>
+
+ {/* RFQ 정보 */}
+ {/* <div className="bg-white shadow-sm rounded-lg p-5 border border-gray-200">
+ <h3 className="text-lg font-semibold mb-3 text-gray-800">RFQ 정보</h3>
+ <div className="grid grid-cols-2 gap-4 text-sm">
+ <div>
+ <span className="font-semibold text-gray-700">상태:</span> {rfqInfo.status}
+ </div>
+ <div>
+ <span className="font-semibold text-gray-700">생성자:</span> {rfqInfo.createdByName}
+ </div>
+ <div>
+ <span className="font-semibold text-gray-700">생성일:</span> {rfqInfo.createdAt}
+ </div>
+ <div>
+ <span className="font-semibold text-gray-700">수정자:</span> {rfqInfo.updatedByName}
+ </div>
+ <div>
+ <span className="font-semibold text-gray-700">수정일:</span> {rfqInfo.updatedAt}
+ </div>
+ <div>
+ <span className="font-semibold text-gray-700">발송자:</span> {rfqInfo.sentByName}
+ </div>
+ <div>
+ <span className="font-semibold text-gray-700">발송일:</span> {rfqInfo.rfqSendDate}
+ </div>
+ </div>
+ </div> */}
+
<Form {...form}>
<form id="update-rfq-form" onSubmit={form.handleSubmit(onSubmit)} className="flex flex-col gap-4">
<FormField
@@ -189,6 +323,24 @@ export default function UpdateSheet({ open, onOpenChange, rfqId, onUpdated }: Up
<FormField
control={form.control}
+ name="remark"
+ render={({ field }) => (
+ <FormItem>
+ <FormLabel className="text-sm font-medium text-gray-700">RFQ Context</FormLabel>
+ <FormControl>
+ <Textarea
+ {...field}
+ placeholder="RFQ Context를 입력하세요"
+ className="border-gray-300 rounded-md min-h-[100px]"
+ />
+ </FormControl>
+ <FormMessage />
+ </FormItem>
+ )}
+ />
+
+ <FormField
+ control={form.control}
name="dueDate"
render={({ field }) => (
<FormItem className="flex flex-col">