11import { TABLE_LENGTH , TABLE_REFETCH_INTERVAL } from '@/config' ;
22import { execute } from '@/graphql/poco/execute' ;
3+ import { App_OrderBy , OrderDirection } from '@/graphql/poco/graphql' ;
34import { useQuery } from '@tanstack/react-query' ;
45import { createFileRoute } from '@tanstack/react-router' ;
5- import { LoaderCircle } from 'lucide-react' ;
6+ import { LoaderCircle , SlidersHorizontal } from 'lucide-react' ;
67import { DataTable } from '@/components/DataTable' ;
78import { PaginatedNavigation } from '@/components/PaginatedNavigation' ;
89import AppIcon from '@/components/icons/AppIcon' ;
910import { BackButton } from '@/components/ui/BackButton' ;
11+ import {
12+ Select ,
13+ SelectContent ,
14+ SelectItem ,
15+ SelectTrigger ,
16+ } from '@/components/ui/select' ;
17+ import { useFilterParam } from '@/hooks/useFilterParam' ;
1018import { usePageParam } from '@/hooks/usePageParam' ;
1119import { ErrorAlert } from '@/modules/ErrorAlert' ;
1220import { AppBreadcrumbsList } from '@/modules/apps/AppBreadcrumbs' ;
1321import { appsQuery } from '@/modules/apps/appsQuery' ;
1422import { columns } from '@/modules/apps/appsTable/columns' ;
1523import { SearcherBar } from '@/modules/search/SearcherBar' ;
1624import useUserStore from '@/stores/useUser.store' ;
17- import { createPlaceholderDataFnForQueryKey } from '@/utils/createPlaceholderDataFnForQueryKey' ;
25+ import { createPlaceholderDataFn } from '@/utils/createPlaceholderDataFnForQueryKey' ;
1826import { getAdditionalPages } from '@/utils/format' ;
1927
2028export const Route = createFileRoute ( '/$chainSlug/_layout/apps' ) ( {
2129 component : AppsRoute ,
2230} ) ;
2331
24- function useAppsData ( currentPage : number ) {
32+ function useAppsData ( currentPage : number , orderFilter : string ) {
2533 const { chainId } = useUserStore ( ) ;
2634 const skip = currentPage * TABLE_LENGTH ;
2735 const nextSkip = skip + TABLE_LENGTH ;
2836 const nextNextSkip = skip + 2 * TABLE_LENGTH ;
2937
30- const queryKey = [ chainId , 'apps' , currentPage ] ;
38+ const orderBy = orderFilter === 'pertinent' ? 'usageCount' : 'timestamp' ;
39+ const orderDirection = orderFilter === 'oldest' ? 'asc' : 'desc' ;
40+ const recentFrom =
41+ orderFilter === 'pertinent'
42+ ? Math . floor ( Date . now ( ) / 1000 ) - 14 * 24 * 60 * 60
43+ : 0 ;
44+
45+ const queryKey = [
46+ chainId ,
47+ 'apps' ,
48+ currentPage ,
49+ orderBy ,
50+ orderDirection ,
51+ recentFrom ,
52+ ] ;
3153 const { data, isLoading, isRefetching, isError, errorUpdateCount } = useQuery (
3254 {
3355 queryKey,
@@ -37,10 +59,13 @@ function useAppsData(currentPage: number) {
3759 skip,
3860 nextSkip,
3961 nextNextSkip,
62+ orderBy : orderBy as App_OrderBy ,
63+ orderDirection : orderDirection as OrderDirection ,
64+ recentFrom : recentFrom ,
4065 } ) ,
4166 refetchInterval : TABLE_REFETCH_INTERVAL ,
4267 enabled : ! ! chainId ,
43- placeholderData : createPlaceholderDataFnForQueryKey ( queryKey ) ,
68+ placeholderData : createPlaceholderDataFn ( ) ,
4469 }
4570 ) ;
4671
@@ -68,20 +93,55 @@ function useAppsData(currentPage: number) {
6893}
6994
7095function AppsRoute ( ) {
96+ const orders = [
97+ { id : 1 , value : 'recent' , name : 'Recently deployed' } ,
98+ { id : 2 , value : 'oldest' , name : 'Oldest deployed' } ,
99+ { id : 3 , value : 'pertinent' , name : 'Most pertinent' } ,
100+ ] ;
101+ const allowedOrderValues = orders . map ( ( o ) => o . value ) ;
71102 const [ currentPage , setCurrentPage ] = usePageParam ( 'appsPage' ) ;
103+ const [ orderBy , setOrderBy ] = useFilterParam (
104+ 'appsOrderBy' ,
105+ allowedOrderValues ,
106+ 'pertinent'
107+ ) ;
72108 const {
73109 data,
74110 isLoading,
75111 isRefetching,
76112 isError,
77113 hasPastError,
78114 additionalPages,
79- } = useAppsData ( currentPage - 1 ) ;
115+ } = useAppsData ( currentPage - 1 , orderBy ) ;
116+
117+ function handleOrderChange ( value : string ) {
118+ setOrderBy ( value ) ;
119+ setCurrentPage ( 1 ) ;
120+ }
80121
81122 return (
82123 < div className = "mt-8 grid gap-6" >
83124 < div className = "mt-6 flex flex-col justify-between lg:flex-row" >
84- < SearcherBar className = "py-6 lg:order-last lg:mr-0 lg:max-w-md lg:py-0 xl:max-w-xl" />
125+ < div className = "flex flex-col items-stretch gap-4 py-6 sm:flex-row lg:order-last lg:mr-0 lg:py-0" >
126+ < SearcherBar className = "lg:max-w-md xl:max-w-xl" />
127+ < Select
128+ value = { orderBy ?. toString ( ) }
129+ onValueChange = { handleOrderChange }
130+ defaultValue = "pertinent"
131+ >
132+ < SelectTrigger className = "m-auto box-content h-9! rounded-2xl" >
133+ < SlidersHorizontal />
134+ Order by
135+ </ SelectTrigger >
136+ < SelectContent >
137+ { orders . map ( ( order ) => (
138+ < SelectItem key = { order . id } value = { order . value } >
139+ { order . name }
140+ </ SelectItem >
141+ ) ) }
142+ </ SelectContent >
143+ </ Select >
144+ </ div >
85145 < div className = "space-y-2" >
86146 < h1 className = "flex items-center gap-2 font-sans text-2xl font-extrabold" >
87147 < AppIcon size = { 24 } />
@@ -116,6 +176,7 @@ function AppsRoute() {
116176 currentPage = { currentPage }
117177 totalPages = { currentPage + additionalPages }
118178 onPageChange = { setCurrentPage }
179+ filterKey = { orderBy }
119180 />
120181 </ div >
121182 ) ;
0 commit comments