diff options
Diffstat (limited to 'app')
| -rw-r--r-- | app/[lng]/evcp/(evcp)/vendor-pool/page.tsx | 123 |
1 files changed, 106 insertions, 17 deletions
diff --git a/app/[lng]/evcp/(evcp)/vendor-pool/page.tsx b/app/[lng]/evcp/(evcp)/vendor-pool/page.tsx index 6708e674..7426e069 100644 --- a/app/[lng]/evcp/(evcp)/vendor-pool/page.tsx +++ b/app/[lng]/evcp/(evcp)/vendor-pool/page.tsx @@ -1,3 +1,5 @@ +"use client" + import * as React from "react" import { type SearchParams } from "@/types/table" @@ -9,24 +11,13 @@ import { getVendorPools } from "@/lib/vendor-pool/service" import { vendorPoolSearchParamsCache } from "@/lib/vendor-pool/validations" import { VendorPoolTable } from "@/lib/vendor-pool/table/vendor-pool-table" import { InformationButton } from "@/components/information/information-button" +import { useSearchParams } from "next/navigation" interface VendorPoolPageProps { searchParams: Promise<SearchParams> } -export default async function VendorPoolPage(props: VendorPoolPageProps) { - const searchParams = await props.searchParams - const search = vendorPoolSearchParamsCache.parse(searchParams) - - const validFilters = getValidFilters(search.filters) - - const promises = Promise.all([ - getVendorPools({ - ...search, - filters: validFilters, - }), - ]) - +export default function VendorPoolPage({ searchParams }: VendorPoolPageProps) { return ( <Shell className="gap-2"> <div className="flex items-center justify-between space-y-2"> @@ -60,20 +51,118 @@ export default async function VendorPoolPage(props: VendorPoolPageProps) { /> } > - <VendorPoolTableWrapper promises={promises} /> + <VendorPoolTableWrapperClient searchParamsPromise={searchParams} /> </React.Suspense> </Shell> ) } -// 실제 데이터를 받아서 VendorPoolTable에 전달하는 컴포넌트 -function VendorPoolTableWrapper({ promises }: { promises: Promise<any> }) { - const [{ data, pageCount }] = React.use(promises) +// 클라이언트 컴포넌트: 필터 변경을 감시하여 데이터 재조회 +function VendorPoolTableWrapperClient({ searchParamsPromise }: { searchParamsPromise: Promise<SearchParams> }) { + const searchParams = useSearchParams() + const [initialData, setInitialData] = React.useState<{ data: any[], pageCount: number } | null>(null) + const [data, setData] = React.useState<any[]>([]) + const [pageCount, setPageCount] = React.useState(0) + const [isLoading, setIsLoading] = React.useState(false) + + // 초기 데이터 로딩 + React.useEffect(() => { + const loadInitialData = async () => { + try { + const searchParamsData = await searchParamsPromise + const search = vendorPoolSearchParamsCache.parse(searchParamsData) + const validFilters = getValidFilters(search.filters) + + const result = await getVendorPools({ + ...search, + filters: validFilters, + }) + + setInitialData(result) + setData(result.data) + setPageCount(result.pageCount) + } catch (error) { + console.error('Failed to load initial data:', error) + } + } + loadInitialData() + }, [searchParamsPromise]) + + // 필터 상태 변경 감시 및 데이터 재조회 + React.useEffect(() => { + if (!initialData) return // 초기 데이터가 로드되기 전까지는 실행하지 않음 + + const refreshData = async () => { + setIsLoading(true) + try { + const currentParams = Object.fromEntries(searchParams.entries()) + const search = vendorPoolSearchParamsCache.parse(currentParams) + const validFilters = getValidFilters(search.filters) + + const result = await getVendorPools({ + ...search, + filters: validFilters, + }) + + setData(result.data) + setPageCount(result.pageCount) + } catch (error) { + console.error('Failed to refresh vendor pool data:', error) + } finally { + setIsLoading(false) + } + } + + // 필터 파라미터가 변경될 때마다 데이터 재조회 + const currentFilters = searchParams.get('filters') + const currentJoinOperator = searchParams.get('joinOperator') + const currentSearch = searchParams.get('search') + const currentPage = searchParams.get('page') + const currentPerPage = searchParams.get('perPage') + const currentSort = searchParams.get('sort') + + // 필터 관련 파라미터가 변경되면 재조회 + if (currentFilters !== '[]' || currentJoinOperator || currentSearch || currentPage || currentPerPage || currentSort) { + refreshData() + } else { + // 필터가 초기 상태면 초기 데이터로 복원 + setData(initialData.data) + setPageCount(initialData.pageCount) + } + }, [searchParams, initialData]) + + const handleRefresh = React.useCallback(async () => { + if (!initialData) return + + setIsLoading(true) + try { + const currentParams = Object.fromEntries(searchParams.entries()) + const search = vendorPoolSearchParamsCache.parse(currentParams) + const validFilters = getValidFilters(search.filters) + + const result = await getVendorPools({ + ...search, + filters: validFilters, + }) + + setData(result.data) + setPageCount(result.pageCount) + } catch (error) { + console.error('Failed to refresh vendor pool data:', error) + } finally { + setIsLoading(false) + } + }, [searchParams, initialData]) + + if (!initialData) { + return null // 초기 데이터 로딩 중 + } return ( <VendorPoolTable data={data} pageCount={pageCount} + onRefresh={handleRefresh} /> ) } |
