diff options
Diffstat (limited to 'app')
| -rw-r--r-- | app/[lng]/evcp/(evcp)/(procurement)/pq_new/[vendorId]/[submissionId]/page.tsx | 1 | ||||
| -rw-r--r-- | app/[lng]/partners/(partners)/pq_new/[id]/page.tsx | 20 | ||||
| -rw-r--r-- | app/[lng]/partners/(partners)/pq_new/page.tsx | 31 | ||||
| -rw-r--r-- | app/api/juso/route.ts | 69 |
4 files changed, 120 insertions, 1 deletions
diff --git a/app/[lng]/evcp/(evcp)/(procurement)/pq_new/[vendorId]/[submissionId]/page.tsx b/app/[lng]/evcp/(evcp)/(procurement)/pq_new/[vendorId]/[submissionId]/page.tsx index 8e3006cc..93302f87 100644 --- a/app/[lng]/evcp/(evcp)/(procurement)/pq_new/[vendorId]/[submissionId]/page.tsx +++ b/app/[lng]/evcp/(evcp)/(procurement)/pq_new/[vendorId]/[submissionId]/page.tsx @@ -157,6 +157,7 @@ export default async function PQReviewPage(props: PQReviewPageProps) { vendorId={vendorId}
pqSubmission={pqSubmission}
vendorInfo={vendorInfo}
+ vendorCountry={pqSubmission.vendorCountry}
/>
</TabsContent>
diff --git a/app/[lng]/partners/(partners)/pq_new/[id]/page.tsx b/app/[lng]/partners/(partners)/pq_new/[id]/page.tsx index f298cc77..8fbf15db 100644 --- a/app/[lng]/partners/(partners)/pq_new/[id]/page.tsx +++ b/app/[lng]/partners/(partners)/pq_new/[id]/page.tsx @@ -3,6 +3,7 @@ import Link from "next/link"; import { getServerSession } from "next-auth/next"; import { authOptions } from "@/app/api/auth/[...nextauth]/route"; import { Button } from "@/components/ui/button"; +import { Badge } from "@/components/ui/badge"; import { ArrowLeft, LogIn } from "lucide-react"; import { Shell } from "@/components/shell"; import { getPQById, getPQDataByVendorId } from "@/lib/pq/service"; @@ -159,6 +160,24 @@ export default async function PQEditPage(props: PQEditPageProps) { </Alert> )} */} + <div className="rounded-lg border p-4 space-y-2"> + <h3 className="text-sm font-semibold">PQ 품목</h3> + {Array.isArray(pqSubmission.pqItems) && pqSubmission.pqItems.length > 0 ? ( + <div className="flex flex-wrap gap-2"> + {pqSubmission.pqItems.map((item: any, idx: number) => ( + <Badge key={idx} variant="outline"> + {item?.itemName || item?.itemCode || "품목"} + {item?.itemCode ? ` (${item.itemCode})` : ""} + </Badge> + ))} + </div> + ) : pqSubmission.pqItems ? ( + <div className="text-sm">{String(pqSubmission.pqItems)}</div> + ) : ( + <p className="text-sm text-muted-foreground">지정된 PQ 품목이 없습니다.</p> + )} + </div> + {/* PQ 입력 컴포넌트 */} <PQInputTabs data={pqData} @@ -171,6 +190,7 @@ export default async function PQEditPage(props: PQEditPageProps) { status: pqSubmission.status, type: pqSubmission.type }} + vendorCountry={pqSubmission.vendorCountry} /> </Shell> ); diff --git a/app/[lng]/partners/(partners)/pq_new/page.tsx b/app/[lng]/partners/(partners)/pq_new/page.tsx index fb77ce0e..b6cc3535 100644 --- a/app/[lng]/partners/(partners)/pq_new/page.tsx +++ b/app/[lng]/partners/(partners)/pq_new/page.tsx @@ -65,6 +65,31 @@ function getFormattedDate(date: Date | null) { }).format(new Date(date)); } +function renderPQItems(pqItems: unknown) { + if (!pqItems) return "-"; + + if (typeof pqItems === "string") { + return pqItems || "-"; + } + + if (Array.isArray(pqItems)) { + if (pqItems.length === 0) return "-"; + + return ( + <div className="flex flex-wrap gap-1"> + {pqItems.map((item: any, idx: number) => ( + <Badge key={idx} variant="outline"> + {item?.itemName || item?.itemCode || ""} + {item?.itemCode ? ` (${item.itemCode})` : ""} + </Badge> + ))} + </div> + ); + } + + return "-"; +} + export default async function PQListPage({ params }: IndexPageProps) { // 캐시 비활성화 noStore(); @@ -212,6 +237,7 @@ export default async function PQListPage({ params }: IndexPageProps) { <TableHead>유형</TableHead> <TableHead>PQ 번호</TableHead> <TableHead>프로젝트</TableHead> + <TableHead>PQ 품목</TableHead> <TableHead>상태</TableHead> <TableHead>요청일</TableHead> <TableHead>제출일</TableHead> @@ -222,7 +248,7 @@ export default async function PQListPage({ params }: IndexPageProps) { <TableBody> {pqList.length === 0 ? ( <TableRow> - <TableCell colSpan={8} className="text-center py-8 text-muted-foreground"> + <TableCell colSpan={9} className="text-center py-8 text-muted-foreground"> 요청된 PQ가 없습니다. </TableCell> </TableRow> @@ -251,6 +277,9 @@ export default async function PQListPage({ params }: IndexPageProps) { {pq.projectName || "-"} </TableCell> <TableCell> + {renderPQItems(pq.pqItems)} + </TableCell> + <TableCell> {getStatusBadge(pq.status)} </TableCell> <TableCell> diff --git a/app/api/juso/route.ts b/app/api/juso/route.ts new file mode 100644 index 00000000..258e51d3 --- /dev/null +++ b/app/api/juso/route.ts @@ -0,0 +1,69 @@ +"use server"; + +import { NextRequest, NextResponse } from "next/server"; + +const JUSO_URL = "https://business.juso.go.kr/addrlink/addrLinkUrl.do"; + +export async function GET() { + const confmKey = process.env.JUSO_API_KEY || ""; + const returnUrl = `${process.env.NEXT_PUBLIC_BASE_URL || ""}/api/juso`; + const resultType = "4"; + + const html = ` + <!doctype html> + <html lang="ko"> + <head><meta charset="utf-8" /></head> + <body onload="document.getElementById('jusoForm').submit();"> + <form id="jusoForm" name="jusoForm" method="post" action="${JUSO_URL}"> + <input type="hidden" name="confmKey" value="${confmKey}" /> + <input type="hidden" name="returnUrl" value="${returnUrl}" /> + <input type="hidden" name="resultType" value="${resultType}" /> + </form> + </body> + </html> + `; + + return new NextResponse(html, { + status: 200, + headers: { "Content-Type": "text/html; charset=utf-8" }, + }); +} + +export async function POST(req: NextRequest) { + const formData = await req.formData(); + + const zipNo = String(formData.get("zipNo") || ""); + const roadAddrPart1 = String(formData.get("roadAddrPart1") || ""); + const roadAddrPart2 = String(formData.get("roadAddrPart2") || ""); + const addrDetail = String(formData.get("addrDetail") || ""); + + const origin = process.env.NEXT_PUBLIC_BASE_URL || "*"; + + const script = ` + <script> + (function() { + try { + const payload = { + zipNo: ${JSON.stringify(zipNo)}, + roadAddrPart1: ${JSON.stringify(roadAddrPart1)}, + roadAddrPart2: ${JSON.stringify(roadAddrPart2)}, + addrDetail: ${JSON.stringify(addrDetail)} + }; + if (window.opener && !window.opener.closed) { + window.opener.postMessage({ type: "JUSO_SELECTED", payload }, "${origin}"); + } + } catch (e) { + console.error(e); + } finally { + window.close(); + } + })(); + </script> + `; + + return new NextResponse(script, { + status: 200, + headers: { "Content-Type": "text/html; charset=utf-8" }, + }); +} + |
