Fix routing details

This commit is contained in:
Timothy Armes
2024-09-30 09:42:37 +02:00
parent 08cbcd785e
commit 03f5ea3454
20 changed files with 60 additions and 43 deletions
+16 -4
View File
@@ -1,13 +1,27 @@
"use client"; "use client";
import { useTranslations } from "next-intl"; import { useLocale, useTranslations } from "next-intl";
import { useSearchParams } from "next/navigation"; import { useSearchParams } from "next/navigation";
import { SignInForm } from "@/components/SignInForm"; import { SignInForm } from "@/components/SignInForm";
import { Locale, getPathname, routing } from "@/utils/routing";
export default function SignIn() { export default function SignIn() {
const t = useTranslations("SignIn"); const t = useTranslations("SignIn");
const params = useSearchParams(); const params = useSearchParams();
const locale = useLocale();
const allowedLocales = routing.locales as unknown as Array<string>;
const effectiveLocal = allowedLocales.includes(locale)
? (locale as Locale)
: routing.defaultLocale;
const fallbackPath = getPathname({
locale: effectiveLocal,
href: { pathname: "/tournaments" },
});
const fallbackUrl = `/${effectiveLocal}${fallbackPath}`;
return ( return (
<section className="grid place-items-center bg-white pb-20 dark:bg-gray-800"> <section className="grid place-items-center bg-white pb-20 dark:bg-gray-800">
@@ -22,9 +36,7 @@ export default function SignIn() {
{t("info")} {t("info")}
</p> </p>
<SignInForm <SignInForm callbackPath={params.get("callbackUrl") ?? fallbackUrl} />
callbackPath={params.get("callbackUrl") ?? "/tournaments"}
/>
</div> </div>
</section> </section>
); );
@@ -7,7 +7,7 @@ import { FaGithub, FaRegEnvelope } from "react-icons/fa";
import { MdOutlinePrivacyTip } from "react-icons/md"; import { MdOutlinePrivacyTip } from "react-icons/md";
import { burgerMenuIsOpenAtom } from "@/atoms"; import { burgerMenuIsOpenAtom } from "@/atoms";
import { Link, usePathname, useRouter } from "@/utils/navigation"; import { Link, usePathname, useRouter } from "@/utils/routing";
import ThemeSwitcher from "./ThemeSwitcher"; import ThemeSwitcher from "./ThemeSwitcher";
@@ -4,7 +4,7 @@ import { twMerge } from "tailwind-merge";
import { burgerMenuIsOpenAtom } from "@/atoms"; import { burgerMenuIsOpenAtom } from "@/atoms";
import { useAuthMenuOptions } from "@/hooks/useAuthMenuOptions"; import { useAuthMenuOptions } from "@/hooks/useAuthMenuOptions";
import { Link } from "@/utils/navigation"; import { Link } from "@/utils/routing";
const HamburgerMenu = () => { const HamburgerMenu = () => {
const t = useTranslations("Nav"); const t = useTranslations("Nav");
@@ -1,7 +1,7 @@
import { useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import AuthButton from "@/components/AuthButton"; import AuthButton from "@/components/AuthButton";
import { Link } from "@/utils/navigation"; import { Link } from "@/utils/routing";
import Hamburger from "./Hamburger"; import Hamburger from "./Hamburger";
@@ -7,7 +7,7 @@ import { useTranslations } from "next-intl";
import InfoMessage from "@/components/InfoMessage"; import InfoMessage from "@/components/InfoMessage";
import { deleteAccount } from "@/server/deleteAccount"; import { deleteAccount } from "@/server/deleteAccount";
import { useRouter } from "@/utils/navigation"; import { useRouter } from "@/utils/routing";
export default function Contact() { export default function Contact() {
const t = useTranslations("DeleteAccount"); const t = useTranslations("DeleteAccount");
+1 -1
View File
@@ -19,7 +19,7 @@ import { fetchTournamentResultsSchema } from "@/schemas";
import { fetchTournamentResults } from "@/server/fetchTournamentResults"; import { fetchTournamentResults } from "@/server/fetchTournamentResults";
import { SearchedTournament } from "@/server/searchTournaments"; import { SearchedTournament } from "@/server/searchTournaments";
import { TimeControl } from "@/types"; import { TimeControl } from "@/types";
import { Link } from "@/utils/navigation"; import { Link } from "@/utils/routing";
import { KFactor } from "./KFactor"; import { KFactor } from "./KFactor";
import { ManualEloForm } from "./ManualEloForm"; import { ManualEloForm } from "./ManualEloForm";
@@ -16,8 +16,8 @@ import {
} from "@/atoms"; } from "@/atoms";
import { Map, MapMarker } from "@/components/Map"; import { Map, MapMarker } from "@/components/Map";
import { TimeControlColours } from "@/constants"; import { TimeControlColours } from "@/constants";
import { generatePieSVG } from "@/lib/pie";
import { TimeControl } from "@/types"; import { TimeControl } from "@/types";
import { generatePieSVG } from "@/utils/pie";
import Legend from "./Legend"; import Legend from "./Legend";
import TimeControlFilters from "./TimeControlFilters"; import TimeControlFilters from "./TimeControlFilters";
@@ -7,7 +7,7 @@ import { useTranslations } from "next-intl";
import InfoMessage, { clearMessage } from "@/components/InfoMessage"; import InfoMessage, { clearMessage } from "@/components/InfoMessage";
import { useZones } from "@/hooks/useZones"; import { useZones } from "@/hooks/useZones";
import { createZone } from "@/server/createZone"; import { createZone } from "@/server/createZone";
import { useRouter } from "@/utils/navigation"; import { useRouter } from "@/utils/routing";
import { ZoneForm, ZoneFormValues } from "../components/ZoneForm"; import { ZoneForm, ZoneFormValues } from "../components/ZoneForm";
@@ -8,7 +8,7 @@ import { useParams } from "next/navigation";
import InfoMessage, { clearMessage } from "@/components/InfoMessage"; import InfoMessage, { clearMessage } from "@/components/InfoMessage";
import { useZones } from "@/hooks/useZones"; import { useZones } from "@/hooks/useZones";
import { editZone } from "@/server/editZone"; import { editZone } from "@/server/editZone";
import { useRouter } from "@/utils/navigation"; import { useRouter } from "@/utils/routing";
import { ZoneForm, ZoneFormValues } from "../../components/ZoneForm"; import { ZoneForm, ZoneFormValues } from "../../components/ZoneForm";
+1 -1
View File
@@ -12,7 +12,7 @@ import { Spinner } from "@/components/Spinner";
import { useZones } from "@/hooks/useZones"; import { useZones } from "@/hooks/useZones";
import { deleteZone } from "@/server/deleteZone"; import { deleteZone } from "@/server/deleteZone";
import { TimeControl } from "@/types"; import { TimeControl } from "@/types";
import { Link, useRouter } from "@/utils/navigation"; import { Link, useRouter } from "@/utils/routing";
const ZoneThumbnail = dynamic(() => import("./components/ZoneThumbnail"), { const ZoneThumbnail = dynamic(() => import("./components/ZoneThumbnail"), {
ssr: false, ssr: false,
+1 -1
View File
@@ -6,7 +6,7 @@ import { HiUserGroup } from "react-icons/hi2";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
import bannerImage from "@/img/banner.jpeg"; import bannerImage from "@/img/banner.jpeg";
import { Link } from "@/utils/navigation"; import { Link } from "@/utils/routing";
export default function Home() { export default function Home() {
const t = useTranslations("Home"); const t = useTranslations("Home");
+16 -14
View File
@@ -1,28 +1,30 @@
import { MetadataRoute } from "next"; import { MetadataRoute } from "next";
import { locales, pathnames } from "@/utils/navigation"; import { Pathnames, routing } from "@/utils/routing";
export default function sitemap(): MetadataRoute.Sitemap { export default function sitemap(): MetadataRoute.Sitemap {
return locales.flatMap((locale) => { return routing.locales.flatMap((locale) => {
const prefix = `https://echecsfrance.com${ const prefix = `https://echecsfrance.com${
locale === "fr" ? "" : `/${locale}` locale === "fr" ? "" : `/${locale}`
}`; }`;
const paths = Object.keys(pathnames) as Array<keyof typeof pathnames>; const paths = Object.keys(routing.pathnames) as Array<Pathnames>;
return paths
.filter((pathname) => !pathname.includes("["))
.map((pathname) => {
const route = routing.pathnames[pathname];
if (typeof route === "string") {
return {
url: `${prefix}${route}`,
lastModified: new Date(),
};
}
return paths.map((pathname) => {
const route = pathnames[pathname];
if (typeof route === "string") {
return { return {
url: `${prefix}${route}`, url: `${prefix}${route[locale]}`,
lastModified: new Date(), lastModified: new Date(),
}; };
} });
return {
url: `${prefix}${route[locale]}`,
lastModified: new Date(),
};
});
}); });
} }
+1 -1
View File
@@ -13,7 +13,7 @@ import { regionFilterAtom } from "@/atoms";
import { BaseOption, Select, SelectProps } from "@/components/form/Select"; import { BaseOption, Select, SelectProps } from "@/components/form/Select";
import { useZones } from "@/hooks/useZones"; import { useZones } from "@/hooks/useZones";
import { Zone } from "@/server/myZones"; import { Zone } from "@/server/myZones";
import { useRouter } from "@/utils/navigation"; import { useRouter } from "@/utils/routing";
type RegionSelectProps = Omit< type RegionSelectProps = Omit<
SelectProps<false, string, Zone | null>, SelectProps<false, string, Zone | null>,
+8 -5
View File
@@ -4,14 +4,14 @@ import { useEffect, useState } from "react";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { signIn } from "next-auth/react"; import { signIn } from "next-auth/react";
import { useLocale, useTranslations } from "next-intl"; import { useTranslations } from "next-intl";
import { usePathname as useRawPathname } from "next/navigation";
import { FormProvider, useForm } from "react-hook-form"; import { FormProvider, useForm } from "react-hook-form";
import { z } from "zod"; import { z } from "zod";
import { clearMessage } from "@/components/InfoMessage"; import { clearMessage } from "@/components/InfoMessage";
import InfoMessage from "@/components/InfoMessage"; import InfoMessage from "@/components/InfoMessage";
import { TextField } from "@/components/form/TextField"; import { TextField } from "@/components/form/TextField";
import { usePathname } from "@/utils/navigation";
const signInSchema = z.object({ const signInSchema = z.object({
email: z.string().email(), email: z.string().email(),
@@ -25,14 +25,17 @@ type SignInFormProps = {
export const SignInForm = ({ callbackPath }: SignInFormProps) => { export const SignInForm = ({ callbackPath }: SignInFormProps) => {
const t = useTranslations("SignIn"); const t = useTranslations("SignIn");
const locale = useLocale();
const path = usePathname(); // We use the version from next/navigation to get the raw pathname in the current locale
const path = useRawPathname();
const [responseMessage, setResponseMessage] = useState({ const [responseMessage, setResponseMessage] = useState({
isSuccessful: false, isSuccessful: false,
message: "", message: "",
}); });
console.log(path);
const form = useForm<SignInFormValues>({ const form = useForm<SignInFormValues>({
resolver: zodResolver(signInSchema), resolver: zodResolver(signInSchema),
}); });
@@ -54,7 +57,7 @@ export const SignInForm = ({ callbackPath }: SignInFormProps) => {
const result = await signIn("nodemailer", { const result = await signIn("nodemailer", {
email, email,
redirect: false, redirect: false,
callbackUrl: callbackPath ?? `/${locale}/${path}`, callbackUrl: callbackPath ?? path,
}); });
if (result?.error) { if (result?.error) {
+4
View File
@@ -1,8 +1,11 @@
import { useQuery } from "@tanstack/react-query"; import { useQuery } from "@tanstack/react-query";
import { useSession } from "next-auth/react";
import { myZones } from "@/server/myZones"; import { myZones } from "@/server/myZones";
export const useZones = () => { export const useZones = () => {
const { status } = useSession();
const query = useQuery({ const query = useQuery({
queryKey: ["zones"], queryKey: ["zones"],
queryFn: async () => myZones(), queryFn: async () => myZones(),
@@ -10,6 +13,7 @@ export const useZones = () => {
staleTime: Infinity, staleTime: Infinity,
gcTime: 10 * 60 * 1000, gcTime: 10 * 60 * 1000,
retry: false, retry: false,
enabled: status === "authenticated",
}); });
return { return {
+1 -1
View File
@@ -1,7 +1,7 @@
import { getRequestConfig } from "next-intl/server"; import { getRequestConfig } from "next-intl/server";
import { notFound } from "next/navigation"; import { notFound } from "next/navigation";
import { routing } from "./utils/navigation"; import { routing } from "./utils/routing";
export default getRequestConfig(async ({ locale }) => { export default getRequestConfig(async ({ locale }) => {
// Validate that the incoming `locale` parameter is valid // Validate that the incoming `locale` parameter is valid
+1 -1
View File
@@ -1,6 +1,6 @@
import createMiddleware from "next-intl/middleware"; import createMiddleware from "next-intl/middleware";
import { routing } from "@/utils/navigation"; import { routing } from "@/utils/routing";
export default createMiddleware(routing); export default createMiddleware(routing);
+2 -4
View File
@@ -40,7 +40,7 @@ export function html(params: {
<tr> <tr>
<td align="center" <td align="center"
style="padding: 10px 0px; font-size: 22px; font-family: Helvetica, Arial, sans-serif; color: ${color.text};"> style="padding: 10px 0px; font-size: 22px; font-family: Helvetica, Arial, sans-serif; color: ${color.text};">
${t("email.subject", { host })} ${t("email.subject", { host: escapedHost })}
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -144,12 +144,10 @@ export default function Nodemailer(
const t = await getTranslations({ locale, namespace: "SignIn" }); const t = await getTranslations({ locale, namespace: "SignIn" });
console.log("Connection URL", url);
const { host } = new URL(url); const { host } = new URL(url);
console.log(config);
if (!(config.server as unknown as any)?.host) { if (!(config.server as unknown as any)?.host) {
console.log("Connection URL", url);
console.log(text({ url, host, t })); console.log(text({ url, host, t }));
return; return;
} }
View File
@@ -1,10 +1,8 @@
import { createLocalizedPathnamesNavigation } from "next-intl/navigation"; import { createLocalizedPathnamesNavigation } from "next-intl/navigation";
import { defineRouting } from "next-intl/routing"; import { defineRouting } from "next-intl/routing";
export const locales = ["fr", "en"] as const;
export const routing = defineRouting({ export const routing = defineRouting({
locales, locales: ["fr", "en"],
defaultLocale: "fr", defaultLocale: "fr",
localePrefix: "as-needed", localePrefix: "as-needed",