From 9633853bf0b78d83ed912c228dfe4fec8ef7ba13 Mon Sep 17 00:00:00 2001 From: peintnermax Date: Wed, 9 Oct 2024 10:31:10 +0200 Subject: [PATCH] client side i18n --- apps/login/locales/de.json | 4 ++++ apps/login/locales/en.json | 10 +++++++- .../src/app/{ => (login)}/accounts/page.tsx | 0 .../idp/[provider]/failure/page.tsx | 0 .../idp/[provider]/success/page.tsx | 0 apps/login/src/app/{ => (login)}/idp/page.tsx | 0 apps/login/src/app/{ => (login)}/layout.tsx | 6 +++-- .../src/app/{ => (login)}/loginname/page.tsx | 1 - .../{ => (login)}/me/change-password/page.tsx | 0 apps/login/src/app/{ => (login)}/mfa/page.tsx | 0 .../src/app/{ => (login)}/mfa/set/page.tsx | 0 .../app/{ => (login)}/otp/[method]/page.tsx | 0 .../{ => (login)}/otp/[method]/set/page.tsx | 0 .../src/app/{ => (login)}/overview/page.tsx | 0 apps/login/src/app/{ => (login)}/page.tsx | 0 .../src/app/{ => (login)}/passkey/page.tsx | 0 .../app/{ => (login)}/passkey/set/page.tsx | 0 .../src/app/{ => (login)}/password/page.tsx | 0 .../src/app/{ => (login)}/register/page.tsx | 0 .../src/app/{ => (login)}/signedin/page.tsx | 0 apps/login/src/app/{ => (login)}/u2f/page.tsx | 0 .../src/app/{ => (login)}/u2f/set/page.tsx | 0 .../src/app/{ => (login)}/verify/page.tsx | 0 .../components/idps/sign-in-with-apple.tsx | 5 +++- .../components/idps/sign-in-with-azure-ad.tsx | 5 +++- .../components/idps/sign-in-with-github.tsx | 5 +++- .../components/idps/sign-in-with-gitlab.tsx | 5 +++- .../components/idps/sign-in-with-google.tsx | 5 +++- .../src/components/language-switcher.tsx | 24 ++----------------- apps/login/src/components/username-form.tsx | 4 +++- apps/login/src/i18n/request.ts | 7 +++--- apps/login/src/lib/cookies.ts | 2 +- 32 files changed, 46 insertions(+), 37 deletions(-) rename apps/login/src/app/{ => (login)}/accounts/page.tsx (100%) rename apps/login/src/app/{ => (login)}/idp/[provider]/failure/page.tsx (100%) rename apps/login/src/app/{ => (login)}/idp/[provider]/success/page.tsx (100%) rename apps/login/src/app/{ => (login)}/idp/page.tsx (100%) rename apps/login/src/app/{ => (login)}/layout.tsx (93%) rename apps/login/src/app/{ => (login)}/loginname/page.tsx (98%) rename apps/login/src/app/{ => (login)}/me/change-password/page.tsx (100%) rename apps/login/src/app/{ => (login)}/mfa/page.tsx (100%) rename apps/login/src/app/{ => (login)}/mfa/set/page.tsx (100%) rename apps/login/src/app/{ => (login)}/otp/[method]/page.tsx (100%) rename apps/login/src/app/{ => (login)}/otp/[method]/set/page.tsx (100%) rename apps/login/src/app/{ => (login)}/overview/page.tsx (100%) rename apps/login/src/app/{ => (login)}/page.tsx (100%) rename apps/login/src/app/{ => (login)}/passkey/page.tsx (100%) rename apps/login/src/app/{ => (login)}/passkey/set/page.tsx (100%) rename apps/login/src/app/{ => (login)}/password/page.tsx (100%) rename apps/login/src/app/{ => (login)}/register/page.tsx (100%) rename apps/login/src/app/{ => (login)}/signedin/page.tsx (100%) rename apps/login/src/app/{ => (login)}/u2f/page.tsx (100%) rename apps/login/src/app/{ => (login)}/u2f/set/page.tsx (100%) rename apps/login/src/app/{ => (login)}/verify/page.tsx (100%) diff --git a/apps/login/locales/de.json b/apps/login/locales/de.json index 50bbb084d72..40b532fa4aa 100644 --- a/apps/login/locales/de.json +++ b/apps/login/locales/de.json @@ -2,5 +2,9 @@ "loginname": { "title": "Willkommen zurück!", "description": "Geben Sie Ihre Anmeldedaten ein." + }, + "idp": { + "signInWithApple": "Mit Apple anmelden", + "signInWithGoogle": "Mit Google anmelden" } } diff --git a/apps/login/locales/en.json b/apps/login/locales/en.json index a783dc0154e..b7f739055da 100644 --- a/apps/login/locales/en.json +++ b/apps/login/locales/en.json @@ -1,6 +1,14 @@ { "loginname": { "title": "Welcome back!", - "description": "Enter your login data." + "description": "Enter your login data.", + "registerButton": "Register new user" + }, + "idp": { + "signInWithApple": "Sign in with Apple", + "signInWithGoogle": "Sign in with Google", + "signInWithAzureAD": "Sign in with AzureAD", + "signInWithGithub": "Sign in with GitHub", + "signInWithGitlab": "Sign in with GitLab" } } diff --git a/apps/login/src/app/accounts/page.tsx b/apps/login/src/app/(login)/accounts/page.tsx similarity index 100% rename from apps/login/src/app/accounts/page.tsx rename to apps/login/src/app/(login)/accounts/page.tsx diff --git a/apps/login/src/app/idp/[provider]/failure/page.tsx b/apps/login/src/app/(login)/idp/[provider]/failure/page.tsx similarity index 100% rename from apps/login/src/app/idp/[provider]/failure/page.tsx rename to apps/login/src/app/(login)/idp/[provider]/failure/page.tsx diff --git a/apps/login/src/app/idp/[provider]/success/page.tsx b/apps/login/src/app/(login)/idp/[provider]/success/page.tsx similarity index 100% rename from apps/login/src/app/idp/[provider]/success/page.tsx rename to apps/login/src/app/(login)/idp/[provider]/success/page.tsx diff --git a/apps/login/src/app/idp/page.tsx b/apps/login/src/app/(login)/idp/page.tsx similarity index 100% rename from apps/login/src/app/idp/page.tsx rename to apps/login/src/app/(login)/idp/page.tsx diff --git a/apps/login/src/app/layout.tsx b/apps/login/src/app/(login)/layout.tsx similarity index 93% rename from apps/login/src/app/layout.tsx rename to apps/login/src/app/(login)/layout.tsx index bf5e7a052bd..e3f54f235b6 100644 --- a/apps/login/src/app/layout.tsx +++ b/apps/login/src/app/(login)/layout.tsx @@ -2,6 +2,7 @@ import "@/styles/globals.scss"; import { AddressBar } from "@/components/address-bar"; import { GlobalNav } from "@/components/global-nav"; +import { LanguageSwitcher } from "@/components/language-switcher"; import { Theme } from "@/components/theme"; import { ThemeProvider } from "@/components/theme-provider"; import { Analytics } from "@vercel/analytics/react"; @@ -22,7 +23,8 @@ export default async function RootLayout({ }: { children: ReactNode; }) { - const locale = await getLocale(); + const locale = (await getLocale()) ?? "en"; + const messages = await getMessages(); // later only shown with dev mode enabled @@ -52,7 +54,7 @@ export default async function RootLayout({ ) : (
- {/* */} +
)} diff --git a/apps/login/src/app/loginname/page.tsx b/apps/login/src/app/(login)/loginname/page.tsx similarity index 98% rename from apps/login/src/app/loginname/page.tsx rename to apps/login/src/app/(login)/loginname/page.tsx index 196323b4f86..928bf1389dd 100644 --- a/apps/login/src/app/loginname/page.tsx +++ b/apps/login/src/app/(login)/loginname/page.tsx @@ -23,7 +23,6 @@ export default async function Page({ }: { searchParams: Record; }) { - // const t = useTranslations("loginname"); const locale = getLocale(); const t = await getTranslations({ locale, namespace: "loginname" }); diff --git a/apps/login/src/app/me/change-password/page.tsx b/apps/login/src/app/(login)/me/change-password/page.tsx similarity index 100% rename from apps/login/src/app/me/change-password/page.tsx rename to apps/login/src/app/(login)/me/change-password/page.tsx diff --git a/apps/login/src/app/mfa/page.tsx b/apps/login/src/app/(login)/mfa/page.tsx similarity index 100% rename from apps/login/src/app/mfa/page.tsx rename to apps/login/src/app/(login)/mfa/page.tsx diff --git a/apps/login/src/app/mfa/set/page.tsx b/apps/login/src/app/(login)/mfa/set/page.tsx similarity index 100% rename from apps/login/src/app/mfa/set/page.tsx rename to apps/login/src/app/(login)/mfa/set/page.tsx diff --git a/apps/login/src/app/otp/[method]/page.tsx b/apps/login/src/app/(login)/otp/[method]/page.tsx similarity index 100% rename from apps/login/src/app/otp/[method]/page.tsx rename to apps/login/src/app/(login)/otp/[method]/page.tsx diff --git a/apps/login/src/app/otp/[method]/set/page.tsx b/apps/login/src/app/(login)/otp/[method]/set/page.tsx similarity index 100% rename from apps/login/src/app/otp/[method]/set/page.tsx rename to apps/login/src/app/(login)/otp/[method]/set/page.tsx diff --git a/apps/login/src/app/overview/page.tsx b/apps/login/src/app/(login)/overview/page.tsx similarity index 100% rename from apps/login/src/app/overview/page.tsx rename to apps/login/src/app/(login)/overview/page.tsx diff --git a/apps/login/src/app/page.tsx b/apps/login/src/app/(login)/page.tsx similarity index 100% rename from apps/login/src/app/page.tsx rename to apps/login/src/app/(login)/page.tsx diff --git a/apps/login/src/app/passkey/page.tsx b/apps/login/src/app/(login)/passkey/page.tsx similarity index 100% rename from apps/login/src/app/passkey/page.tsx rename to apps/login/src/app/(login)/passkey/page.tsx diff --git a/apps/login/src/app/passkey/set/page.tsx b/apps/login/src/app/(login)/passkey/set/page.tsx similarity index 100% rename from apps/login/src/app/passkey/set/page.tsx rename to apps/login/src/app/(login)/passkey/set/page.tsx diff --git a/apps/login/src/app/password/page.tsx b/apps/login/src/app/(login)/password/page.tsx similarity index 100% rename from apps/login/src/app/password/page.tsx rename to apps/login/src/app/(login)/password/page.tsx diff --git a/apps/login/src/app/register/page.tsx b/apps/login/src/app/(login)/register/page.tsx similarity index 100% rename from apps/login/src/app/register/page.tsx rename to apps/login/src/app/(login)/register/page.tsx diff --git a/apps/login/src/app/signedin/page.tsx b/apps/login/src/app/(login)/signedin/page.tsx similarity index 100% rename from apps/login/src/app/signedin/page.tsx rename to apps/login/src/app/(login)/signedin/page.tsx diff --git a/apps/login/src/app/u2f/page.tsx b/apps/login/src/app/(login)/u2f/page.tsx similarity index 100% rename from apps/login/src/app/u2f/page.tsx rename to apps/login/src/app/(login)/u2f/page.tsx diff --git a/apps/login/src/app/u2f/set/page.tsx b/apps/login/src/app/(login)/u2f/set/page.tsx similarity index 100% rename from apps/login/src/app/u2f/set/page.tsx rename to apps/login/src/app/(login)/u2f/set/page.tsx diff --git a/apps/login/src/app/verify/page.tsx b/apps/login/src/app/(login)/verify/page.tsx similarity index 100% rename from apps/login/src/app/verify/page.tsx rename to apps/login/src/app/(login)/verify/page.tsx diff --git a/apps/login/src/components/idps/sign-in-with-apple.tsx b/apps/login/src/components/idps/sign-in-with-apple.tsx index 560c0e61c31..8b9419ae024 100644 --- a/apps/login/src/components/idps/sign-in-with-apple.tsx +++ b/apps/login/src/components/idps/sign-in-with-apple.tsx @@ -1,5 +1,6 @@ "use client"; +import { useTranslations } from "next-intl"; import { forwardRef } from "react"; import { BaseButton, SignInWithIdentityProviderProps } from "./base-button"; @@ -8,6 +9,8 @@ export const SignInWithApple = forwardRef< SignInWithIdentityProviderProps >(function SignInWithApple(props, ref) { const { children, name, ...restProps } = props; + const t = useTranslations("idp"); + return (
@@ -21,7 +24,7 @@ export const SignInWithApple = forwardRef< {children ? ( children ) : ( - {name ? name : "Sign in with Apple"} + {name ? name : t("signInWithApple")} )} ); diff --git a/apps/login/src/components/idps/sign-in-with-azure-ad.tsx b/apps/login/src/components/idps/sign-in-with-azure-ad.tsx index 933604d23e7..a3a4c822725 100644 --- a/apps/login/src/components/idps/sign-in-with-azure-ad.tsx +++ b/apps/login/src/components/idps/sign-in-with-azure-ad.tsx @@ -1,5 +1,6 @@ "use client"; +import { useTranslations } from "next-intl"; import { forwardRef } from "react"; import { BaseButton, SignInWithIdentityProviderProps } from "./base-button"; @@ -8,6 +9,8 @@ export const SignInWithAzureAd = forwardRef< SignInWithIdentityProviderProps >(function SignInWithAzureAd(props, ref) { const { children, name, ...restProps } = props; + const t = useTranslations("idp"); + return (
@@ -27,7 +30,7 @@ export const SignInWithAzureAd = forwardRef< {children ? ( children ) : ( - {name ? name : "Sign in with AzureAD"} + {name ? name : t("signInWithAzureAD")} )} ); diff --git a/apps/login/src/components/idps/sign-in-with-github.tsx b/apps/login/src/components/idps/sign-in-with-github.tsx index 11b9078616d..49b4ce7b266 100644 --- a/apps/login/src/components/idps/sign-in-with-github.tsx +++ b/apps/login/src/components/idps/sign-in-with-github.tsx @@ -1,5 +1,6 @@ "use client"; +import { useTranslations } from "next-intl"; import { forwardRef } from "react"; import { BaseButton, SignInWithIdentityProviderProps } from "./base-button"; @@ -8,6 +9,8 @@ export const SignInWithGithub = forwardRef< SignInWithIdentityProviderProps >(function SignInWithGithub(props, ref) { const { children, name, ...restProps } = props; + const t = useTranslations("idp"); + return (
@@ -41,7 +44,7 @@ export const SignInWithGithub = forwardRef< {children ? ( children ) : ( - {name ? name : "Sign in with GitHub"} + {name ? name : t("signInWithGithub")} )} ); diff --git a/apps/login/src/components/idps/sign-in-with-gitlab.tsx b/apps/login/src/components/idps/sign-in-with-gitlab.tsx index c685cea2abb..8a1ed7d3498 100644 --- a/apps/login/src/components/idps/sign-in-with-gitlab.tsx +++ b/apps/login/src/components/idps/sign-in-with-gitlab.tsx @@ -1,5 +1,6 @@ "use client"; +import { useTranslations } from "next-intl"; import { forwardRef } from "react"; import { BaseButton, SignInWithIdentityProviderProps } from "./base-button"; @@ -8,6 +9,8 @@ export const SignInWithGitlab = forwardRef< SignInWithIdentityProviderProps >(function SignInWithGitlab(props, ref) { const { children, name, ...restProps } = props; + const t = useTranslations("idp"); + return (
@@ -38,7 +41,7 @@ export const SignInWithGitlab = forwardRef< {children ? ( children ) : ( - {name ? name : "Sign in with GitLab"} + {name ? name : t("signInWithGitlab")} )} ); diff --git a/apps/login/src/components/idps/sign-in-with-google.tsx b/apps/login/src/components/idps/sign-in-with-google.tsx index 136e85e62d0..6162ef4a96e 100644 --- a/apps/login/src/components/idps/sign-in-with-google.tsx +++ b/apps/login/src/components/idps/sign-in-with-google.tsx @@ -1,5 +1,6 @@ "use client"; +import { useTranslations } from "next-intl"; import { forwardRef } from "react"; import { BaseButton, SignInWithIdentityProviderProps } from "./base-button"; @@ -8,6 +9,8 @@ export const SignInWithGoogle = forwardRef< SignInWithIdentityProviderProps >(function SignInWithGoogle(props, ref) { const { children, name, ...restProps } = props; + const t = useTranslations("idp"); + return (
@@ -51,7 +54,7 @@ export const SignInWithGoogle = forwardRef< {children ? ( children ) : ( - {name ? name : "Sign in with Google"} + {name ? name : t("signInWithGoogle")} )} ); diff --git a/apps/login/src/components/language-switcher.tsx b/apps/login/src/components/language-switcher.tsx index 3a8657d6b96..92f097998f8 100644 --- a/apps/login/src/components/language-switcher.tsx +++ b/apps/login/src/components/language-switcher.tsx @@ -9,8 +9,7 @@ import { Transition, } from "@headlessui/react"; import { CheckIcon, ChevronUpDownIcon } from "@heroicons/react/24/outline"; -import { useTranslations } from "next-intl"; -import { usePathname, useRouter } from "next/navigation"; +import { useRouter } from "next/navigation"; import { Fragment, useState } from "react"; interface Lang { @@ -46,37 +45,18 @@ type Props = { }; export function LanguageSwitcher({ locale }: Props) { - const { i18n } = useTranslations(); - - const currentLocale = locale || i18n.language || "en"; + const currentLocale = locale || "en"; const [selected, setSelected] = useState( LANGS.find((l) => l.code === currentLocale) || LANGS[0], ); const router = useRouter(); - const currentPathname = usePathname(); const handleChange = async (language: Lang) => { setSelected(language); const newLocale = language.code; - // set cookie - // const days = 30; - // const date = new Date(); - // date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000); - // const expires = date.toUTCString(); - // document.cookie = `NEXT_LOCALE=${newLocale};expires=${expires};path=/`; - - // redirect to the new locale path - // if (currentLocale === "en" /*i18nConfig.defaultLocale*/) { - // router.push("/" + newLocale + currentPathname); - // } else { - // router.push( - // currentPathname.replace(`/${currentLocale}`, `/${newLocale}`), - // ); - // } - await setLanguageCookie(newLocale); router.refresh(); diff --git a/apps/login/src/components/username-form.tsx b/apps/login/src/components/username-form.tsx index 28469cd2018..b67cb5f5cdb 100644 --- a/apps/login/src/components/username-form.tsx +++ b/apps/login/src/components/username-form.tsx @@ -1,6 +1,7 @@ "use client"; import { sendLoginname } from "@/lib/server/loginname"; +import { useTranslations } from "next-intl"; import { useRouter } from "next/navigation"; import { ReactNode, useEffect, useState } from "react"; import { useForm } from "react-hook-form"; @@ -31,6 +32,7 @@ export function UsernameForm({ allowRegister, children, }: Props) { + const t = useTranslations("loginname"); const { register, handleSubmit, formState } = useForm({ mode: "onBlur", defaultValues: { @@ -96,7 +98,7 @@ export function UsernameForm({ type="button" disabled={loading} > - Register new user + {t("registerButton")} )}
diff --git a/apps/login/src/i18n/request.ts b/apps/login/src/i18n/request.ts index 6cb19f91e72..123f52e2a78 100644 --- a/apps/login/src/i18n/request.ts +++ b/apps/login/src/i18n/request.ts @@ -2,11 +2,10 @@ import { getRequestConfig } from "next-intl/server"; import { cookies } from "next/headers"; export default getRequestConfig(async () => { - // Provide a static locale, fetch a user setting, - // read from `cookies()`, `headers()`, etc. - const cookiesList = cookies(); - const locale = cookiesList.get("NEXT_LOCALE")?.value ?? "en"; + const locale: string = cookiesList.get("NEXT_LOCALE")?.value ?? "en"; + + console.log("i18nRequest", locale); return { locale, diff --git a/apps/login/src/lib/cookies.ts b/apps/login/src/lib/cookies.ts index f9c8debf1c9..6ff84c2c77b 100644 --- a/apps/login/src/lib/cookies.ts +++ b/apps/login/src/lib/cookies.ts @@ -31,7 +31,7 @@ export async function setLanguageCookie(language: string) { // @ts-ignore return cookiesList.set({ name: "NEXT_LOCALE", - value: JSON.stringify(language), + value: language, httpOnly: true, path: "/", });