-
+ )
);
}
diff --git a/app/[locale]/page.tsx b/app/[locale]/page.tsx
index 7948af2..a9c4dc0 100644
--- a/app/[locale]/page.tsx
+++ b/app/[locale]/page.tsx
@@ -1,11 +1,9 @@
-import {
- dehydrate,
- HydrationBoundary,
- QueryClient,
-} from "@tanstack/react-query";
+"use client";
+
import dynamic from "next/dynamic";
+import { useLocale } from "next-intl";
+import { useQueryState } from "nuqs";
-import { getHighline } from "@/app/actions/getHighline";
import CreateHighline from "@/components/CreateHighline";
import MapToggle from "@/components/Map/MapToggle";
@@ -13,8 +11,6 @@ import { HeroPromoCard } from "./_components/hero-promo-card";
import { HighlineList } from "./_components/HighlineList";
import Search from "./_components/search";
-const PAGE_SIZE = 6;
-
const Map = dynamic(() => import("@/components/Map/Map"), {
ssr: false,
loading: () => (
@@ -39,30 +35,15 @@ const Map = dynamic(() => import("@/components/Map/Map"), {
),
});
-export default async function Home({
- params: { locale },
- searchParams,
-}: {
- params: { locale: "en" | "pt" };
- searchParams: { [key: string]: string | undefined };
-}) {
- const mapOpen = searchParams["view"] === "map";
- const location = searchParams["location"] || null;
- const focusedMarker = searchParams["focusedMarker"];
+export default function Home() {
+ const locale = useLocale();
+
+ const [view] = useQueryState("view");
+ const [location] = useQueryState("location");
+ const [focusedMarker] = useQueryState("focusedMarker");
+
+ const mapOpen = view === "map";
const isPickingLocation = location === "picking";
- const searchValue = searchParams["q"] || "";
- const queryClient = new QueryClient();
- await queryClient.prefetchInfiniteQuery({
- queryKey: ["highlines", { searchValue }],
- queryFn: ({ pageParam }) =>
- getHighline({ pageParam, searchValue, pageSize: PAGE_SIZE }),
- initialPageParam: 1,
- getNextPageParam: (lastPage, pages) => {
- const nextPage = pages.length + 1;
- return lastPage.data?.length === PAGE_SIZE ? nextPage : undefined;
- },
- pages: 2,
- });
return (
@@ -76,9 +57,7 @@ export default async function Home({
<>
-
-
-
+
>
)}
{
- const searchParams = useSearchParams();
- const router = useRouter();
- const pathname = usePathname();
-
- // Get a new searchParams string by merging the current
- // searchParams with a provided key/value pair
- const createQueryString = React.useCallback(
- (name: string, value: string) => {
- const params = new URLSearchParams(searchParams.toString());
- params.set(name, value);
-
- return params.toString();
- },
- [searchParams]
- );
+ const [year, setYear] = useQueryState("year");
function handleYearChange(year: string) {
- router.push(pathname + "?" + createQueryString("year", year));
+ setYear(year);
}
return (
diff --git a/app/[locale]/profile/[username]/page.tsx b/app/[locale]/profile/[username]/page.tsx
index 49cfde9..055c4e0 100644
--- a/app/[locale]/profile/[username]/page.tsx
+++ b/app/[locale]/profile/[username]/page.tsx
@@ -1,5 +1,4 @@
import type { Metadata } from "next";
-import { cookies } from "next/headers";
import { getTranslations } from "next-intl/server";
import { Suspense } from "react";
@@ -14,14 +13,12 @@ import UserNotFound from "./_components/UserNotFound";
export const dynamic = "force-dynamic";
type Props = {
- params: { locale: string; username: string };
- searchParams: { [key: string]: string | undefined };
+ params: Promise<{ locale: string; username: string }>;
+ searchParams: Promise<{ [key: string]: string | undefined }>;
};
-export async function generateMetadata({
- params,
- searchParams,
-}: Props): Promise {
+export async function generateMetadata(props: Props): Promise {
+ const params = await props.params;
const t = await getTranslations("profileMetadata");
return {
title: t("title", { username: `@${params.username}` }),
@@ -29,12 +26,13 @@ export async function generateMetadata({
};
}
-export default async function Profile({
- params: { username },
- searchParams,
-}: Props) {
- const cookieStore = cookies();
- const supabase = useSupabaseServer(cookieStore);
+export default async function Profile(props: Props) {
+ // eslint-disable-next-line react-hooks/rules-of-hooks
+ const supabase = await useSupabaseServer();
+
+ const searchParams = await props.searchParams;
+ const params = await props.params;
+ const { username } = params;
const result = await Promise.all([
supabase.auth.getUser(),
diff --git a/app/actions/getHighline.ts b/app/actions/getHighline.ts
index 9d8bbdb..80a772a 100644
--- a/app/actions/getHighline.ts
+++ b/app/actions/getHighline.ts
@@ -20,7 +20,7 @@ export const getHighline = async ({
pageSize,
id,
}: Props) => {
- const cookieStore = cookies();
+ const cookieStore = await cookies();
const supabase = createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
diff --git a/components/CreateHighline.tsx b/components/CreateHighline.tsx
index 5ac98e2..a4d6b0d 100644
--- a/components/CreateHighline.tsx
+++ b/components/CreateHighline.tsx
@@ -5,6 +5,7 @@ import { useMutation } from "@tanstack/react-query";
import type { LatLng } from "leaflet";
import { PlusIcon } from "lucide-react";
import { useTranslations } from "next-intl";
+import { useQueryState } from "nuqs";
import { useEffect, useState } from "react";
import { useForm } from "react-hook-form";
import { v4 as uuidv4 } from "uuid";
@@ -22,7 +23,6 @@ import {
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer";
-import { useQueryString } from "@/hooks/useQueryString";
import { Link } from "@/navigation";
import {
decodeLocation,
@@ -85,20 +85,20 @@ const CreateHighline = ({
location: string | null;
hidden?: boolean;
}) => {
- const { pushQueryParam, deleteQueryParam } = useQueryString();
+ const [locationParam, setLocationParam] = useQueryState("location");
const [open, setOpen] = useState(false);
function handleToggleDrawer(open: boolean) {
// If user is on map, set location query parameter to picking so he can set the anchors
if (mapIsOpen && !location) {
- pushQueryParam("location", "picking");
+ setLocationParam("picking");
return;
}
// If user is picking location don't open the Drawer
if (location === "picking") return;
// If there is a location setted and he is closing the drawer, reset the location
if (open === false && location) {
- deleteQueryParam("location");
+ setLocationParam(null);
}
setOpen(open);
}
diff --git a/components/Map/Controls.tsx b/components/Map/Controls.tsx
index f074873..e66d6de 100644
--- a/components/Map/Controls.tsx
+++ b/components/Map/Controls.tsx
@@ -8,6 +8,7 @@ import {
SatelliteIcon,
} from "lucide-react";
import { useTranslations } from "next-intl";
+import { useQueryState } from "nuqs";
import { useState } from "react";
import { TileLayer, useMapEvents } from "react-leaflet";
@@ -16,18 +17,16 @@ import {
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";
-import { useQueryString } from "@/hooks/useQueryString";
-export const MapControls = ({ locale }: { locale: string }) => {
+export const MapControls = () => {
const t = useTranslations("map.type");
- const { pushQueryParam, searchParams } = useQueryString();
+ const [mapType, setMapType] = useQueryState("mapType");
const acceptedTypes = ["map", "satelite"] as const;
- const mapType: (typeof acceptedTypes)[number] = acceptedTypes.includes(
- // @ts-expect-error
- searchParams.get("mapType") || ""
+ const currentMapType: (typeof acceptedTypes)[number] = acceptedTypes.includes(
+ mapType as (typeof acceptedTypes)[number]
)
- ? (searchParams.get("mapType") as (typeof acceptedTypes)[number])
+ ? (mapType as (typeof acceptedTypes)[number])
: "map";
const [isLocated, setIsLocated] = useState(false);
@@ -43,7 +42,7 @@ export const MapControls = ({ locale }: { locale: string }) => {
return (
<>
- {mapType === "satelite" ? (
+ {currentMapType === "satelite" ? (
Mapbox © OpenStreetMap Improve this map`}
url={`https://api.mapbox.com/styles/v1/mapbox/satellite-streets-v12/tiles/{z}/{x}/{y}?access_token=${process.env.NEXT_PUBLIC_MAPBOX_ACCESS_TOKEN}`}
@@ -82,8 +81,8 @@ export const MapControls = ({ locale }: { locale: string }) => {