Skip to content

Commit 66c789a

Browse files
feat: query-factory, custom devtools to change data source
1 parent 17dac78 commit 66c789a

File tree

24 files changed

+551
-189
lines changed

24 files changed

+551
-189
lines changed

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
"@radix-ui/react-separator": "^1.1.8",
2525
"@radix-ui/react-slot": "^1.2.4",
2626
"@radix-ui/react-tabs": "^1.1.13",
27+
"@radix-ui/react-toggle": "^1.1.10",
28+
"@radix-ui/react-toggle-group": "^1.1.11",
2729
"@tailwindcss/vite": "^4.1.17",
2830
"@tanstack/react-query": "^5.90.12",
2931
"@tanstack/react-router": "^1.139.16",
@@ -32,10 +34,12 @@
3234
"class-variance-authority": "^0.7.1",
3335
"clsx": "^2.1.1",
3436
"cmdk": "^1.1.1",
37+
"next-themes": "^0.4.6",
3538
"react": "^19.2.1",
3639
"react-dom": "^19.2.1",
3740
"react-icons": "^5.5.0",
3841
"react-spinners": "^0.17.0",
42+
"sonner": "^2.0.7",
3943
"tailwind-merge": "^3.4.0",
4044
"tailwindcss-animate": "^1.0.7",
4145
"url-join": "^5.0.0"

pnpm-lock.yaml

Lines changed: 86 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/__root.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
22
import { createRootRoute, Outlet } from "@tanstack/react-router"
33
import { StrictMode } from "react"
44
import { IconContext } from "react-icons"
5+
import DevSettings from "@/components/DevSettings"
56
import Layout from "@/components/Layout"
7+
import { Toaster } from "@/components/ui/sonner"
68
import ContextProvider from "@/contexts/ContextProvider"
79

810
export const queryClient = new QueryClient()
@@ -20,7 +22,10 @@ function RootComponent() {
2022
<QueryClientProvider client={queryClient}>
2123
<Layout>
2224
<Outlet />
25+
26+
{import.meta.env.DEV && <DevSettings />}
2327
</Layout>
28+
<Toaster richColors position="bottom-center" />
2429
</QueryClientProvider>
2530
</IconContext.Provider>
2631
</ContextProvider>

src/app/_home/$school/$year/$id/-Table/columns.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -179,13 +179,13 @@ export function getColumns(
179179
id: "sectionsResults",
180180
columns: rows[0].sectionsResults
181181
? Object.keys(rows[0].sectionsResults).map((k) => ({
182-
header: k,
183-
accessorFn: (row) => row.sectionsResults?.[k],
184-
cell: ({ getValue }) => {
185-
const value = getValue()
186-
return Formatter.displayScore(value)
187-
},
188-
}))
182+
header: k,
183+
accessorFn: (row) => row.sectionsResults?.[k],
184+
cell: ({ getValue }) => {
185+
const value = getValue()
186+
return Formatter.displayScore(value)
187+
},
188+
}))
189189
: [],
190190
},
191191
{

src/app/_home/$school/$year/$id/-Table/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,9 @@ export default function Table({ table: _table, csvFilename: _ }: TableProps) {
113113
{header.isPlaceholder
114114
? null
115115
: flexRender(
116-
header.column.columnDef.header,
117-
header.getContext()
118-
)}
116+
header.column.columnDef.header,
117+
header.getContext()
118+
)}
119119
</TableHead>
120120
)
121121
)

