this repo has no description
0
fork

Configure Feed

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

pokedex update

+276 -269
+98
src/components/tables/pokedex-table-section.tsx
··· 1 + import { Suspense, type ComponentProps, type ReactNode } from "react"; 2 + import { POKEMON_LIMIT } from "~/constants"; 3 + import { lazily } from "~/lib/lazily"; 4 + import { PaginationNav } from "~/components/pagination-nav"; 5 + import { PokemonTableSkeleton } from "./pokemon-table-skeleton"; 6 + 7 + const { PokemonTable } = lazily(() => import("./pokemon-table")); 8 + 9 + interface Pokemon { 10 + id: number; 11 + name: string; 12 + types: Array<{ name: string }>; 13 + } 14 + 15 + interface PokedexTableSectionProps { 16 + children: ReactNode; 17 + currentOffset: number; 18 + fallbackPagination: ReactNode; 19 + nameFilter?: string; 20 + } 21 + 22 + export function PokedexTableSection(props: PokedexTableSectionProps) { 23 + const { children, currentOffset, fallbackPagination, nameFilter } = props; 24 + 25 + return ( 26 + <> 27 + <h1 className="text-lg font-mono text-(--text-primary) mb-4"> 28 + National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 29 + {nameFilter && ( 30 + <span className="text-(--text-muted)"> (filtered: &quot;{nameFilter}&quot;)</span> 31 + )} 32 + </h1> 33 + <Suspense 34 + fallback={ 35 + <> 36 + <PokedexTableShell> 37 + <PokemonTableSkeleton rowCount={POKEMON_LIMIT} /> 38 + </PokedexTableShell> 39 + {fallbackPagination} 40 + </> 41 + } 42 + > 43 + {children} 44 + </Suspense> 45 + </> 46 + ); 47 + } 48 + 49 + interface PokedexTableResultsProps { 50 + nameFilter?: string; 51 + pagination: ReactNode; 52 + pokemon: Pokemon[]; 53 + } 54 + 55 + export function PokedexTableResults(props: PokedexTableResultsProps) { 56 + const { nameFilter, pagination, pokemon } = props; 57 + 58 + return ( 59 + <> 60 + <PokedexTableShell> 61 + <PokemonTable pokemon={pokemon} /> 62 + 63 + {pokemon.length === 0 && nameFilter && ( 64 + <div className="text-center py-4 text-(--text-muted) font-mono text-sm"> 65 + No Pokémon found matching &quot;{nameFilter}&quot; 66 + </div> 67 + )} 68 + </PokedexTableShell> 69 + {pagination} 70 + </> 71 + ); 72 + } 73 + 74 + interface PokedexPaginationProps { 75 + nameFilter?: string; 76 + nextOffset: number | null; 77 + prefetch?: "intent" | "viewport" | "render" | false; 78 + prevOffset: number | null; 79 + to: ComponentProps<typeof PaginationNav>["to"]; 80 + } 81 + 82 + export function PokedexPagination(props: PokedexPaginationProps) { 83 + const { nameFilter, nextOffset, prefetch, prevOffset, to } = props; 84 + 85 + return ( 86 + <PaginationNav 87 + prefetch={prefetch} 88 + search={nameFilter == null ? undefined : { name: nameFilter }} 89 + prevOffset={prevOffset} 90 + nextOffset={nextOffset} 91 + to={to} 92 + /> 93 + ); 94 + } 95 + 96 + function PokedexTableShell({ children }: { children: ReactNode }) { 97 + return <div className="min-h-125">{children}</div>; 98 + }
+16 -29
src/routes/basic.tsx
··· 1 - import { Suspense } from "react"; 2 1 import { createFileRoute } from "@tanstack/react-router"; 3 2 import { useSuspenseQuery } from "@tanstack/react-query"; 4 3 import * as v from "valibot"; 5 - import { PaginationNav } from "~/components/pagination-nav"; 6 4 import { StrategyPageLayout } from "~/components/strategy-page-layout"; 7 5 import { ConsoleCard } from "~/components/console/console-card"; 8 6 import { SectionHeader } from "~/components/console/section-header"; 9 - import { PokemonTableSkeleton } from "~/components/tables/pokemon-table-skeleton"; 10 - import { POKEMON_LIMIT } from "~/constants"; 7 + import { 8 + PokedexPagination, 9 + PokedexTableResults, 10 + PokedexTableSection, 11 + } from "~/components/tables/pokedex-table-section"; 11 12 import { getPokemonListQueryFn, getPokemonListQueryKey } from "~/utils/pokemon"; 12 - import { lazily } from "~/lib/lazily"; 13 13 import { getStrategyArticle } from "~/server/strategy-article.functions"; 14 - 15 - const { PokemonTable } = lazily(() => import("~/components/tables/pokemon-table")); 16 14 17 15 const searchParamsSchema = v.object({ 18 16 offset: v.optional(v.number(), 0), ··· 40 38 41 39 <StrategyPageLayout sidebar={Article}> 42 40 <ConsoleCard className="mb-6"> 43 - <h1 className="text-lg font-mono text-(--text-primary) mb-4"> 44 - National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 45 - </h1> 46 - <Suspense 47 - fallback={ 48 - <> 49 - <PokemonTableShell> 50 - <PokemonTableSkeleton rowCount={POKEMON_LIMIT} /> 51 - </PokemonTableShell> 52 - <PaginationNav prevOffset={null} nextOffset={null} to="/basic" /> 53 - </> 41 + <PokedexTableSection 42 + currentOffset={currentOffset} 43 + fallbackPagination={ 44 + <PokedexPagination prevOffset={null} nextOffset={null} to="/basic" /> 54 45 } 55 46 > 56 47 <PokemonTableContent currentOffset={currentOffset} /> 57 - </Suspense> 48 + </PokedexTableSection> 58 49 </ConsoleCard> 59 50 </StrategyPageLayout> 60 51 </div> ··· 62 53 ); 63 54 } 64 55 65 - function PokemonTableShell({ children }: { children: React.ReactNode }) { 66 - return <div className="min-h-125">{children}</div>; 67 - } 68 - 69 56 function PokemonTableContent({ currentOffset }: { currentOffset: number }) { 70 57 const queryKey = getPokemonListQueryKey("suspense", currentOffset); 71 58 const { data } = useSuspenseQuery({ ··· 74 61 }); 75 62 76 63 return ( 77 - <> 78 - <PokemonTableShell> 79 - <PokemonTable pokemon={data.pokemon} /> 80 - </PokemonTableShell> 81 - <PaginationNav prevOffset={data.prevOffset} nextOffset={data.nextOffset} to="/basic" /> 82 - </> 64 + <PokedexTableResults 65 + pokemon={data.pokemon} 66 + pagination={ 67 + <PokedexPagination prevOffset={data.prevOffset} nextOffset={data.nextOffset} to="/basic" /> 68 + } 69 + /> 83 70 ); 84 71 }
+29 -45
src/routes/debounced-preload-filters.tsx
··· 1 - import { Suspense, useCallback, useState } from "react"; 1 + import { useCallback, useState, type ReactNode } from "react"; 2 2 import { createFileRoute, useRouteContext } from "@tanstack/react-router"; 3 3 import { useDebouncedCallback } from "@tanstack/react-pacer"; 4 4 import { queryOptions, useQueryClient, useSuspenseQuery } from "@tanstack/react-query"; 5 5 import * as v from "valibot"; 6 6 import { FilterForm, FilterSubmitContext } from "~/components/filter-form"; 7 - import { PaginationNav } from "~/components/pagination-nav"; 8 7 import { StrategyPageLayout } from "~/components/strategy-page-layout"; 9 8 import { ConsoleCard } from "~/components/console/console-card"; 10 9 import { SectionHeader } from "~/components/console/section-header"; 11 - import { PokemonTableSkeleton } from "~/components/tables/pokemon-table-skeleton"; 12 - import { POKEMON_LIMIT } from "~/constants"; 10 + import { 11 + PokedexPagination, 12 + PokedexTableResults, 13 + PokedexTableSection, 14 + } from "~/components/tables/pokedex-table-section"; 13 15 import { getFilteredPokemonListQueryKey, getFilteredPokemonListQueryFn } from "~/utils/pokemon"; 14 - import { lazily } from "~/lib/lazily"; 15 16 import { getStrategyArticle } from "~/server/strategy-article.functions"; 16 - 17 - const { PokemonTable } = lazily(() => import("~/components/tables/pokemon-table")); 18 17 19 18 const searchParamsSchema = v.object({ 20 19 offset: v.optional(v.number(), 0), ··· 56 55 function PreloadFilterSubmitContextProvider(props: { 57 56 initialName: string; 58 57 handleSubmit: (nameFilter: string) => void; 59 - children: React.ReactNode; 58 + children: ReactNode; 60 59 }) { 61 60 const queryClient = useQueryClient(); 62 61 const { pokemonListOptions: serverPokemonListOptions } = Route.useRouteContext(); ··· 129 128 </ConsoleCard> 130 129 131 130 <ConsoleCard> 132 - <h1 className="text-lg font-mono text-(--text-primary) mb-4"> 133 - National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 134 - {nameFilter && ( 135 - <span className="text-(--text-muted)"> (filtered: &quot;{nameFilter}&quot;)</span> 136 - )} 137 - </h1> 138 - 139 - <Suspense 140 - fallback={ 141 - <> 142 - <div className="min-h-125"> 143 - <PokemonTableSkeleton rowCount={POKEMON_LIMIT} /> 144 - </div> 145 - <PaginationNav 146 - prevOffset={null} 147 - nextOffset={null} 148 - to="/debounced-preload-filters" 149 - /> 150 - </> 131 + <PokedexTableSection 132 + currentOffset={currentOffset} 133 + nameFilter={nameFilter} 134 + fallbackPagination={ 135 + <PokedexPagination 136 + prevOffset={null} 137 + nextOffset={null} 138 + to="/debounced-preload-filters" 139 + /> 151 140 } 152 141 > 153 142 <PokemonTableContent nameFilter={nameFilter} /> 154 - </Suspense> 143 + </PokedexTableSection> 155 144 </ConsoleCard> 156 145 </StrategyPageLayout> 157 146 </div> ··· 165 154 const filteredPokemon = data.pokemon; 166 155 167 156 return ( 168 - <> 169 - <div className="min-h-125"> 170 - <PokemonTable pokemon={filteredPokemon} /> 171 - 172 - {filteredPokemon.length === 0 && nameFilter && ( 173 - <div className="text-center py-4 text-(--text-muted) font-mono text-sm"> 174 - No Pokémon found matching &quot;{nameFilter}&quot; 175 - </div> 176 - )} 177 - </div> 178 - <PaginationNav 179 - prefetch="viewport" 180 - prevOffset={data.prevOffset} 181 - nextOffset={data.nextOffset} 182 - to="/debounced-preload-filters" 183 - /> 184 - </> 157 + <PokedexTableResults 158 + nameFilter={nameFilter} 159 + pokemon={filteredPokemon} 160 + pagination={ 161 + <PokedexPagination 162 + prefetch="viewport" 163 + prevOffset={data.prevOffset} 164 + nextOffset={data.nextOffset} 165 + to="/debounced-preload-filters" 166 + /> 167 + } 168 + /> 185 169 ); 186 170 }
+25 -41
src/routes/filters.tsx
··· 1 - import { Suspense, useCallback, useState } from "react"; 1 + import { useCallback, useState, type ReactNode } from "react"; 2 2 import { createFileRoute, useRouteContext } from "@tanstack/react-router"; 3 3 import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; 4 4 import * as v from "valibot"; 5 5 import { FilterForm, FilterSubmitContext } from "~/components/filter-form"; 6 - import { PaginationNav } from "~/components/pagination-nav"; 7 6 import { StrategyPageLayout } from "~/components/strategy-page-layout"; 8 7 import { ConsoleCard } from "~/components/console/console-card"; 9 8 import { SectionHeader } from "~/components/console/section-header"; 10 - import { PokemonTableSkeleton } from "~/components/tables/pokemon-table-skeleton"; 11 - import { POKEMON_LIMIT } from "~/constants"; 9 + import { 10 + PokedexPagination, 11 + PokedexTableResults, 12 + PokedexTableSection, 13 + } from "~/components/tables/pokedex-table-section"; 12 14 import { getFilteredPokemonListQueryKey, getFilteredPokemonListQueryFn } from "~/utils/pokemon"; 13 - import { lazily } from "~/lib/lazily"; 14 15 import { getStrategyArticle } from "~/server/strategy-article.functions"; 15 - 16 - const { PokemonTable } = lazily(() => import("~/components/tables/pokemon-table")); 17 16 18 17 const searchParamsSchema = v.object({ 19 18 offset: v.optional(v.number(), 0), ··· 23 22 function FilterSubmitContextProvider(props: { 24 23 initialName: string; 25 24 handleSubmit: (nameFilter: string) => void; 26 - children: React.ReactNode; 25 + children: ReactNode; 27 26 }) { 28 27 const [nameFilter, setNameFilter] = useState(props.initialName); 29 28 ··· 98 97 </ConsoleCard> 99 98 100 99 <ConsoleCard> 101 - <h1 className="text-lg font-mono text-(--text-primary) mb-4"> 102 - National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 103 - {nameFilter && ( 104 - <span className="text-(--text-muted)"> (filtered: &quot;{nameFilter}&quot;)</span> 105 - )} 106 - </h1> 107 - 108 - <Suspense 109 - fallback={ 110 - <> 111 - <div className="min-h-125"> 112 - <PokemonTableSkeleton rowCount={POKEMON_LIMIT} /> 113 - </div> 114 - <PaginationNav prevOffset={null} nextOffset={null} to="/filters" /> 115 - </> 100 + <PokedexTableSection 101 + currentOffset={currentOffset} 102 + nameFilter={nameFilter} 103 + fallbackPagination={ 104 + <PokedexPagination prevOffset={null} nextOffset={null} to="/filters" /> 116 105 } 117 106 > 118 107 <PokemonTableContent nameFilter={nameFilter} /> 119 - </Suspense> 108 + </PokedexTableSection> 120 109 </ConsoleCard> 121 110 </StrategyPageLayout> 122 111 </div> ··· 130 119 const filteredPokemon = data.pokemon; 131 120 132 121 return ( 133 - <> 134 - <div className="min-h-125"> 135 - <PokemonTable pokemon={filteredPokemon} /> 136 - 137 - {filteredPokemon.length === 0 && nameFilter && ( 138 - <div className="text-center py-4 text-(--text-muted) font-mono text-sm"> 139 - No Pokémon found matching &quot;{nameFilter}&quot; 140 - </div> 141 - )} 142 - </div> 143 - <PaginationNav 144 - prefetch="viewport" 145 - prevOffset={data.prevOffset} 146 - nextOffset={data.nextOffset} 147 - to="/filters" 148 - /> 149 - </> 122 + <PokedexTableResults 123 + nameFilter={nameFilter} 124 + pokemon={filteredPokemon} 125 + pagination={ 126 + <PokedexPagination 127 + prefetch="viewport" 128 + prevOffset={data.prevOffset} 129 + nextOffset={data.nextOffset} 130 + to="/filters" 131 + /> 132 + } 133 + /> 150 134 ); 151 135 }
+21 -30
src/routes/intent-preloading.tsx
··· 1 - import { Suspense } from "react"; 2 1 import { createFileRoute, useRouteContext } from "@tanstack/react-router"; 3 2 import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; 4 3 import * as v from "valibot"; 5 - import { PaginationNav } from "~/components/pagination-nav"; 6 4 import { StrategyPageLayout } from "~/components/strategy-page-layout"; 7 5 import { ConsoleCard } from "~/components/console/console-card"; 8 6 import { SectionHeader } from "~/components/console/section-header"; 9 - import { PokemonTableSkeleton } from "~/components/tables/pokemon-table-skeleton"; 10 - import { POKEMON_LIMIT } from "~/constants"; 7 + import { 8 + PokedexPagination, 9 + PokedexTableResults, 10 + PokedexTableSection, 11 + } from "~/components/tables/pokedex-table-section"; 11 12 import { getPokemonListQueryKey, getPokemonListQueryFn } from "~/utils/pokemon"; 12 - import { lazily } from "~/lib/lazily"; 13 13 import { getStrategyArticle } from "~/server/strategy-article.functions"; 14 - 15 - const { PokemonTable } = lazily(() => import("~/components/tables/pokemon-table")); 16 14 17 15 const searchParamsSchema = v.object({ 18 16 offset: v.optional(v.number(), 0), ··· 56 54 57 55 <StrategyPageLayout sidebar={Article}> 58 56 <ConsoleCard className="mb-6"> 59 - <h1 className="text-lg font-mono text-(--text-primary) mb-4"> 60 - National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 61 - </h1> 62 - <Suspense 63 - fallback={ 64 - <> 65 - <div className="min-h-125"> 66 - <PokemonTableSkeleton rowCount={POKEMON_LIMIT} /> 67 - </div> 68 - <PaginationNav prevOffset={null} nextOffset={null} to="/intent-preloading" /> 69 - </> 57 + <PokedexTableSection 58 + currentOffset={currentOffset} 59 + fallbackPagination={ 60 + <PokedexPagination prevOffset={null} nextOffset={null} to="/intent-preloading" /> 70 61 } 71 62 > 72 63 <PokemonTableContent /> 73 - </Suspense> 64 + </PokedexTableSection> 74 65 </ConsoleCard> 75 66 </StrategyPageLayout> 76 67 </div> ··· 83 74 const { data } = useSuspenseQuery(pokemonListOptions); 84 75 85 76 return ( 86 - <> 87 - <div className="min-h-125"> 88 - <PokemonTable pokemon={data.pokemon} /> 89 - </div> 90 - <PaginationNav 91 - prefetch="intent" 92 - prevOffset={data.prevOffset} 93 - nextOffset={data.nextOffset} 94 - to="/intent-preloading" 95 - /> 96 - </> 77 + <PokedexTableResults 78 + pokemon={data.pokemon} 79 + pagination={ 80 + <PokedexPagination 81 + prefetch="intent" 82 + prevOffset={data.prevOffset} 83 + nextOffset={data.nextOffset} 84 + to="/intent-preloading" 85 + /> 86 + } 87 + /> 97 88 ); 98 89 }
+30 -45
src/routes/live-query-filters.tsx
··· 1 - import { Suspense, useCallback, useState } from "react"; 1 + import { useCallback, useState, type ReactNode } from "react"; 2 2 import { createFileRoute } from "@tanstack/react-router"; 3 3 import { useLiveSuspenseQuery, eq, ilike, toArray } from "@tanstack/react-db"; 4 4 import * as v from "valibot"; 5 - import { PaginationNav } from "~/components/pagination-nav"; 6 5 import { StrategyPageLayout } from "~/components/strategy-page-layout"; 7 6 import { ConsoleCard } from "~/components/console/console-card"; 8 - import { PokemonTableSkeleton } from "~/components/tables/pokemon-table-skeleton"; 9 7 import { SectionHeader } from "~/components/console/section-header"; 10 8 import { FilterForm, FilterSubmitContext } from "~/components/filter-form"; 11 9 import { 10 + PokedexPagination, 11 + PokedexTableResults, 12 + PokedexTableSection, 13 + } from "~/components/tables/pokedex-table-section"; 14 + import { 12 15 pokemonCollection, 13 16 pokemonTypesCollection, 14 17 typesCollection, 15 18 } from "~/data/local/collections"; 16 19 import { POKEMON_LIMIT } from "~/constants"; 17 - import { lazily } from "~/lib/lazily"; 18 20 import { getStrategyArticle } from "~/server/strategy-article.functions"; 19 21 20 - const { PokemonTable } = lazily(() => import("~/components/tables/pokemon-table")); 21 - 22 22 const searchParamsSchema = v.object({ 23 23 offset: v.optional(v.number(), 0), 24 24 name: v.optional(v.string(), ""), ··· 27 27 function FilterSubmitContextProvider(props: { 28 28 initialName: string; 29 29 handleSubmit: (nameFilter: string) => void; 30 - children: React.ReactNode; 30 + children: ReactNode; 31 31 }) { 32 32 const [nameFilter, setNameFilter] = useState(props.initialName); 33 33 ··· 86 86 </ConsoleCard> 87 87 88 88 <ConsoleCard> 89 - <h1 className="text-lg font-mono text-(--text-primary) mb-4"> 90 - National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 91 - {nameFilter && ( 92 - <span className="text-(--text-muted)"> (filtered: &quot;{nameFilter}&quot;)</span> 93 - )} 94 - </h1> 95 - 96 - <Suspense 97 - fallback={ 98 - <> 99 - <div className="min-h-125"> 100 - <PokemonTableSkeleton rowCount={POKEMON_LIMIT} /> 101 - </div> 102 - <PaginationNav 103 - search={{ name: nameFilter }} 104 - nextOffset={null} 105 - prevOffset={null} 106 - to="/live-query-filters" 107 - /> 108 - </> 89 + <PokedexTableSection 90 + currentOffset={currentOffset} 91 + nameFilter={nameFilter} 92 + fallbackPagination={ 93 + <PokedexPagination 94 + nameFilter={nameFilter} 95 + nextOffset={null} 96 + prevOffset={null} 97 + to="/live-query-filters" 98 + /> 109 99 } 110 100 > 111 101 <PokemonTableContent currentOffset={currentOffset} nameFilter={nameFilter} /> 112 - </Suspense> 102 + </PokedexTableSection> 113 103 </ConsoleCard> 114 104 </div> 115 105 </StrategyPageLayout> ··· 168 158 const nextOffset = hasMore ? currentOffset + POKEMON_LIMIT : null; 169 159 170 160 return ( 171 - <> 172 - <div className="min-h-125"> 173 - <PokemonTable pokemon={pokemon} /> 174 - 175 - {pokemon.length === 0 && nameFilter && ( 176 - <div className="text-center py-4 text-(--text-muted) font-mono text-sm"> 177 - No Pokémon found matching &quot;{nameFilter}&quot; 178 - </div> 179 - )} 180 - </div> 181 - <PaginationNav 182 - search={{ name: nameFilter }} 183 - prevOffset={prevOffset} 184 - nextOffset={nextOffset} 185 - to="/live-query-filters" 186 - /> 187 - </> 161 + <PokedexTableResults 162 + nameFilter={nameFilter} 163 + pokemon={pokemon} 164 + pagination={ 165 + <PokedexPagination 166 + nameFilter={nameFilter} 167 + prevOffset={prevOffset} 168 + nextOffset={nextOffset} 169 + to="/live-query-filters" 170 + /> 171 + } 172 + /> 188 173 ); 189 174 }
+16 -24
src/routes/live-query.tsx
··· 1 - import { Suspense } from "react"; 2 1 import { createFileRoute } from "@tanstack/react-router"; 3 2 import { useLiveSuspenseQuery, eq, toArray } from "@tanstack/react-db"; 4 3 import * as v from "valibot"; 5 - import { PaginationNav } from "~/components/pagination-nav"; 6 4 import { StrategyPageLayout } from "~/components/strategy-page-layout"; 7 5 import { ConsoleCard } from "~/components/console/console-card"; 8 6 import { SectionHeader } from "~/components/console/section-header"; 9 - import { PokemonTableSkeleton } from "~/components/tables/pokemon-table-skeleton"; 7 + import { 8 + PokedexPagination, 9 + PokedexTableResults, 10 + PokedexTableSection, 11 + } from "~/components/tables/pokedex-table-section"; 10 12 import { POKEMON_LIMIT } from "~/constants"; 11 - import { lazily } from "~/lib/lazily"; 12 13 import { getStrategyArticle } from "~/server/strategy-article.functions"; 13 14 import { 14 15 pokemonCollection, 15 16 typesCollection, 16 17 pokemonTypesCollection, 17 18 } from "~/data/local/collections"; 18 - 19 - const { PokemonTable } = lazily(() => import("~/components/tables/pokemon-table")); 20 19 21 20 const searchParamsSchema = v.object({ 22 21 offset: v.optional(v.number(), 0), ··· 45 44 46 45 <StrategyPageLayout sidebar={Article}> 47 46 <ConsoleCard className="mb-6"> 48 - <h1 className="text-lg font-mono text-(--text-primary) mb-4"> 49 - National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 50 - </h1> 51 - <Suspense 52 - fallback={ 53 - <> 54 - <div className="min-h-125"> 55 - <PokemonTableSkeleton rowCount={POKEMON_LIMIT} /> 56 - </div> 57 - <PaginationNav prevOffset={null} nextOffset={null} to="/live-query" /> 58 - </> 47 + <PokedexTableSection 48 + currentOffset={currentOffset} 49 + fallbackPagination={ 50 + <PokedexPagination prevOffset={null} nextOffset={null} to="/live-query" /> 59 51 } 60 52 > 61 53 <PokemonTableContent currentOffset={currentOffset} /> 62 - </Suspense> 54 + </PokedexTableSection> 63 55 </ConsoleCard> 64 56 </StrategyPageLayout> 65 57 </div> ··· 105 97 const nextOffset = hasMore ? currentOffset + POKEMON_LIMIT : null; 106 98 107 99 return ( 108 - <> 109 - <div className="min-h-125"> 110 - <PokemonTable pokemon={pokemon} /> 111 - </div> 112 - <PaginationNav prevOffset={prevOffset} nextOffset={nextOffset} to="/live-query" /> 113 - </> 100 + <PokedexTableResults 101 + pokemon={pokemon} 102 + pagination={ 103 + <PokedexPagination prevOffset={prevOffset} nextOffset={nextOffset} to="/live-query" /> 104 + } 105 + /> 114 106 ); 115 107 }
+21 -30
src/routes/pagination.tsx
··· 1 - import { Suspense } from "react"; 2 1 import { createFileRoute, useRouteContext } from "@tanstack/react-router"; 3 2 import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; 4 3 import * as v from "valibot"; 5 - import { PaginationNav } from "~/components/pagination-nav"; 6 4 import { StrategyPageLayout } from "~/components/strategy-page-layout"; 7 5 import { ConsoleCard } from "~/components/console/console-card"; 8 6 import { SectionHeader } from "~/components/console/section-header"; 9 - import { PokemonTableSkeleton } from "~/components/tables/pokemon-table-skeleton"; 10 - import { POKEMON_LIMIT } from "~/constants"; 7 + import { 8 + PokedexPagination, 9 + PokedexTableResults, 10 + PokedexTableSection, 11 + } from "~/components/tables/pokedex-table-section"; 11 12 import { getPokemonListQueryKey, getPokemonListQueryFn } from "~/utils/pokemon"; 12 - import { lazily } from "~/lib/lazily"; 13 13 import { getStrategyArticle } from "~/server/strategy-article.functions"; 14 - 15 - const { PokemonTable } = lazily(() => import("~/components/tables/pokemon-table")); 16 14 17 15 const searchParamsSchema = v.object({ 18 16 offset: v.optional(v.number(), 0), ··· 56 54 57 55 <StrategyPageLayout sidebar={Article}> 58 56 <ConsoleCard className="mb-6"> 59 - <h1 className="text-lg font-mono text-(--text-primary) mb-4"> 60 - National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 61 - </h1> 62 - <Suspense 63 - fallback={ 64 - <> 65 - <div className="min-h-125"> 66 - <PokemonTableSkeleton rowCount={POKEMON_LIMIT} /> 67 - </div> 68 - <PaginationNav prevOffset={null} nextOffset={null} to="/pagination" /> 69 - </> 57 + <PokedexTableSection 58 + currentOffset={currentOffset} 59 + fallbackPagination={ 60 + <PokedexPagination prevOffset={null} nextOffset={null} to="/pagination" /> 70 61 } 71 62 > 72 63 <PokemonTableContent /> 73 - </Suspense> 64 + </PokedexTableSection> 74 65 </ConsoleCard> 75 66 </StrategyPageLayout> 76 67 </div> ··· 83 74 const { data } = useSuspenseQuery(pokemonListOptions); 84 75 85 76 return ( 86 - <> 87 - <div className="min-h-125"> 88 - <PokemonTable pokemon={data.pokemon} /> 89 - </div> 90 - <PaginationNav 91 - prefetch="viewport" 92 - prevOffset={data.prevOffset} 93 - nextOffset={data.nextOffset} 94 - to="/pagination" 95 - /> 96 - </> 77 + <PokedexTableResults 78 + pokemon={data.pokemon} 79 + pagination={ 80 + <PokedexPagination 81 + prefetch="viewport" 82 + prevOffset={data.prevOffset} 83 + nextOffset={data.nextOffset} 84 + to="/pagination" 85 + /> 86 + } 87 + /> 97 88 ); 98 89 }
+20 -25
src/routes/preloading.tsx
··· 1 - import { Suspense } from "react"; 2 1 import { createFileRoute, useRouteContext } from "@tanstack/react-router"; 3 2 import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"; 4 3 import * as v from "valibot"; 5 - import { PaginationNav } from "~/components/pagination-nav"; 6 4 import { StrategyPageLayout } from "~/components/strategy-page-layout"; 7 5 import { ConsoleCard } from "~/components/console/console-card"; 8 6 import { SectionHeader } from "~/components/console/section-header"; 9 - import { PokemonTableSkeleton } from "~/components/tables/pokemon-table-skeleton"; 10 - import { POKEMON_LIMIT } from "~/constants"; 7 + import { 8 + PokedexPagination, 9 + PokedexTableResults, 10 + PokedexTableSection, 11 + } from "~/components/tables/pokedex-table-section"; 11 12 import { getPokemonListQueryKey, getPokemonListQueryFn } from "~/utils/pokemon"; 12 - import { lazily } from "~/lib/lazily"; 13 13 import { getStrategyArticle } from "~/server/strategy-article.functions"; 14 - 15 - const { PokemonTable } = lazily(() => import("~/components/tables/pokemon-table")); 16 14 17 15 const searchParamsSchema = v.object({ 18 16 offset: v.optional(v.number(), 0), ··· 56 54 57 55 <StrategyPageLayout sidebar={Article}> 58 56 <ConsoleCard className="mb-6"> 59 - <h1 className="text-lg font-mono text-(--text-primary) mb-4"> 60 - National Pokédex: Pokémon {currentOffset + 1}-{currentOffset + POKEMON_LIMIT} 61 - </h1> 62 - <Suspense 63 - fallback={ 64 - <> 65 - <div className="min-h-125"> 66 - <PokemonTableSkeleton rowCount={POKEMON_LIMIT} /> 67 - </div> 68 - <PaginationNav prevOffset={null} nextOffset={null} to="/preloading" /> 69 - </> 57 + <PokedexTableSection 58 + currentOffset={currentOffset} 59 + fallbackPagination={ 60 + <PokedexPagination prevOffset={null} nextOffset={null} to="/preloading" /> 70 61 } 71 62 > 72 63 <PokemonTableContent /> 73 - </Suspense> 64 + </PokedexTableSection> 74 65 </ConsoleCard> 75 66 </StrategyPageLayout> 76 67 </div> ··· 83 74 const { data } = useSuspenseQuery(pokemonListOptions); 84 75 85 76 return ( 86 - <> 87 - <div className="min-h-125"> 88 - <PokemonTable pokemon={data.pokemon} /> 89 - </div> 90 - <PaginationNav prevOffset={data.prevOffset} nextOffset={data.nextOffset} to="/preloading" /> 91 - </> 77 + <PokedexTableResults 78 + pokemon={data.pokemon} 79 + pagination={ 80 + <PokedexPagination 81 + prevOffset={data.prevOffset} 82 + nextOffset={data.nextOffset} 83 + to="/preloading" 84 + /> 85 + } 86 + /> 92 87 ); 93 88 }