Skip to content

Instantly share code, notes, and snippets.

@sonicoder86
Created April 21, 2024 16:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sonicoder86/6effbbe2de48547845285cf5225f1a98 to your computer and use it in GitHub Desktop.
Save sonicoder86/6effbbe2de48547845285cf5225f1a98 to your computer and use it in GitHub Desktop.
import React from "react";
import { useSearchParams } from "next/navigation";
import type { PropsWithChildren } from "react";
import { z } from "zod";
const MAIN_PAGE = "main";
const VIDEOS_PAGE = "videos";
const pageDefinitions = {
[MAIN_PAGE]: {
searchParams: z.object({
lang: z.string().default("en"),
}),
},
[VIDEOS_PAGE]: {
searchParams: z.object({
lang: z.string().default("en"),
page: z.number().default(1),
}),
},
};
type PageKeys = keyof typeof pageDefinitions;
const usePageSearchParams = <T extends PageKeys>(page: T): z.infer<(typeof pageDefinitions[T]["searchParams"])> => {
const searchParams = Object.fromEntries(useSearchParams().entries());
return pageDefinitions[page].searchParams.parse(searchParams);
};
const generateUrl = <T extends PageKeys>(page: T, searchParams?: Partial<z.infer<(typeof pageDefinitions[T]["searchParams"])>>): string => {
return `/${page}?${searchParams ? Object.keys(searchParams).join("&") : ""}`;
}
interface LinkParams<T extends PageKeys> {
page: T,
searchParams: Partial<z.infer<(typeof pageDefinitions[T]["searchParams"])>>
}
const PageLink = <T extends PageKeys>({ page, searchParams }: LinkParams<T> & PropsWithChildren) => {
return <div>{generateUrl(page, searchParams)}</div>;
}
const Page = () => {
return (
<PageLink page={MAIN_PAGE} searchParams={{ lang: "en" }}></PageLink>
);
}
const result = usePageSearchParams(MAIN_PAGE);
console.log(generateUrl(MAIN_PAGE, { lang: "en" }))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment