diff --git a/src/app/[locale]/(main)/auth/sign-in/page.tsx b/src/app/[locale]/(main)/auth/sign-in/page.tsx index 5c6381f..518937a 100644 --- a/src/app/[locale]/(main)/auth/sign-in/page.tsx +++ b/src/app/[locale]/(main)/auth/sign-in/page.tsx @@ -1,13 +1,27 @@ "use client"; -import { useTranslations } from "next-intl"; +import { useLocale, useTranslations } from "next-intl"; import { useSearchParams } from "next/navigation"; import { SignInForm } from "@/components/SignInForm"; +import { Locale, getPathname, routing } from "@/utils/routing"; export default function SignIn() { const t = useTranslations("SignIn"); const params = useSearchParams(); + const locale = useLocale(); + + const allowedLocales = routing.locales as unknown as Array; + const effectiveLocal = allowedLocales.includes(locale) + ? (locale as Locale) + : routing.defaultLocale; + + const fallbackPath = getPathname({ + locale: effectiveLocal, + href: { pathname: "/tournaments" }, + }); + + const fallbackUrl = `/${effectiveLocal}${fallbackPath}`; return (
@@ -22,9 +36,7 @@ export default function SignIn() { {t("info")}

- +
); diff --git a/src/app/[locale]/(main)/components/Footer.tsx b/src/app/[locale]/(main)/components/Footer.tsx index b3abf1b..7b6a92a 100644 --- a/src/app/[locale]/(main)/components/Footer.tsx +++ b/src/app/[locale]/(main)/components/Footer.tsx @@ -7,7 +7,7 @@ import { FaGithub, FaRegEnvelope } from "react-icons/fa"; import { MdOutlinePrivacyTip } from "react-icons/md"; import { burgerMenuIsOpenAtom } from "@/atoms"; -import { Link, usePathname, useRouter } from "@/utils/navigation"; +import { Link, usePathname, useRouter } from "@/utils/routing"; import ThemeSwitcher from "./ThemeSwitcher"; diff --git a/src/app/[locale]/(main)/components/HamburgerMenu.tsx b/src/app/[locale]/(main)/components/HamburgerMenu.tsx index d2e4522..0e54385 100644 --- a/src/app/[locale]/(main)/components/HamburgerMenu.tsx +++ b/src/app/[locale]/(main)/components/HamburgerMenu.tsx @@ -4,7 +4,7 @@ import { twMerge } from "tailwind-merge"; import { burgerMenuIsOpenAtom } from "@/atoms"; import { useAuthMenuOptions } from "@/hooks/useAuthMenuOptions"; -import { Link } from "@/utils/navigation"; +import { Link } from "@/utils/routing"; const HamburgerMenu = () => { const t = useTranslations("Nav"); diff --git a/src/app/[locale]/(main)/components/Navbar.tsx b/src/app/[locale]/(main)/components/Navbar.tsx index e54af04..1fc75b6 100644 --- a/src/app/[locale]/(main)/components/Navbar.tsx +++ b/src/app/[locale]/(main)/components/Navbar.tsx @@ -1,7 +1,7 @@ import { useTranslations } from "next-intl"; import AuthButton from "@/components/AuthButton"; -import { Link } from "@/utils/navigation"; +import { Link } from "@/utils/routing"; import Hamburger from "./Hamburger"; diff --git a/src/app/[locale]/(main)/delete-account/page.tsx b/src/app/[locale]/(main)/delete-account/page.tsx index de4bf38..cb3405b 100644 --- a/src/app/[locale]/(main)/delete-account/page.tsx +++ b/src/app/[locale]/(main)/delete-account/page.tsx @@ -7,7 +7,7 @@ import { useTranslations } from "next-intl"; import InfoMessage from "@/components/InfoMessage"; import { deleteAccount } from "@/server/deleteAccount"; -import { useRouter } from "@/utils/navigation"; +import { useRouter } from "@/utils/routing"; export default function Contact() { const t = useTranslations("DeleteAccount"); diff --git a/src/app/[locale]/(main)/elo/page.tsx b/src/app/[locale]/(main)/elo/page.tsx index 377537e..35437fe 100644 --- a/src/app/[locale]/(main)/elo/page.tsx +++ b/src/app/[locale]/(main)/elo/page.tsx @@ -19,7 +19,7 @@ import { fetchTournamentResultsSchema } from "@/schemas"; import { fetchTournamentResults } from "@/server/fetchTournamentResults"; import { SearchedTournament } from "@/server/searchTournaments"; import { TimeControl } from "@/types"; -import { Link } from "@/utils/navigation"; +import { Link } from "@/utils/routing"; import { KFactor } from "./KFactor"; import { ManualEloForm } from "./ManualEloForm"; diff --git a/src/app/[locale]/(main)/tournaments/TournamentMap.tsx b/src/app/[locale]/(main)/tournaments/TournamentMap.tsx index c98ed28..6fbea42 100644 --- a/src/app/[locale]/(main)/tournaments/TournamentMap.tsx +++ b/src/app/[locale]/(main)/tournaments/TournamentMap.tsx @@ -16,8 +16,8 @@ import { } from "@/atoms"; import { Map, MapMarker } from "@/components/Map"; import { TimeControlColours } from "@/constants"; -import { generatePieSVG } from "@/lib/pie"; import { TimeControl } from "@/types"; +import { generatePieSVG } from "@/utils/pie"; import Legend from "./Legend"; import TimeControlFilters from "./TimeControlFilters"; diff --git a/src/app/[locale]/(main)/zones/create/page.tsx b/src/app/[locale]/(main)/zones/create/page.tsx index 9d9ac64..592e540 100644 --- a/src/app/[locale]/(main)/zones/create/page.tsx +++ b/src/app/[locale]/(main)/zones/create/page.tsx @@ -7,7 +7,7 @@ import { useTranslations } from "next-intl"; import InfoMessage, { clearMessage } from "@/components/InfoMessage"; import { useZones } from "@/hooks/useZones"; import { createZone } from "@/server/createZone"; -import { useRouter } from "@/utils/navigation"; +import { useRouter } from "@/utils/routing"; import { ZoneForm, ZoneFormValues } from "../components/ZoneForm"; diff --git a/src/app/[locale]/(main)/zones/edit/[id]/page.tsx b/src/app/[locale]/(main)/zones/edit/[id]/page.tsx index 132ab94..1c15ab5 100644 --- a/src/app/[locale]/(main)/zones/edit/[id]/page.tsx +++ b/src/app/[locale]/(main)/zones/edit/[id]/page.tsx @@ -8,7 +8,7 @@ import { useParams } from "next/navigation"; import InfoMessage, { clearMessage } from "@/components/InfoMessage"; import { useZones } from "@/hooks/useZones"; import { editZone } from "@/server/editZone"; -import { useRouter } from "@/utils/navigation"; +import { useRouter } from "@/utils/routing"; import { ZoneForm, ZoneFormValues } from "../../components/ZoneForm"; diff --git a/src/app/[locale]/(main)/zones/page.tsx b/src/app/[locale]/(main)/zones/page.tsx index 7ee4427..447e003 100644 --- a/src/app/[locale]/(main)/zones/page.tsx +++ b/src/app/[locale]/(main)/zones/page.tsx @@ -12,7 +12,7 @@ import { Spinner } from "@/components/Spinner"; import { useZones } from "@/hooks/useZones"; import { deleteZone } from "@/server/deleteZone"; import { TimeControl } from "@/types"; -import { Link, useRouter } from "@/utils/navigation"; +import { Link, useRouter } from "@/utils/routing"; const ZoneThumbnail = dynamic(() => import("./components/ZoneThumbnail"), { ssr: false, diff --git a/src/app/[locale]/page.tsx b/src/app/[locale]/page.tsx index d5ec540..c27e956 100644 --- a/src/app/[locale]/page.tsx +++ b/src/app/[locale]/page.tsx @@ -6,7 +6,7 @@ import { HiUserGroup } from "react-icons/hi2"; import { twMerge } from "tailwind-merge"; import bannerImage from "@/img/banner.jpeg"; -import { Link } from "@/utils/navigation"; +import { Link } from "@/utils/routing"; export default function Home() { const t = useTranslations("Home"); diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts index ab83e49..72687a0 100644 --- a/src/app/sitemap.ts +++ b/src/app/sitemap.ts @@ -1,28 +1,30 @@ import { MetadataRoute } from "next"; -import { locales, pathnames } from "@/utils/navigation"; +import { Pathnames, routing } from "@/utils/routing"; export default function sitemap(): MetadataRoute.Sitemap { - return locales.flatMap((locale) => { + return routing.locales.flatMap((locale) => { const prefix = `https://echecsfrance.com${ locale === "fr" ? "" : `/${locale}` }`; - const paths = Object.keys(pathnames) as Array; + const paths = Object.keys(routing.pathnames) as Array; + + 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 { - url: `${prefix}${route}`, + url: `${prefix}${route[locale]}`, lastModified: new Date(), }; - } - - return { - url: `${prefix}${route[locale]}`, - lastModified: new Date(), - }; - }); + }); }); } diff --git a/src/components/RegionSelect.tsx b/src/components/RegionSelect.tsx index d7f4e2b..1147bcd 100644 --- a/src/components/RegionSelect.tsx +++ b/src/components/RegionSelect.tsx @@ -13,7 +13,7 @@ import { regionFilterAtom } from "@/atoms"; import { BaseOption, Select, SelectProps } from "@/components/form/Select"; import { useZones } from "@/hooks/useZones"; import { Zone } from "@/server/myZones"; -import { useRouter } from "@/utils/navigation"; +import { useRouter } from "@/utils/routing"; type RegionSelectProps = Omit< SelectProps, diff --git a/src/components/SignInForm.tsx b/src/components/SignInForm.tsx index 4c608ac..564d2eb 100644 --- a/src/components/SignInForm.tsx +++ b/src/components/SignInForm.tsx @@ -4,14 +4,14 @@ import { useEffect, useState } from "react"; import { zodResolver } from "@hookform/resolvers/zod"; 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 { z } from "zod"; import { clearMessage } from "@/components/InfoMessage"; import InfoMessage from "@/components/InfoMessage"; import { TextField } from "@/components/form/TextField"; -import { usePathname } from "@/utils/navigation"; const signInSchema = z.object({ email: z.string().email(), @@ -25,14 +25,17 @@ type SignInFormProps = { export const SignInForm = ({ callbackPath }: SignInFormProps) => { 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({ isSuccessful: false, message: "", }); + console.log(path); + const form = useForm({ resolver: zodResolver(signInSchema), }); @@ -54,7 +57,7 @@ export const SignInForm = ({ callbackPath }: SignInFormProps) => { const result = await signIn("nodemailer", { email, redirect: false, - callbackUrl: callbackPath ?? `/${locale}/${path}`, + callbackUrl: callbackPath ?? path, }); if (result?.error) { diff --git a/src/hooks/useZones.ts b/src/hooks/useZones.ts index 3e3baf1..c7a519e 100644 --- a/src/hooks/useZones.ts +++ b/src/hooks/useZones.ts @@ -1,8 +1,11 @@ import { useQuery } from "@tanstack/react-query"; +import { useSession } from "next-auth/react"; import { myZones } from "@/server/myZones"; export const useZones = () => { + const { status } = useSession(); + const query = useQuery({ queryKey: ["zones"], queryFn: async () => myZones(), @@ -10,6 +13,7 @@ export const useZones = () => { staleTime: Infinity, gcTime: 10 * 60 * 1000, retry: false, + enabled: status === "authenticated", }); return { diff --git a/src/i18n.ts b/src/i18n.ts index aa556aa..1800915 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -1,7 +1,7 @@ import { getRequestConfig } from "next-intl/server"; import { notFound } from "next/navigation"; -import { routing } from "./utils/navigation"; +import { routing } from "./utils/routing"; export default getRequestConfig(async ({ locale }) => { // Validate that the incoming `locale` parameter is valid diff --git a/src/middleware.ts b/src/middleware.ts index 0b1ab88..2188de0 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,6 +1,6 @@ import createMiddleware from "next-intl/middleware"; -import { routing } from "@/utils/navigation"; +import { routing } from "@/utils/routing"; export default createMiddleware(routing); diff --git a/src/utils/nodemailerProvider.ts b/src/utils/nodemailerProvider.ts index 1f98bfc..1802f87 100644 --- a/src/utils/nodemailerProvider.ts +++ b/src/utils/nodemailerProvider.ts @@ -40,7 +40,7 @@ export function html(params: { - ${t("email.subject", { host })} + ${t("email.subject", { host: escapedHost })} @@ -144,12 +144,10 @@ export default function Nodemailer( const t = await getTranslations({ locale, namespace: "SignIn" }); - console.log("Connection URL", url); - const { host } = new URL(url); - console.log(config); if (!(config.server as unknown as any)?.host) { + console.log("Connection URL", url); console.log(text({ url, host, t })); return; } diff --git a/src/lib/pie.ts b/src/utils/pie.ts similarity index 100% rename from src/lib/pie.ts rename to src/utils/pie.ts diff --git a/src/utils/navigation.ts b/src/utils/routing.ts similarity index 95% rename from src/utils/navigation.ts rename to src/utils/routing.ts index a038cf7..b6f2d39 100644 --- a/src/utils/navigation.ts +++ b/src/utils/routing.ts @@ -1,10 +1,8 @@ import { createLocalizedPathnamesNavigation } from "next-intl/navigation"; import { defineRouting } from "next-intl/routing"; -export const locales = ["fr", "en"] as const; - export const routing = defineRouting({ - locales, + locales: ["fr", "en"], defaultLocale: "fr", localePrefix: "as-needed",