From 0547ab2fe1701d84753d0e078bba718a79b07a0c Mon Sep 17 00:00:00 2001 From: dujinkim Date: Fri, 23 May 2025 05:26:26 +0000 Subject: (최겸)기술영업 벤더 개발 초안(index 스키마 미포함 상태) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../(evcp)/tech-vendors/[id]/info/items/page.tsx | 56 +++++++++++++++++ .../evcp/(evcp)/tech-vendors/[id]/info/layout.tsx | 73 ++++++++++++++++++++++ .../evcp/(evcp)/tech-vendors/[id]/info/page.tsx | 56 +++++++++++++++++ app/[lng]/evcp/(evcp)/tech-vendors/page.tsx | 71 +++++++++++++++++++++ 4 files changed, 256 insertions(+) create mode 100644 app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/items/page.tsx create mode 100644 app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/layout.tsx create mode 100644 app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/page.tsx create mode 100644 app/[lng]/evcp/(evcp)/tech-vendors/page.tsx (limited to 'app') diff --git a/app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/items/page.tsx b/app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/items/page.tsx new file mode 100644 index 00000000..5ca4492e --- /dev/null +++ b/app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/items/page.tsx @@ -0,0 +1,56 @@ +import { Separator } from "@/components/ui/separator" +import { getVendorItemsByType, findVendorById } from "@/lib/tech-vendors/service" +import { type SearchParams } from "@/types/table" +import { TechVendorItemsTable } from "@/lib/tech-vendors/items-table/item-table" +import { notFound } from "next/navigation" + +interface PageProps { + params: { + lng: string + id: string + } + searchParams: Promise +} + +export default async function Page(props: PageProps) { + const resolvedParams = await props.params + const id = resolvedParams.id + const vendorId = Number(id) + + if (isNaN(vendorId)) { + notFound() + } + + const vendor = await findVendorById(vendorId) + if (!vendor) { + notFound() + } + + const items = await getVendorItemsByType(vendorId, vendor.techVendorType) + + return ( +
+
+

+ Possible Items +

+

+ 딜리버리가 가능한 아이템 리스트를 확인할 수 있습니다. +

+
+ +
+ ({ + ...item, + vendorId, + itemName: item.itemCode, + vendorItemId: item.id + }))} + vendorId={vendorId} + vendorType={vendor.techVendorType} + /> +
+
+ ) +} \ No newline at end of file diff --git a/app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/layout.tsx b/app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/layout.tsx new file mode 100644 index 00000000..508ae82a --- /dev/null +++ b/app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/layout.tsx @@ -0,0 +1,73 @@ +import { Metadata } from "next" + +import { Separator } from "@/components/ui/separator" +import { SidebarNav } from "@/components/layout/sidebar-nav" +import { findVendorById } from "@/lib/tech-vendors/service" +import { TechVendor } from "@/db/schema/techVendors" +import { Button } from "@/components/ui/button" +import { ArrowLeft } from "lucide-react" +import Link from "next/link" + +export const metadata: Metadata = { + title: "Tech Vendor Detail", +} + +export default async function SettingsLayout({ + children, + params, +}: { + children: React.ReactNode + params: { lng: string, id: string } +}) { + const resolvedParams = await params + const lng = resolvedParams.lng + const id = resolvedParams.id + + const idAsNumber = Number(id) + const vendor: TechVendor | null = await findVendorById(idAsNumber) + + const sidebarNavItems = [ + { + title: "연락처", + href: `/${lng}/evcp/tech-vendors/${id}/info`, + }, + { + title: "공급품목", + href: `/${lng}/evcp/tech-vendors/${id}/info/items`, + }, + ] + + return ( + <> +
+
+
+
+ + + +
+
+

+ {vendor + ? `${vendor.vendorCode ?? ""} - ${vendor.vendorName} 상세 정보` + : "Loading Vendor..."} +

+

기술협력업체 관련 상세사항을 확인하세요.

+
+ +
+ +
{children}
+
+
+
+
+ + ) +} \ No newline at end of file diff --git a/app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/page.tsx b/app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/page.tsx new file mode 100644 index 00000000..0092ee70 --- /dev/null +++ b/app/[lng]/evcp/(evcp)/tech-vendors/[id]/info/page.tsx @@ -0,0 +1,56 @@ +import { Separator } from "@/components/ui/separator" +import { getTechVendorContacts } from "@/lib/tech-vendors/service" +import { type SearchParams } from "@/types/table" +import { getValidFilters } from "@/lib/data-table" +import { searchParamsContactCache } from "@/lib/tech-vendors/validations" +import { TechVendorContactsTable } from "@/lib/tech-vendors/contacts-table/contact-table" + +interface IndexPageProps { + // Next.js 13 App Router에서 기본으로 주어지는 객체들 + params: { + lng: string + id: string + } + searchParams: Promise +} + +export default async function SettingsAccountPage(props: IndexPageProps) { + const resolvedParams = await props.params + const lng = resolvedParams.lng + const id = resolvedParams.id + + const idAsNumber = Number(id) + + // 2) SearchParams 파싱 (Zod) + // - "filters", "page", "perPage", "sort" 등 contact 전용 컬럼 + const searchParams = await props.searchParams + const search = searchParamsContactCache.parse(searchParams) + const validFilters = getValidFilters(search.filters) + + + + const promises = Promise.all([ + getTechVendorContacts({ + ...search, + filters: validFilters, + }, + idAsNumber) + ]) + // 4) 렌더링 + return ( +
+
+

+ Contacts +

+

+ 업무별 담당자 정보를 확인하세요. +

+
+ +
+ +
+
+ ) +} \ No newline at end of file diff --git a/app/[lng]/evcp/(evcp)/tech-vendors/page.tsx b/app/[lng]/evcp/(evcp)/tech-vendors/page.tsx new file mode 100644 index 00000000..176a6fbc --- /dev/null +++ b/app/[lng]/evcp/(evcp)/tech-vendors/page.tsx @@ -0,0 +1,71 @@ +import * as React from "react" +import { type SearchParams } from "@/types/table" + +import { getValidFilters } from "@/lib/data-table" +import { Skeleton } from "@/components/ui/skeleton" +import { DataTableSkeleton } from "@/components/data-table/data-table-skeleton" +import { Shell } from "@/components/shell" + +import { searchParamsCache } from "@/lib/tech-vendors/validations" +import { getTechVendors, getTechVendorStatusCounts } from "@/lib/tech-vendors/service" +import { TechVendorsTable } from "@/lib/tech-vendors/table/tech-vendors-table" +import { Ellipsis } from "lucide-react" + +interface IndexPageProps { + searchParams: Promise +} + +export default async function IndexPage(props: IndexPageProps) { + const searchParams = await props.searchParams + const search = searchParamsCache.parse(searchParams) + + const validFilters = getValidFilters(search.filters) + + const promises = Promise.all([ + getTechVendors({ + ...search, + filters: validFilters, + }), + getTechVendorStatusCounts(), + ]) + + return ( + +
+
+
+

+ 협력업체 리스트(기술영업) +

+

+ 기술영업 협력업체에 대한 요약 정보를 확인하고{" "} + + + 버튼 + + 을 통해 담당자 연락처, 공급 가능 아이템 등을 확인할 수 있습니다.
+ 벤더의 상태에 따라 가입을 승인해주거나 거부할 수 있습니다. +

+
+
+
+ + }> + {/* 필요한 경우 데이터 범위 선택기 등의 추가 UI를 이곳에 배치할 수 있습니다 */} + + + } + > + + +
+ ) +} -- cgit v1.2.3