src/app/_home/$school/$year/$id/index.tsx

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import { queryOptions, useSuspenseQuery } from "@tanstack/react-query"
1+
import { useSuspenseQuery } from "@tanstack/react-query"
22
import {
33
createFileRoute,
44
ErrorComponent,
55
redirect,
66
} from "@tanstack/react-router"
77
import { useContext, useMemo, useState } from "react"
8-
import { queryClient } from "@/app/__root"
98
import Page from "@/components/custom-ui/Page.tsx"
109
import PathBreadcrumb from "@/components/PathBreadcrumb.tsx"
1110
import MobileContext from "@/contexts/MobileContext"
11+
import { useQueries } from "@/hooks/use-queries"
1212
import CustomMap from "@/utils/CustomMap"
1313
import { NotFoundError } from "@/utils/errors.ts"
1414
import type {
@@ -20,7 +20,6 @@ import { isSchool } from "@/utils/types/data/school"
2020
import { CourseCombobox } from "./-course-combobox"
2121
import LocationsSelect from "./-location-select"
2222
import Table from "./-Table"
23-
import { getDataUrl } from "@/utils/data"
2423

2524
// function TEMP_getCoursesMap(
2625
// ranking: NewRanking
@@ -120,18 +119,6 @@ function fallbackSelectedLocation(
120119
return locations[0]
121120
}
122121

123-
function rankingOptions(id: string) {
124-
return queryOptions({
125-
queryKey: ["ranking", id],
126-
queryFn: async () => {
127-
const res = await fetch(getDataUrl(`/output/rankings/${id}.json`))
128-
if (res.status === 404) throw new NotFoundError()
129-
return res.json() as Promise<NewRanking>
130-
},
131-
staleTime: 5 * 1000,
132-
})
133-
}
134-
135122
function getCoursesMap(
136123
courses: NewRanking["courses"]
137124
): CustomMap<string, string[]> {
@@ -160,8 +147,6 @@ export const Route = createFileRoute("/_home/$school/$year/$id/")({
160147
else throw redirect({ to: "/" })
161148
},
162149
},
163-
loader: ({ params }) =>
164-
queryClient.ensureQueryData(rankingOptions(params.id)),
165150
errorComponent: ({ error }) => {
166151
if (error instanceof NotFoundError) return <p>Ranking not found</p>
167152

@@ -172,7 +157,8 @@ export const Route = createFileRoute("/_home/$school/$year/$id/")({
172157

173158
function RouteComponent() {
174159
const params = Route.useParams()
175-
const { data: ranking } = useSuspenseQuery(rankingOptions(params.id))
160+
const queries = useQueries()
161+
const { data: ranking } = useSuspenseQuery(queries.ranking(params.id))
176162

177163
// const res = await axios.get(
178164
// "http://localhost:8120/2024_20102_491d_html.json"
@@ -259,13 +245,15 @@ function RouteComponent() {
259245

260246
return (
261247
<Page
262-
className={`flex items-center gap-4 px-0 ${isMobile ? "flex-col overflow-y-auto overflow-x-hidden" : ""
263-
}`}
248+
className={`flex items-center gap-4 px-0 ${
249+
isMobile ? "flex-col overflow-y-auto overflow-x-hidden" : ""
250+
}`}
264251
fullWidth
265252
>
266253
<div
267-
className={`flex w-full max-w-7xl flex-col gap-4 px-4 ${isMobile ? "flex-col overflow-y-auto overflow-x-hidden" : ""
268-
}`}
254+
className={`flex w-full max-w-7xl flex-col gap-4 px-4 ${
255+
isMobile ? "flex-col overflow-y-auto overflow-x-hidden" : ""
256+
}`}
269257
>
270258
<PathBreadcrumb />
271259
<div className="flex w-full gap-4 max-sm:flex-col sm:items-center">

src/app/_home/$school/$year/index.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@ import PhaseFlag from "@/components/custom-ui/PhaseFlag"
55
import { ButtonGrid } from "@/components/Homepage/ButtonGrid"
66
import PathBreadcrumb from "@/components/PathBreadcrumb"
77
import { Button } from "@/components/ui/button"
8+
import { useQueries } from "@/hooks/use-queries"
89
import { getPhaseGroups, phaseGroupLabel, phaseLinkLabel } from "@/utils/phase"
910
import type { PhaseLink } from "@/utils/types/data/phase"
10-
import type { BySchoolYearIndex } from "@/utils/types/data/ranking"
1111
import { isSchool } from "@/utils/types/data/school"
12-
import { getDataUrl } from "@/utils/data"
1312

1413
export const Route = createFileRoute("/_home/$school/$year/")({
1514
component: RouteComponent,
@@ -23,14 +22,9 @@ export const Route = createFileRoute("/_home/$school/$year/")({
2322

2423
function RouteComponent() {
2524
const { school, year } = Route.useParams()
26-
const { data } = useQuery({
27-
queryKey: ["index"],
28-
queryFn: async () => {
29-
const res = await fetch(getDataUrl("/output/indexes/bySchoolYear.json"))
30-
return res.json() as Promise<BySchoolYearIndex>
31-
},
32-
})
33-
if (!data) return null
25+
const queries = useQueries()
26+
const { data, isPending } = useQuery(queries.index)
27+
if (!data || isPending) return null
3428
const yearData = data[school]?.[year] ?? []
3529

3630
const groups = getPhaseGroups(yearData).entriesArr()

src/app/_home/$school/index.tsx

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ import Spinner from "@/components/custom-ui/Spinner"
66
import { ButtonGrid } from "@/components/Homepage/ButtonGrid"
77
import PathBreadcrumb from "@/components/PathBreadcrumb"
88
import { Button } from "@/components/ui/button"
9-
import type { BySchoolYearIndex } from "@/utils/types/data/ranking"
9+
import { useQueries } from "@/hooks/use-queries"
1010
import { isSchool } from "@/utils/types/data/school"
11-
import { getDataUrl } from "@/utils/data"
1211

1312
export const Route = createFileRoute("/_home/$school/")({
1413
component: RouteComponent,
@@ -23,15 +22,10 @@ export const Route = createFileRoute("/_home/$school/")({
2322
function RouteComponent() {
2423
const [clicked, setClicked] = useState(false)
2524
const { school } = Route.useParams()
26-
const { data } = useQuery({
27-
queryKey: ["index"],
28-
queryFn: async () => {
29-
const res = await fetch(getDataUrl("/output/indexes/bySchoolYear.json"))
30-
return res.json() as Promise<BySchoolYearIndex>
31-
},
32-
})
25+
const queries = useQueries()
26+
const { data, isPending } = useQuery(queries.index)
3327

34-
if (!data) return null
28+
if (!data || isPending) return null
3529
const years = Object.keys(data[school] ?? {}).map(Number)
3630

3731
return clicked ? (

0 commit comments

Comments
 (0)