Skip to content

Commit b5e94fc

Browse files
committed
Move tabs state from useState to query parameters
1 parent 37e36d1 commit b5e94fc

File tree

4 files changed

+50
-34
lines changed

4 files changed

+50
-34
lines changed

app/[locale]/_components/search.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import { useRouter } from "@/navigation";
99
import { createUrl } from "@/utils/helperFunctions";
1010

1111
export default function Search() {
12-
const router = useRouter();
1312
const t = useTranslations("home");
13+
const router = useRouter();
1414
const searchParams = useSearchParams();
1515

1616
function onSubmit(e: React.FormEvent<HTMLFormElement>) {

components/tabs/Ranking/CategoryDropdown.tsx

-20
Original file line numberDiff line numberDiff line change
@@ -66,26 +66,6 @@ function CategoryDropdown({
6666
</label>
6767
</li>
6868
))}
69-
{/* {categories.map((c) => (
70-
<li key={c}>
71-
<label
72-
htmlFor={c}
73-
className="flex items-center rounded p-2 hover:bg-gray-100 dark:hover:bg-gray-500"
74-
>
75-
<input
76-
id={c}
77-
type="radio"
78-
value={c}
79-
checked={selectedCategory === c}
80-
onChange={() => handleCategorySelect(c)}
81-
className="h-4 w-4 border-gray-300 bg-gray-100 text-blue-600 focus:ring-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 dark:ring-offset-gray-800 dark:focus:ring-blue-600"
82-
/>
83-
<span className="ml-2 w-full rounded text-sm font-medium text-gray-500 dark:text-gray-300">
84-
{c}
85-
</span>
86-
</label>
87-
</li>
88-
))} */}
8969
</ul>
9070
</div>
9171
)}

components/tabs/Ranking/index.tsx

+21-5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
"use client";
22

3+
import { useSearchParams } from "next/navigation";
34
import { useTranslations } from "next-intl";
4-
import React, { useMemo, useState } from "react";
5+
import { useCallback, useMemo } from "react";
56

7+
import { usePathname, useRouter } from "@/navigation";
68
import type { Tables } from "@/utils/supabase/database.types";
79

810
import Cadenas from "./Cadenas";
@@ -20,6 +22,9 @@ export type Categories = Record<Category, { label: string }>;
2022

2123
function Ranking({ highline }: Props) {
2224
const t = useTranslations("highline.tabs.ranking");
25+
const searchParams = useSearchParams();
26+
const router = useRouter();
27+
const pathname = usePathname();
2328
const categories = useMemo<Categories>(
2429
() => ({
2530
speedline: { label: "Speedline" },
@@ -29,13 +34,24 @@ function Ranking({ highline }: Props) {
2934
}),
3035
[t]
3136
);
32-
const [selectedCategory, setSelectedCategory] = useState<Category>(
33-
() => (localStorage.getItem("selectedCategory") as Category) || "speedline"
37+
38+
const selectedCategory: Category =
39+
(searchParams.get("category") as Category) || "speedline";
40+
41+
// Get a new searchParams string by merging the current
42+
// searchParams with a provided key/value pair
43+
const createQueryString = useCallback(
44+
(name: string, value: string) => {
45+
const params = new URLSearchParams(searchParams.toString());
46+
params.set(name, value);
47+
48+
return params.toString();
49+
},
50+
[searchParams]
3451
);
3552

3653
function handleCategoryChange(category: Category) {
37-
localStorage.setItem("selectedCategory", category);
38-
setSelectedCategory(category);
54+
router.push(pathname + "?" + createQueryString("category", category));
3955
}
4056

4157
function renderCategory() {

components/tabs/Tabs.tsx

+28-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
"use client";
22

33
import { motion } from "framer-motion";
4+
import { useSearchParams } from "next/navigation";
45
import { useTranslations } from "next-intl";
5-
import { useMemo, useState } from "react";
6+
import { useCallback, useMemo } from "react";
67

8+
import { usePathname, useRouter } from "@/navigation";
79
import type { Tables } from "@/utils/supabase/database.types";
810

911
import Comments from "./Comments";
@@ -34,6 +36,24 @@ function tabMapping(tab: string, highline: Tables["highline"]["Row"]) {
3436

3537
function Tabs({ highline }: Props) {
3638
const t = useTranslations("highline.tabs");
39+
const router = useRouter();
40+
const pathname = usePathname();
41+
const searchParams = useSearchParams();
42+
43+
const tab = searchParams.get("tab") || "info";
44+
45+
// Get a new searchParams string by merging the current
46+
// searchParams with a provided key/value pair
47+
const createQueryString = useCallback(
48+
(name: string, value: string) => {
49+
const params = new URLSearchParams(searchParams.toString());
50+
params.set(name, value);
51+
params.delete("category");
52+
53+
return params.toString();
54+
},
55+
[searchParams]
56+
);
3757

3858
const tabs = useMemo<Tab[]>(
3959
() => [
@@ -52,7 +72,6 @@ function Tabs({ highline }: Props) {
5272
],
5373
[t]
5474
);
55-
const [selectedTabId, setSelectedTabId] = useState(tabs[0].id);
5675

5776
return (
5877
<div className="h-full">
@@ -61,14 +80,15 @@ function Tabs({ highline }: Props) {
6180
<li
6281
key={item.id}
6382
className={`relative flex-auto cursor-pointer rounded-t-md text-base md:text-lg ${
64-
item.id === selectedTabId
65-
? "text-blue-600 dark:text-blue-500"
66-
: ""
83+
item.id === tab ? "text-blue-600 dark:text-blue-500" : ""
6784
}`}
68-
onClick={() => setSelectedTabId(item.id)}
85+
onClick={(e) => {
86+
e.preventDefault();
87+
router.push(pathname + "?" + createQueryString("tab", item.id));
88+
}}
6989
>
7090
{item.label}
71-
{item.id === selectedTabId ? (
91+
{item.id === tab ? (
7292
<motion.div
7393
className="absolute -bottom-px left-0 right-0 h-px bg-blue-700"
7494
layout
@@ -80,7 +100,7 @@ function Tabs({ highline }: Props) {
80100
</ul>
81101

82102
<div className="overflow-y-auto overflow-x-hidden">
83-
{tabMapping(selectedTabId, highline)}
103+
{tabMapping(tab, highline)}
84104
</div>
85105
</div>
86106
);

0 commit comments

Comments
 (0)