diff options
| author | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-06-23 09:02:07 +0000 |
|---|---|---|
| committer | dujinkim <dujin.kim@dtsolution.co.kr> | 2025-06-23 09:02:07 +0000 |
| commit | 5c9b39eb011763a7491b3e8542de9f6d4976dd65 (patch) | |
| tree | ef18c420a72b0e4c8d5dfd03ae1e8648dda906f7 /components/tech-vendors/tech-vendor-items-container.tsx | |
| parent | a75541e1a1aea596bfca2a435f39133b9b72f193 (diff) | |
(최겸) 기술영업 벤더 개발
Diffstat (limited to 'components/tech-vendors/tech-vendor-items-container.tsx')
| -rw-r--r-- | components/tech-vendors/tech-vendor-items-container.tsx | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/components/tech-vendors/tech-vendor-items-container.tsx b/components/tech-vendors/tech-vendor-items-container.tsx new file mode 100644 index 00000000..49a9d4ee --- /dev/null +++ b/components/tech-vendors/tech-vendor-items-container.tsx @@ -0,0 +1,121 @@ +"use client"
+
+import * as React from "react"
+import { useRouter, usePathname, useSearchParams } from "next/navigation"
+import { ChevronDown } from "lucide-react"
+
+import { type TechVendor } from "@/db/schema/techVendors"
+
+import { Button } from "@/components/ui/button"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu"
+import { TechVendorItemsTable } from "@/lib/tech-vendors/items-table/item-table"
+import { getVendorItemsByType } from "@/lib/tech-vendors/service"
+
+interface ItemType {
+ id: string
+ name: string
+ vendorType: string
+}
+
+interface TechVendorItemsContainerProps {
+ vendorId: number
+ vendor: TechVendor
+ itemTypes: ItemType[]
+}
+
+export function TechVendorItemsContainer({
+ vendorId,
+ vendor,
+ itemTypes,
+}: TechVendorItemsContainerProps) {
+ const router = useRouter()
+ const pathname = usePathname()
+ const searchParamsObj = useSearchParams()
+
+ // useSearchParams를 메모이제이션하여 안정적인 참조 생성
+ const currentSearchParams = React.useMemo(
+ () => searchParamsObj || new URLSearchParams(),
+ [searchParamsObj]
+ )
+
+ // URL에서 현재 선택된 아이템 타입 가져오기 (기본값은 첫 번째 타입)
+ const itemType = currentSearchParams.get("type") || itemTypes[0]?.id || "ship"
+
+ // 선택한 아이템 타입에 해당하는 정보 찾기
+ const selectedItemType = itemTypes.find((item) => item.id === itemType) || itemTypes[0]
+
+ // 아이템 타입 변경 핸들러
+ const handleItemTypeChange = React.useCallback((value: string) => {
+ const params = new URLSearchParams(currentSearchParams.toString())
+ params.set("type", value)
+
+ router.push(`${pathname}?${params.toString()}`)
+ }, [router, pathname, currentSearchParams])
+
+ // 현재 선택된 벤더 타입에 대한 아이템 데이터 가져오기
+ const promises = React.useMemo(() => {
+ if (selectedItemType) {
+ return getVendorItemsByType(vendorId, selectedItemType.vendorType)
+ }
+ return Promise.resolve({ data: [] })
+ }, [vendorId, selectedItemType])
+
+ // 벤더 타입이 하나뿐인 경우 드롭다운 숨기기
+ const showDropdown = itemTypes.length > 1
+
+ return (
+ <>
+ {/* 상단 영역: 제목 왼쪽 / 아이템 타입 선택기 오른쪽 */}
+ <div className="flex items-center justify-between">
+ {/* 왼쪽: 타이틀 & 설명 */}
+ <div>
+ <h4 className="text-lg font-medium">자재 목록</h4>
+ <p className="text-sm text-muted-foreground">
+ {vendor.vendorName}의 공급 가능한 자재 목록입니다.
+ </p>
+ </div>
+
+ {/* 오른쪽: 아이템 타입 드롭다운 (타입이 여러 개인 경우에만 표시) */}
+ {showDropdown && (
+ <DropdownMenu>
+ <DropdownMenuTrigger asChild>
+ <Button variant="outline" className="min-w-[150px]">
+ {selectedItemType?.name || "타입 선택"}
+ <ChevronDown className="ml-2 h-4 w-4" />
+ </Button>
+ </DropdownMenuTrigger>
+ <DropdownMenuContent align="end" className="w-[200px]">
+ {itemTypes.map((item) => (
+ <DropdownMenuItem
+ key={item.id}
+ onClick={() => handleItemTypeChange(item.id)}
+ className={item.id === itemType ? "bg-muted" : ""}
+ >
+ {item.name}
+ </DropdownMenuItem>
+ ))}
+ </DropdownMenuContent>
+ </DropdownMenu>
+ )}
+ </div>
+
+ {/* 컨텐츠 영역 */}
+ <section className="overflow-hidden">
+ <div>
+ {selectedItemType && (
+ <TechVendorItemsTable
+ promises={promises}
+ vendorId={vendorId}
+ vendorType={selectedItemType.vendorType}
+ />
+ )}
+ </div>
+ </section>
+ </>
+ )
+}
\ No newline at end of file |
