this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

update pagination pages

+25 -130
+1 -42
src/components/pagination-nav.tsx
··· 6 6 prevOffset: number | undefined; 7 7 nextOffset: number | undefined; 8 8 to: keyof FileRoutesByPath; 9 - currentOffset?: number; 10 9 } 11 10 12 11 export function PaginationNav(props: PaginationNavProps) { 13 - const { prefetch, prevOffset, nextOffset, to, currentOffset = 0 } = props; 14 - 15 - // Calculate page numbers for display 16 - const currentPage = Math.floor(currentOffset / 20) + 1; 17 - const prevPage = prevOffset !== undefined ? Math.floor(prevOffset / 20) + 1 : null; 18 - const nextPage = nextOffset !== undefined ? Math.floor(nextOffset / 20) + 1 : null; 12 + const { prefetch, prevOffset, nextOffset, to } = props; 19 13 20 14 return ( 21 15 <nav className="flex items-center justify-center gap-1 mt-8 font-mono"> ··· 33 27 <span>&lt;</span> 34 28 <span>prev</span> 35 29 </Link> 36 - 37 - {/* Separator */} 38 - <span className="px-2 text-charcoal-muted">|</span> 39 - 40 - {/* Page number indicators */} 41 - {prevPage && ( 42 - <> 43 - <Link 44 - preload={prefetch} 45 - to={to} 46 - search={{ offset: prevOffset }} 47 - className="page-number text-charcoal-muted hover:text-charcoal" 48 - > 49 - {prevPage} 50 - </Link> 51 - <span className="px-1 text-charcoal-muted">|</span> 52 - </> 53 - )} 54 - 55 - {/* Current page */} 56 - <span className="page-number page-number--active">{currentPage}</span> 57 - 58 - {nextPage && ( 59 - <> 60 - <span className="px-1 text-charcoal-muted">|</span> 61 - <Link 62 - preload={prefetch} 63 - to={to} 64 - search={{ offset: nextOffset }} 65 - className="page-number text-charcoal-muted hover:text-charcoal" 66 - > 67 - {nextPage} 68 - </Link> 69 - </> 70 - )} 71 30 72 31 {/* Separator */} 73 32 <span className="px-2 text-charcoal-muted">|</span>
+5 -18
src/routes/basic.tsx
··· 1 1 import { createFileRoute } from "@tanstack/react-router"; 2 2 import { useSuspenseQuery } from "@tanstack/react-query"; 3 - import { useServerFn } from "@tanstack/react-start"; 4 3 import * as v from "valibot"; 5 4 import { PaginationNav } from "~/components/pagination-nav"; 6 5 import { ··· 11 10 TableHeader, 12 11 TableRow, 13 12 } from "~/components/ui/table"; 14 - import { 15 - POKEMON_LIMIT, 16 - getPokemonListQueryFn, 17 - getPokemonListQueryKey, 18 - } from "~/util/pokemon"; 13 + import { POKEMON_LIMIT, getPokemonListQueryFn, getPokemonListQueryKey } from "~/util/pokemon"; 19 14 20 15 const searchParamsSchema = v.object({ 21 16 offset: v.optional(v.number(), 0), ··· 40 35 <div className="max-w-4xl mx-auto"> 41 36 <div className="section-header"> 42 37 <span className="section-header__title">01_basic</span> 43 - <span className="text-charcoal-muted text-sm"> 44 - // No prefetching (baseline) 45 - </span> 38 + <span className="text-charcoal-muted text-sm">// No prefetching (baseline)</span> 46 39 </div> 47 40 48 41 <div className="console-card mb-6"> 49 42 <h1 className="text-lg font-mono text-charcoal mb-4"> 50 - National Pokédex: Pokémon {currentOffset + 1}- 51 - {currentOffset + POKEMON_LIMIT} 43 + National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 52 44 </h1> 53 45 <Table className="data-table"> 54 46 <TableHeader> ··· 61 53 <TableBody> 62 54 {data.pokemon.map((pokemon) => ( 63 55 <TableRow key={pokemon.name}> 64 - <TableCell className="font-mono text-charcoal-muted"> 65 - {pokemon.id} 66 - </TableCell> 67 - <TableCell className="capitalize text-charcoal"> 68 - {pokemon.name} 69 - </TableCell> 56 + <TableCell className="font-mono text-charcoal-muted">{pokemon.id}</TableCell> 57 + <TableCell className="capitalize text-charcoal">{pokemon.name}</TableCell> 70 58 <TableCell> 71 59 {pokemon.types.map((type) => ( 72 60 <span key={type.name} className="type-badge"> ··· 82 70 prevOffset={data.prevOffset ?? undefined} 83 71 nextOffset={data.nextOffset ?? undefined} 84 72 to="/basic" 85 - currentOffset={currentOffset} 86 73 /> 87 74 </div> 88 75 </div>
+8 -28
src/routes/debounced-preload-filters.tsx
··· 1 1 import { createFileRoute } from "@tanstack/react-router"; 2 2 import { useDebouncedCallback } from "@tanstack/react-pacer"; 3 - import { 4 - queryOptions, 5 - useQueryClient, 6 - useSuspenseQuery, 7 - } from "@tanstack/react-query"; 3 + import { queryOptions, useQueryClient, useSuspenseQuery } from "@tanstack/react-query"; 8 4 import { useCallback } from "react"; 9 5 import { useState } from "react"; 10 6 import * as v from "valibot"; ··· 64 60 children: React.ReactNode; 65 61 }) { 66 62 const queryClient = useQueryClient(); 67 - const { pokemonListOptions: serverPokemonListOptions } = 68 - Route.useRouteContext(); 63 + const { pokemonListOptions: serverPokemonListOptions } = Route.useRouteContext(); 69 64 const [nameFilter, setNameFilter] = useState(props.initialName); 70 65 71 66 const debouncedNameFilter = useDebouncedCallback( ··· 97 92 }, [nameFilter, props]); 98 93 99 94 return ( 100 - <FilterSubmitContext.Provider 101 - value={{ handleSubmit, nameFilter, updateNameFilter }} 102 - > 95 + <FilterSubmitContext.Provider value={{ handleSubmit, nameFilter, updateNameFilter }}> 103 96 {props.children} 104 97 </FilterSubmitContext.Provider> 105 98 ); ··· 120 113 <div className="max-w-4xl mx-auto"> 121 114 <div className="section-header"> 122 115 <span className="section-header__title">06_debounced</span> 123 - <span className="text-charcoal-muted text-sm"> 124 - // Advanced filter prefetch 125 - </span> 116 + <span className="text-charcoal-muted text-sm">// Advanced filter prefetch</span> 126 117 </div> 127 118 128 119 {/* Filter UI */} ··· 147 138 148 139 <div className="console-card"> 149 140 <h1 className="text-lg font-mono text-charcoal mb-4"> 150 - National Pokédex: Pokémon {currentOffset + 1}- 151 - {currentOffset + POKEMON_LIMIT} 152 - {nameFilter && ( 153 - <span className="text-charcoal-muted"> 154 - {" "} 155 - (filtered: "{nameFilter}") 156 - </span> 157 - )} 141 + National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 142 + {nameFilter && <span className="text-charcoal-muted"> (filtered: "{nameFilter}")</span>} 158 143 </h1> 159 144 160 145 <Table className="data-table"> ··· 168 153 <TableBody> 169 154 {filteredPokemon.map((pokemon) => ( 170 155 <TableRow key={pokemon.name}> 171 - <TableCell className="font-mono text-charcoal-muted"> 172 - {pokemon.id} 173 - </TableCell> 174 - <TableCell className="capitalize text-charcoal"> 175 - {pokemon.name} 176 - </TableCell> 156 + <TableCell className="font-mono text-charcoal-muted">{pokemon.id}</TableCell> 157 + <TableCell className="capitalize text-charcoal">{pokemon.name}</TableCell> 177 158 <TableCell> 178 159 {pokemon.types.map((type) => ( 179 160 <span key={type.name} className="type-badge"> ··· 197 178 prevOffset={data.prevOffset ?? undefined} 198 179 nextOffset={data.nextOffset ?? undefined} 199 180 to="/debounced-preload-filters" 200 - currentOffset={currentOffset} 201 181 /> 202 182 </div> 203 183 </div>
+6 -23
src/routes/filters.tsx
··· 51 51 name: search.name, 52 52 }), 53 53 context: ({ deps }) => { 54 - const newKey = getFilteredPokemonListQueryKey( 55 - "filters", 56 - deps.offset, 57 - deps.name, 58 - ); 54 + const newKey = getFilteredPokemonListQueryKey("filters", deps.offset, deps.name); 59 55 60 56 const pokemonListOptions = queryOptions({ 61 57 queryKey: newKey, ··· 87 83 <div className="max-w-4xl mx-auto"> 88 84 <div className="section-header"> 89 85 <span className="section-header__title">05_filters</span> 90 - <span className="text-charcoal-muted text-sm"> 91 - // Search with prefetch 92 - </span> 86 + <span className="text-charcoal-muted text-sm">// Search with prefetch</span> 93 87 </div> 94 88 95 89 {/* Filter UI */} ··· 112 106 113 107 <div className="console-card"> 114 108 <h1 className="text-lg font-mono text-charcoal mb-4"> 115 - National Pokédex: Pokémon {currentOffset + 1}- 116 - {currentOffset + POKEMON_LIMIT} 117 - {nameFilter && ( 118 - <span className="text-charcoal-muted"> 119 - {" "} 120 - (filtered: "{nameFilter}") 121 - </span> 122 - )} 109 + National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 110 + {nameFilter && <span className="text-charcoal-muted"> (filtered: "{nameFilter}")</span>} 123 111 </h1> 124 112 125 113 <Table className="data-table"> ··· 133 121 <TableBody> 134 122 {filteredPokemon.map((pokemon) => ( 135 123 <TableRow key={pokemon.name}> 136 - <TableCell className="font-mono text-charcoal-muted"> 137 - {pokemon.id} 138 - </TableCell> 139 - <TableCell className="capitalize text-charcoal"> 140 - {pokemon.name} 141 - </TableCell> 124 + <TableCell className="font-mono text-charcoal-muted">{pokemon.id}</TableCell> 125 + <TableCell className="capitalize text-charcoal">{pokemon.name}</TableCell> 142 126 <TableCell> 143 127 {pokemon.types.map((type) => ( 144 128 <span key={type.name} className="type-badge"> ··· 162 146 prevOffset={data.prevOffset ?? undefined} 163 147 nextOffset={data.nextOffset ?? undefined} 164 148 to="/filters" 165 - currentOffset={currentOffset} 166 149 /> 167 150 </div> 168 151 </div>
-1
src/routes/intent-preloading.tsx
··· 87 87 prevOffset={data.prevOffset ?? undefined} 88 88 nextOffset={data.nextOffset ?? undefined} 89 89 to="/intent-preloading" 90 - currentOffset={currentOffset} 91 90 /> 92 91 </div> 93 92 </div>
+5 -17
src/routes/pagination.tsx
··· 10 10 TableHeader, 11 11 TableRow, 12 12 } from "~/components/ui/table"; 13 - import { 14 - POKEMON_LIMIT, 15 - getPokemonListQueryKey, 16 - getPokemonListQueryFn, 17 - } from "~/util/pokemon"; 13 + import { POKEMON_LIMIT, getPokemonListQueryKey, getPokemonListQueryFn } from "~/util/pokemon"; 18 14 19 15 const searchParamsSchema = v.object({ 20 16 offset: v.optional(v.number(), 0), ··· 55 51 <div className="max-w-4xl mx-auto"> 56 52 <div className="section-header"> 57 53 <span className="section-header__title">04_pagination</span> 58 - <span className="text-charcoal-muted text-sm"> 59 - // Preloading next/prev pages 60 - </span> 54 + <span className="text-charcoal-muted text-sm">// Preloading next/prev pages</span> 61 55 </div> 62 56 63 57 <div className="console-card mb-6"> 64 58 <h1 className="text-lg font-mono text-charcoal mb-4"> 65 - National Pokédex: Pokémon {currentOffset + 1}- 66 - {currentOffset + POKEMON_LIMIT} 59 + National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 67 60 </h1> 68 61 <Table className="data-table"> 69 62 <TableHeader> ··· 76 69 <TableBody> 77 70 {data.pokemon.map((pokemon) => ( 78 71 <TableRow key={pokemon.name}> 79 - <TableCell className="font-mono text-charcoal-muted"> 80 - {pokemon.id} 81 - </TableCell> 82 - <TableCell className="capitalize text-charcoal"> 83 - {pokemon.name} 84 - </TableCell> 72 + <TableCell className="font-mono text-charcoal-muted">{pokemon.id}</TableCell> 73 + <TableCell className="capitalize text-charcoal">{pokemon.name}</TableCell> 85 74 <TableCell> 86 75 {pokemon.types.map((type) => ( 87 76 <span key={type.name} className="type-badge"> ··· 98 87 prevOffset={data.prevOffset ?? undefined} 99 88 nextOffset={data.nextOffset ?? undefined} 100 89 to="/pagination" 101 - currentOffset={currentOffset} 102 90 /> 103 91 </div> 104 92 </div>
-1
src/routes/preloading.tsx
··· 89 89 prevOffset={data.prevOffset ?? undefined} 90 90 nextOffset={data.nextOffset ?? undefined} 91 91 to="/preloading" 92 - currentOffset={currentOffset} 93 92 /> 94 93 </div> 95 94 </div>