summaryrefslogtreecommitdiff
path: root/components/po-rfq/po-rfq-container.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'components/po-rfq/po-rfq-container.tsx')
-rw-r--r--components/po-rfq/po-rfq-container.tsx261
1 files changed, 0 insertions, 261 deletions
diff --git a/components/po-rfq/po-rfq-container.tsx b/components/po-rfq/po-rfq-container.tsx
deleted file mode 100644
index e5159242..00000000
--- a/components/po-rfq/po-rfq-container.tsx
+++ /dev/null
@@ -1,261 +0,0 @@
-"use client"
-
-import { useState, useEffect, useCallback, useRef } from "react"
-import { useSearchParams, useRouter } from "next/navigation"
-import { Button } from "@/components/ui/button"
-import { PanelLeft, PanelLeftClose, PanelLeftOpen } from "lucide-react"
-
-// shadcn/ui components
-import {
- ResizablePanelGroup,
- ResizablePanel,
- ResizableHandle,
-} from "@/components/ui/resizable"
-
-import { cn } from "@/lib/utils"
-import { ProcurementRfqsView } from "@/db/schema"
-import { RFQListTable } from "@/lib/procurement-rfqs/table/rfq-table"
-import { getPORfqs } from "@/lib/procurement-rfqs/services"
-import { RFQFilterSheet } from "./rfq-filter-sheet"
-import { DataTableSkeleton } from "@/components/data-table/data-table-skeleton"
-import { RfqDetailTables } from "./detail-table/rfq-detail-table"
-
-interface RfqContainerProps {
- // 초기 데이터 (필수)
- initialData: Awaited<ReturnType<typeof getPORfqs>>
- // 서버 액션으로 데이터를 가져오는 함수
- fetchData: (params: any) => Promise<Awaited<ReturnType<typeof getPORfqs>>>
-}
-
-export default function RFQContainer({
- initialData,
- fetchData
-}: RfqContainerProps) {
- const router = useRouter()
- const searchParams = useSearchParams()
-
- // Whether the filter panel is open (now a side panel instead of sheet)
- const [isFilterPanelOpen, setIsFilterPanelOpen] = useState(false)
-
- // 데이터 상태 관리 - 초기 데이터로 시작
- const [data, setData] = useState<Awaited<ReturnType<typeof getPORfqs>>>(initialData)
- const [isLoading, setIsLoading] = useState(false)
-
- // 선택된 문서를 이 state로 관리
- const [selectedRfq, setSelectedRfq] = useState<ProcurementRfqsView | null>(null)
-
- // 패널 collapse
- const [isTopCollapsed, setIsTopCollapsed] = useState(false)
-
- // 이전 URL 파라미터를 저장하기 위한 ref
- const prevParamsRef = useRef<string>(searchParams.toString())
-
- // 현재 URL 파라미터로부터 필터 데이터 구성
- const getFilterParams = useCallback(() => {
- return {
- page: searchParams.get('page') || '1',
- perPage: searchParams.get('perPage') || '10',
- sort: searchParams.get('sort') || JSON.stringify([{ id: "updatedAt", desc: true }]),
- basicFilters: searchParams.get('basicFilters') || null,
- basicJoinOperator: searchParams.get('basicJoinOperator') || 'and',
- filters: searchParams.get('filters') || null,
- joinOperator: searchParams.get('joinOperator') || 'and',
- search: searchParams.get('search') || '',
- }
- }, [searchParams])
-
- // 데이터 로드 함수
- const loadData = useCallback(async () => {
- try {
- setIsLoading(true)
- const filterParams = getFilterParams()
-
- console.log("데이터 로드 시작:", filterParams)
-
- // 서버 액션으로 데이터 가져오는 함수
- const newData = await fetchData(filterParams)
-
- console.log("데이터 로드 완료:", newData.data.length, "건")
-
- setData(newData)
- } catch (error) {
- console.error("데이터 로드 오류:", error)
- } finally {
- setIsLoading(false)
- }
- }, [fetchData, getFilterParams])
-
- const refreshData = useCallback(() => {
- // 현재 파라미터로 데이터 다시 로드
- loadData();
- }, [loadData]);
-
- // URL 파라미터 변경 감지
- useEffect(() => {
- const currentParams = searchParams.toString()
-
- // 파라미터가 변경되었을 때만 데이터 로드
- if (currentParams !== prevParamsRef.current) {
- console.log("URL 파라미터 변경 감지:", {
- previous: prevParamsRef.current,
- current: currentParams,
- })
-
- prevParamsRef.current = currentParams
- loadData()
- }
- }, [searchParams, loadData])
-
- // 문서 선택 핸들러
- const handleSelectRfq = (rfq: ProcurementRfqsView | null) => {
- setSelectedRfq(rfq)
- }
-
- // 조회 버튼 클릭 핸들러 - RFQFilterSheet에 전달
- // 페이지 리라우팅을 통해 처리하므로 별도 로직 불필요
- const handleSearch = () => {
- // Close the panel after search
- setIsFilterPanelOpen(false)
- }
-
- const [panelHeight, setPanelHeight] = useState<number>(400)
-
- // Get active filter count for UI display
- const getActiveFilterCount = () => {
- try {
- const basicFilters = searchParams.get('basicFilters')
- return basicFilters ? JSON.parse(basicFilters).length : 0
- } catch (e) {
- console.error("Error parsing filters:", e)
- return 0
- }
- }
-
- // Filter panel width in pixels
- const FILTER_PANEL_WIDTH = 400;
-
- // Table refresh key - 패널 상태가 변경되면 테이블을 강제로 재렌더링
- const [tableRefreshKey, setTableRefreshKey] = useState(0);
-
- useEffect(() => {
- // 패널 상태가 변경될 때 테이블 강제 재렌더링
- setTableRefreshKey(prev => prev + 1);
- }, [isFilterPanelOpen]);
-
- return (
- <div className="h-[calc(100vh-220px)] w-full overflow-hidden relative">
- {/* Fixed Filter Panel - 가장 왼쪽부터 시작, 전체 높이 맞춤 */}
- <div
- className={cn(
- "fixed left-0 bg-background border-r overflow-hidden flex flex-col transition-all duration-300 ease-in-out z-30",
- isFilterPanelOpen ? "border-r" : "border-r-0"
- )}
- style={{
- width: isFilterPanelOpen ? `${FILTER_PANEL_WIDTH}px` : '0px',
- height: 'calc(100vh - 130px)' // 나머지 높이 전체 사용
- }}
- >
- {/* Filter Content - 제목 포함하여 내부에서 처리 */}
- <div className="h-full">
- <RFQFilterSheet
- isOpen={isFilterPanelOpen}
- onClose={() => setIsFilterPanelOpen(false)}
- onSearch={handleSearch}
- isLoading={isLoading}
- />
- </div>
- </div>
-
- {/* Main Content Panel - 패널이 열릴 때 오른쪽으로 이동 */}
- <div
- className="h-full overflow-hidden transition-all duration-300 ease-in-out"
- style={{
- marginLeft: isFilterPanelOpen ? `${FILTER_PANEL_WIDTH}px` : '0px'
- }}
- >
- {/* Filter Toggle Button - 메인 콘텐츠 상단에 위치 */}
- <div className="flex items-center p-4 border-b bg-background pl-0">
- <Button
- variant="outline"
- size="sm"
- type='button'
- onClick={() => setIsFilterPanelOpen(!isFilterPanelOpen)}
- className="flex items-center shadow-md"
- >
- {
- isFilterPanelOpen ? <PanelLeftClose className="size-4"/> : <PanelLeftOpen className="size-4"/>
- }
- {/* 검색 필터 */}
- {getActiveFilterCount() > 0 && (
- <span className="ml-2 bg-primary text-primary-foreground rounded-full px-2 py-0.5 text-xs">
- {getActiveFilterCount()}
- </span>
- )}
- </Button>
-
- {/* 추가적인 헤더 정보나 버튼들을 여기에 배치할 수 있음 */}
- <div className="flex-1" />
- <div className="text-sm text-muted-foreground">
- {data && !isLoading && (
- <span>총 {data.total || 0}건</span>
- )}
- </div>
- </div>
-
- {/* Main Content Area */}
- <div className="h-[calc(100%-64px)] w-full overflow-hidden">
- {isLoading ? (
- // 로딩 중 상태
- <DataTableSkeleton
- columnCount={6}
- searchableColumnCount={1}
- filterableColumnCount={2}
- cellWidths={["10rem", "40rem", "12rem", "12rem", "8rem", "8rem"]}
- shrinkZero
- />
- ) : (
- // 데이터 로드 완료 상태
- <ResizablePanelGroup direction="vertical" className="h-full">
- <ResizablePanel
- defaultSize={55}
- minSize={0}
- maxSize={95}
- collapsible
- collapsedSize={10}
- onCollapse={() => setIsTopCollapsed(true)}
- onExpand={() => setIsTopCollapsed(false)}
- onResize={(size) => {
- setPanelHeight(size)
- }}
- className={cn("overflow-y-auto overflow-x-hidden border-b", isTopCollapsed && "transition-all")}
- >
- <div className="flex h-full min-h-0 flex-col">
- <RFQListTable
- key={tableRefreshKey} // Force re-render when panel toggles
- maxHeight={`${panelHeight*0.5}vh`}
- data={data}
- onSelectRFQ={handleSelectRfq}
- onDataRefresh={refreshData}
- />
- </div>
- </ResizablePanel>
-
- <ResizableHandle
- withHandle
- className="pointer-events-none data-[resize-handle]:pointer-events-auto"
- />
-
- <ResizablePanel
- minSize={0}
- defaultSize={35}
- className="overflow-y-auto overflow-x-hidden"
- >
- <RfqDetailTables selectedRfq={selectedRfq} />
- </ResizablePanel>
- </ResizablePanelGroup>
- )}
- </div>
- </div>
- </div>
- )
-} \ No newline at end of file