summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/[lng]/evcp/(evcp)/(procurement)/pq_new/[vendorId]/[submissionId]/page.tsx1
-rw-r--r--app/[lng]/partners/(partners)/pq_new/[id]/page.tsx20
-rw-r--r--app/[lng]/partners/(partners)/pq_new/page.tsx31
-rw-r--r--app/api/juso/route.ts69
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" },
+ });
+}
+