diff options
Diffstat (limited to 'lib/pq/pq-review-table-new/pq-container.tsx')
| -rw-r--r-- | lib/pq/pq-review-table-new/pq-container.tsx | 300 |
1 files changed, 150 insertions, 150 deletions
diff --git a/lib/pq/pq-review-table-new/pq-container.tsx b/lib/pq/pq-review-table-new/pq-container.tsx index ebe46809..01b7aab1 100644 --- a/lib/pq/pq-review-table-new/pq-container.tsx +++ b/lib/pq/pq-review-table-new/pq-container.tsx @@ -1,151 +1,151 @@ -"use client" - -import { useState, useEffect, useCallback, useRef } from "react" -import { useSearchParams } from "next/navigation" -import { Button } from "@/components/ui/button" -import { PanelLeftClose, PanelLeftOpen } from "lucide-react" - -import { cn } from "@/lib/utils" -import { getPQSubmissions } from "../service" -import { PQSubmissionsTable } from "./vendors-table" -import { PQFilterSheet } from "./pq-filter-sheet" - -interface PQContainerProps { - // Promise.all로 감싼 promises를 받음 - promises: Promise<[Awaited<ReturnType<typeof getPQSubmissions>>]> - // 컨테이너 클래스명 (옵션) - className?: string -} - -export default function PQContainer({ - promises, - className -}: PQContainerProps) { - const searchParams = useSearchParams() - - // Whether the filter panel is open - const [isFilterPanelOpen, setIsFilterPanelOpen] = useState(false) - - // Container wrapper의 위치를 측정하기 위한 ref - const containerRef = useRef<HTMLDivElement>(null) - const [containerTop, setContainerTop] = useState(0) - - // Container 위치 측정 함수 - top만 측정 - const updateContainerBounds = useCallback(() => { - if (containerRef.current) { - const rect = containerRef.current.getBoundingClientRect() - setContainerTop(rect.top) - } - }, []) - - // 컴포넌트 마운트 시와 윈도우 리사이즈 시 위치 업데이트 - useEffect(() => { - updateContainerBounds() - - const handleResize = () => { - updateContainerBounds() - } - - window.addEventListener('resize', handleResize) - window.addEventListener('scroll', updateContainerBounds) - - return () => { - window.removeEventListener('resize', handleResize) - window.removeEventListener('scroll', updateContainerBounds) - } - }, [updateContainerBounds]) - - // 조회 버튼 클릭 핸들러 - PQFilterSheet에 전달 - const handleSearch = () => { - // Close the panel after search - setIsFilterPanelOpen(false) - } - - // Get active filter count for UI display (서버 사이드 필터만 계산) - const getActiveFilterCount = () => { - try { - // 새로운 이름 우선, 기존 이름도 지원 - const basicFilters = searchParams.get('basicFilters') || searchParams.get('pqBasicFilters') - return basicFilters ? JSON.parse(basicFilters).length : 0 - } catch (e) { - return 0 - } - } - - // Filter panel width - const FILTER_PANEL_WIDTH = 400; - - return ( - <> - {/* Filter Panel - fixed positioning으로 화면 최대 좌측에서 시작 */} - <div - className={cn( - "fixed left-0 bg-background border-r z-50 flex flex-col transition-all duration-300 ease-in-out overflow-hidden", - isFilterPanelOpen ? "border-r shadow-lg" : "border-r-0" - )} - style={{ - width: isFilterPanelOpen ? `${FILTER_PANEL_WIDTH}px` : '0px', - top: `${containerTop}px`, - height: `calc(100vh - ${containerTop}px)` - }} - > - {/* Filter Content */} - <div className="h-full"> - <PQFilterSheet - isOpen={isFilterPanelOpen} - onClose={() => setIsFilterPanelOpen(false)} - onSearch={handleSearch} - isLoading={false} // 로딩 상태 제거 - /> - </div> - </div> - - {/* Main Content Container */} - <div - ref={containerRef} - className={cn("relative w-full overflow-hidden", className)} - > - <div className="flex w-full h-full"> - {/* Main Content - 너비 조정으로 필터 패널 공간 확보 */} - <div - className="flex flex-col min-w-0 overflow-hidden transition-all duration-300 ease-in-out" - style={{ - width: isFilterPanelOpen ? `calc(100% - ${FILTER_PANEL_WIDTH}px)` : '100%', - marginLeft: isFilterPanelOpen ? `${FILTER_PANEL_WIDTH}px` : '0px' - }} - > - {/* Header Bar */} - <div className="flex items-center justify-between p-4 bg-background shrink-0"> - <div className="flex items-center gap-3"> - <Button - variant="outline" - size="sm" - type='button' - onClick={() => setIsFilterPanelOpen(!isFilterPanelOpen)} - className="flex items-center shadow-sm" - > - { - 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> - </div> - - {/* Table Content Area */} - <div className="flex-1 overflow-hidden" style={{ height: 'calc(100vh - 380px)' }}> - <div className="h-full w-full"> - {/* Promise를 직접 전달 - Items와 동일한 패턴 */} - <PQSubmissionsTable promises={promises} /> - </div> - </div> - </div> - </div> - </div> - </> - ) +"use client"
+
+import { useState, useEffect, useCallback, useRef } from "react"
+import { useSearchParams } from "next/navigation"
+import { Button } from "@/components/ui/button"
+import { PanelLeftClose, PanelLeftOpen } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+import { getPQSubmissions } from "../service"
+import { PQSubmissionsTable } from "./vendors-table"
+import { PQFilterSheet } from "./pq-filter-sheet"
+
+interface PQContainerProps {
+ // Promise.all로 감싼 promises를 받음
+ promises: Promise<[Awaited<ReturnType<typeof getPQSubmissions>>]>
+ // 컨테이너 클래스명 (옵션)
+ className?: string
+}
+
+export default function PQContainer({
+ promises,
+ className
+}: PQContainerProps) {
+ const searchParams = useSearchParams()
+
+ // Whether the filter panel is open
+ const [isFilterPanelOpen, setIsFilterPanelOpen] = useState(false)
+
+ // Container wrapper의 위치를 측정하기 위한 ref
+ const containerRef = useRef<HTMLDivElement>(null)
+ const [containerTop, setContainerTop] = useState(0)
+
+ // Container 위치 측정 함수 - top만 측정
+ const updateContainerBounds = useCallback(() => {
+ if (containerRef.current) {
+ const rect = containerRef.current.getBoundingClientRect()
+ setContainerTop(rect.top)
+ }
+ }, [])
+
+ // 컴포넌트 마운트 시와 윈도우 리사이즈 시 위치 업데이트
+ useEffect(() => {
+ updateContainerBounds()
+
+ const handleResize = () => {
+ updateContainerBounds()
+ }
+
+ window.addEventListener('resize', handleResize)
+ window.addEventListener('scroll', updateContainerBounds)
+
+ return () => {
+ window.removeEventListener('resize', handleResize)
+ window.removeEventListener('scroll', updateContainerBounds)
+ }
+ }, [updateContainerBounds])
+
+ // 조회 버튼 클릭 핸들러 - PQFilterSheet에 전달
+ const handleSearch = () => {
+ // Close the panel after search
+ setIsFilterPanelOpen(false)
+ }
+
+ // Get active filter count for UI display (서버 사이드 필터만 계산)
+ const getActiveFilterCount = () => {
+ try {
+ // 새로운 이름 우선, 기존 이름도 지원
+ const basicFilters = searchParams.get('basicFilters') || searchParams.get('pqBasicFilters')
+ return basicFilters ? JSON.parse(basicFilters).length : 0
+ } catch (e) {
+ return 0
+ }
+ }
+
+ // Filter panel width
+ const FILTER_PANEL_WIDTH = 400;
+
+ return (
+ <>
+ {/* Filter Panel - fixed positioning으로 화면 최대 좌측에서 시작 */}
+ <div
+ className={cn(
+ "fixed left-0 bg-background border-r z-50 flex flex-col transition-all duration-300 ease-in-out overflow-hidden",
+ isFilterPanelOpen ? "border-r shadow-lg" : "border-r-0"
+ )}
+ style={{
+ width: isFilterPanelOpen ? `${FILTER_PANEL_WIDTH}px` : '0px',
+ top: `${containerTop}px`,
+ height: `calc(100vh - ${containerTop}px)`
+ }}
+ >
+ {/* Filter Content */}
+ <div className="h-full">
+ <PQFilterSheet
+ isOpen={isFilterPanelOpen}
+ onClose={() => setIsFilterPanelOpen(false)}
+ onSearch={handleSearch}
+ isLoading={false} // 로딩 상태 제거
+ />
+ </div>
+ </div>
+
+ {/* Main Content Container */}
+ <div
+ ref={containerRef}
+ className={cn("relative w-full overflow-hidden", className)}
+ >
+ <div className="flex w-full h-full">
+ {/* Main Content - 너비 조정으로 필터 패널 공간 확보 */}
+ <div
+ className="flex flex-col min-w-0 overflow-hidden transition-all duration-300 ease-in-out"
+ style={{
+ width: isFilterPanelOpen ? `calc(100% - ${FILTER_PANEL_WIDTH}px)` : '100%',
+ marginLeft: isFilterPanelOpen ? `${FILTER_PANEL_WIDTH}px` : '0px'
+ }}
+ >
+ {/* Header Bar */}
+ <div className="flex items-center justify-between p-4 bg-background shrink-0">
+ <div className="flex items-center gap-3">
+ <Button
+ variant="outline"
+ size="sm"
+ type='button'
+ onClick={() => setIsFilterPanelOpen(!isFilterPanelOpen)}
+ className="flex items-center shadow-sm"
+ >
+ {
+ 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>
+ </div>
+
+ {/* Table Content Area */}
+ <div className="flex-1 overflow-hidden" style={{ height: 'calc(100vh - 380px)' }}>
+ <div className="h-full w-full">
+ {/* Promise를 직접 전달 - Items와 동일한 패턴 */}
+ <PQSubmissionsTable promises={promises} />
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </>
+ )
}
\ No newline at end of file |
