client side i18n

This commit is contained in:
peintnermax
2024-10-09 10:31:10 +02:00
parent f2262666fb
commit 9633853bf0
32 changed files with 46 additions and 37 deletions

View File

@@ -2,5 +2,9 @@
"loginname": {
"title": "Willkommen zurück!",
"description": "Geben Sie Ihre Anmeldedaten ein."
},
"idp": {
"signInWithApple": "Mit Apple anmelden",
"signInWithGoogle": "Mit Google anmelden"
}
}

View File

@@ -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"
}
}

View File

@@ -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({
<GlobalNav />
) : (
<div className="absolute bottom-0 right-0 flex flex-row p-4 items-center space-x-4">
{/*<LanguageSwitcher locale={locale} /> */}
<LanguageSwitcher locale={`${locale}`} />
<Theme />
</div>
)}

View File

@@ -23,7 +23,6 @@ export default async function Page({
}: {
searchParams: Record<string | number | symbol, string | undefined>;
}) {
// const t = useTranslations("loginname");
const locale = getLocale();
const t = await getTranslations({ locale, namespace: "loginname" });

View File

@@ -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 (
<BaseButton {...restProps} ref={ref}>
<div className="h-12 w-12 flex items-center justify-center">
@@ -21,7 +24,7 @@ export const SignInWithApple = forwardRef<
{children ? (
children
) : (
<span className="ml-4">{name ? name : "Sign in with Apple"}</span>
<span className="ml-4">{name ? name : t("signInWithApple")}</span>
)}
</BaseButton>
);

View File

@@ -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 (
<BaseButton {...restProps} ref={ref}>
<div className="h-12 p-[10px] w-12 flex items-center justify-center">
@@ -27,7 +30,7 @@ export const SignInWithAzureAd = forwardRef<
{children ? (
children
) : (
<span className="ml-4">{name ? name : "Sign in with AzureAD"}</span>
<span className="ml-4">{name ? name : t("signInWithAzureAD")}</span>
)}
</BaseButton>
);

View File

@@ -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 (
<BaseButton {...restProps} ref={ref}>
<div className="mx-2 my-2 flex items-center justify-center">
@@ -41,7 +44,7 @@ export const SignInWithGithub = forwardRef<
{children ? (
children
) : (
<span className="ml-4">{name ? name : "Sign in with GitHub"}</span>
<span className="ml-4">{name ? name : t("signInWithGithub")}</span>
)}
</BaseButton>
);

View File

@@ -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 (
<BaseButton {...restProps} ref={ref}>
<div className="h-12 w-12 flex items-center justify-center">
@@ -38,7 +41,7 @@ export const SignInWithGitlab = forwardRef<
{children ? (
children
) : (
<span className="ml-4">{name ? name : "Sign in with GitLab"}</span>
<span className="ml-4">{name ? name : t("signInWithGitlab")}</span>
)}
</BaseButton>
);

View File

@@ -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 (
<BaseButton {...restProps} ref={ref}>
<div className="h-12 w-12 flex items-center justify-center">
@@ -51,7 +54,7 @@ export const SignInWithGoogle = forwardRef<
{children ? (
children
) : (
<span className="ml-4">{name ? name : "Sign in with Google"}</span>
<span className="ml-4">{name ? name : t("signInWithGoogle")}</span>
)}
</BaseButton>
);

View File

@@ -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();

View File

@@ -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<Inputs>({
mode: "onBlur",
defaultValues: {
@@ -96,7 +98,7 @@ export function UsernameForm({
type="button"
disabled={loading}
>
Register new user
{t("registerButton")}
</button>
)}
</div>

View File

@@ -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,

View File

@@ -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: "/",
});