Skip to content

Commit fc8056d

Browse files
feat: zustand time (it allows prefetching pattern)
1 parent a101afe commit fc8056d

File tree

9 files changed

+90
-68
lines changed

9 files changed

+90
-68
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@
4242
"sonner": "^2.0.7",
4343
"tailwind-merge": "^3.4.0",
4444
"tailwindcss-animate": "^1.0.7",
45-
"url-join": "^5.0.0"
45+
"url-join": "^5.0.0",
46+
"zustand": "^5.0.9"
4647
},
4748
"devDependencies": {
4849
"@biomejs/biome": "^2.3.8",

pnpm-lock.yaml

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

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@ import {
55
redirect,
66
} from "@tanstack/react-router"
77
import { useContext, useMemo, useState } from "react"
8+
import { queryClient } from "@/app/__root"
89
import Alert from "@/components/custom-ui/Alert"
910
import Page from "@/components/custom-ui/Page.tsx"
1011
import Spinner from "@/components/custom-ui/Spinner"
1112
import PathBreadcrumb from "@/components/PathBreadcrumb.tsx"
1213
import MobileContext from "@/contexts/MobileContext"
1314
import { useQueries } from "@/hooks/use-queries"
15+
import { useSettingsStore } from "@/stores/settings-store"
1416
import CustomMap from "@/utils/CustomMap"
1517
import { NotFoundError } from "@/utils/errors.ts"
18+
import { getActiveQueries } from "@/utils/queries"
1619
import type {
1720
NewRanking,
1821
NewStudentResultCourse,
@@ -149,6 +152,11 @@ export const Route = createFileRoute("/_home/$school/$year/$id/")({
149152
else throw redirect({ to: "/" })
150153
},
151154
},
155+
loader: ({ params }) => {
156+
const state = useSettingsStore.getState()
157+
const queries = getActiveQueries(state)
158+
queryClient.prefetchQuery(queries.ranking(params.id))
159+
},
152160
errorComponent: ({ error }) => {
153161
if (error instanceof NotFoundError) return <p>Ranking not found</p>
154162

src/components/DevSettings/settings/set-data-source.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useQuery } from "@tanstack/react-query"
2-
import { useContext, useState } from "react"
2+
import { useState } from "react"
33
import { LuCheck, LuPencil, LuRefreshCw } from "react-icons/lu"
44
import { toast } from "sonner"
55
import { Badge } from "@/components/ui/badge"
@@ -11,14 +11,13 @@ import {
1111
PopoverTrigger,
1212
} from "@/components/ui/popover"
1313
import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"
14-
import { SettingsContext } from "@/contexts/SettingsContext"
1514
import { useQueries } from "@/hooks/use-queries"
15+
import { useSettingsStore } from "@/stores/settings-store"
1616
import { DATA_SOURCE } from "@/utils/constants"
1717
import type { DataSource } from "@/utils/queries"
1818

1919
export function SetDataSource() {
20-
const { localPort, ref, dataSource, setDataSource } =
21-
useContext(SettingsContext)
20+
const { localPort, ref, dataSource, setDataSource } = useSettingsStore()
2221

2322
return (
2423
<div className="flex w-full items-center gap-10">
@@ -58,7 +57,8 @@ export function SetDataSource() {
5857
function ChangeRef({ initialRef }: { initialRef: string }) {
5958
const [ref, setRef] = useState<string>(initialRef)
6059
const [open, setOpen] = useState<boolean>(false)
61-
const { setRef: updateRef } = useContext(SettingsContext)
60+
61+
const { setRef: updateRef } = useSettingsStore()
6262

6363
function handleUpdate(e: React.FormEvent<HTMLFormElement>) {
6464
e.preventDefault()
@@ -94,7 +94,7 @@ function ChangePort({ initialPort }: { initialPort: number }) {
9494
const [port, setPort] = useState<number>(initialPort)
9595
const [open, setOpen] = useState<boolean>(false)
9696
const error = port < 1000 || port > 65535 || Number.isNaN(port)
97-
const { changeLocalPort } = useContext(SettingsContext)
97+
const { changeLocalPort } = useSettingsStore()
9898

9999
function handleInputChange(e: React.ChangeEvent<HTMLInputElement>) {
100100
const value = e.target.valueAsNumber

src/contexts/ContextProvider.tsx

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
import { DarkModeProvider } from "./DarkModeContext"
22
import { MobileProvider } from "./MobileContext"
3-
import { SettingsProvider } from "./SettingsContext"
43

54
interface Props {
65
children: React.ReactNode
76
}
87
export default function ContextProvider({ children }: Props) {
98
return (
109
<DarkModeProvider>
11-
<SettingsProvider>
12-
<MobileProvider>{children}</MobileProvider>
13-
</SettingsProvider>
10+
<MobileProvider>{children}</MobileProvider>
1411
</DarkModeProvider>
1512
)
1613
}

src/contexts/SettingsContext.tsx

Lines changed: 0 additions & 46 deletions
This file was deleted.

src/hooks/use-queries.tsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,7 @@
1-
import { useContext, useMemo } from "react"
2-
import { SettingsContext } from "@/contexts/SettingsContext"
3-
import { queryFactory } from "@/utils/queries"
1+
import { useSettingsStore } from "@/stores/settings-store"
2+
import { getActiveQueries } from "@/utils/queries"
43

54
export function useQueries() {
6-
const { dataSource, ref, localPort } = useContext(SettingsContext)
7-
return useMemo(
8-
() =>
9-
dataSource === "github"
10-
? queryFactory({ source: dataSource, ref })
11-
: queryFactory({ source: "local", port: localPort }),
12-
[dataSource, ref, localPort]
13-
)
5+
const settings = useSettingsStore()
6+
return getActiveQueries(settings)
147
}

src/stores/settings-store.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { create } from "zustand"
2+
import type { DataSource } from "@/utils/queries"
3+
4+
export interface SettingsState {
5+
dataSource: DataSource
6+
localPort: number
7+
ref: string
8+
// Actions
9+
setDataSource: (dataSource: DataSource) => void
10+
changeLocalPort: (port: number) => void
11+
setRef: (ref: string) => void
12+
}
13+
14+
export const useSettingsStore = create<SettingsState>((set) => ({
15+
// Initial State
16+
dataSource: "github",
17+
localPort: 6767,
18+
ref: "main",
19+
20+
// Actions
21+
setDataSource: (dataSource) => set({ dataSource }),
22+
23+
changeLocalPort: (port) => {
24+
if (port < 1000 || port > 65535) return
25+
set({ localPort: port })
26+
},
27+
28+
setRef: (ref) => set({ ref }),
29+
}))

src/utils/queries.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { queryOptions } from "@tanstack/react-query"
22
import urlJoin from "url-join"
3+
import type { SettingsState } from "@/stores/settings-store"
34
import { type DATA_SOURCE, LINKS } from "./constants"
45
import { NotFoundError } from "./errors"
56
import type { BySchoolYearIndex, NewRanking } from "./types/data/ranking"
@@ -39,6 +40,7 @@ export const queryFactory = (opts: QueryFactoryOpts) => ({
3940
},
4041
retry: 2,
4142
retryDelay: 300,
43+
staleTime: 120_000,
4244
}),
4345

4446
ranking: (id: string) =>
@@ -52,5 +54,16 @@ export const queryFactory = (opts: QueryFactoryOpts) => ({
5254
},
5355
retry: 2,
5456
retryDelay: 300,
57+
staleTime: 600_000,
5558
}),
5659
})
60+
61+
export const getActiveQueries = (
62+
settings: Pick<SettingsState, "dataSource" | "ref" | "localPort">
63+
) => {
64+
const { dataSource, ref, localPort } = settings
65+
66+
return dataSource === "github"
67+
? queryFactory({ source: dataSource, ref })
68+
: queryFactory({ source: "local", port: localPort })
69+
}

0 commit comments

Comments
 (0)