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": { "loginname": {
"title": "Willkommen zurück!", "title": "Willkommen zurück!",
"description": "Geben Sie Ihre Anmeldedaten ein." "description": "Geben Sie Ihre Anmeldedaten ein."
},
"idp": {
"signInWithApple": "Mit Apple anmelden",
"signInWithGoogle": "Mit Google anmelden"
} }
} }

View File

@@ -1,6 +1,14 @@
{ {
"loginname": { "loginname": {
"title": "Welcome back!", "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 { AddressBar } from "@/components/address-bar";
import { GlobalNav } from "@/components/global-nav"; import { GlobalNav } from "@/components/global-nav";
import { LanguageSwitcher } from "@/components/language-switcher";
import { Theme } from "@/components/theme"; import { Theme } from "@/components/theme";
import { ThemeProvider } from "@/components/theme-provider"; import { ThemeProvider } from "@/components/theme-provider";
import { Analytics } from "@vercel/analytics/react"; import { Analytics } from "@vercel/analytics/react";
@@ -22,7 +23,8 @@ export default async function RootLayout({
}: { }: {
children: ReactNode; children: ReactNode;
}) { }) {
const locale = await getLocale(); const locale = (await getLocale()) ?? "en";
const messages = await getMessages(); const messages = await getMessages();
// later only shown with dev mode enabled // later only shown with dev mode enabled
@@ -52,7 +54,7 @@ export default async function RootLayout({
<GlobalNav /> <GlobalNav />
) : ( ) : (
<div className="absolute bottom-0 right-0 flex flex-row p-4 items-center space-x-4"> <div className="absolute bottom-0 right-0 flex flex-row p-4 items-center space-x-4">
{/*<LanguageSwitcher locale={locale} /> */} <LanguageSwitcher locale={`${locale}`} />
<Theme /> <Theme />
</div> </div>
)} )}

View File

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

View File

@@ -1,5 +1,6 @@
"use client"; "use client";
import { useTranslations } from "next-intl";
import { forwardRef } from "react"; import { forwardRef } from "react";
import { BaseButton, SignInWithIdentityProviderProps } from "./base-button"; import { BaseButton, SignInWithIdentityProviderProps } from "./base-button";
@@ -8,6 +9,8 @@ export const SignInWithApple = forwardRef<
SignInWithIdentityProviderProps SignInWithIdentityProviderProps
>(function SignInWithApple(props, ref) { >(function SignInWithApple(props, ref) {
const { children, name, ...restProps } = props; const { children, name, ...restProps } = props;
const t = useTranslations("idp");
return ( return (
<BaseButton {...restProps} ref={ref}> <BaseButton {...restProps} ref={ref}>
<div className="h-12 w-12 flex items-center justify-center"> <div className="h-12 w-12 flex items-center justify-center">
@@ -21,7 +24,7 @@ export const SignInWithApple = forwardRef<
{children ? ( {children ? (
children children
) : ( ) : (
<span className="ml-4">{name ? name : "Sign in with Apple"}</span> <span className="ml-4">{name ? name : t("signInWithApple")}</span>
)} )}
</BaseButton> </BaseButton>
); );

View File

@@ -1,5 +1,6 @@
"use client"; "use client";
import { useTranslations } from "next-intl";
import { forwardRef } from "react"; import { forwardRef } from "react";
import { BaseButton, SignInWithIdentityProviderProps } from "./base-button"; import { BaseButton, SignInWithIdentityProviderProps } from "./base-button";
@@ -8,6 +9,8 @@ export const SignInWithAzureAd = forwardRef<
SignInWithIdentityProviderProps SignInWithIdentityProviderProps
>(function SignInWithAzureAd(props, ref) { >(function SignInWithAzureAd(props, ref) {
const { children, name, ...restProps } = props; const { children, name, ...restProps } = props;
const t = useTranslations("idp");
return ( return (
<BaseButton {...restProps} ref={ref}> <BaseButton {...restProps} ref={ref}>
<div className="h-12 p-[10px] w-12 flex items-center justify-center"> <div className="h-12 p-[10px] w-12 flex items-center justify-center">
@@ -27,7 +30,7 @@ export const SignInWithAzureAd = forwardRef<
{children ? ( {children ? (
children children
) : ( ) : (
<span className="ml-4">{name ? name : "Sign in with AzureAD"}</span> <span className="ml-4">{name ? name : t("signInWithAzureAD")}</span>
)} )}
</BaseButton> </BaseButton>
); );

View File

@@ -1,5 +1,6 @@
"use client"; "use client";
import { useTranslations } from "next-intl";
import { forwardRef } from "react"; import { forwardRef } from "react";
import { BaseButton, SignInWithIdentityProviderProps } from "./base-button"; import { BaseButton, SignInWithIdentityProviderProps } from "./base-button";
@@ -8,6 +9,8 @@ export const SignInWithGithub = forwardRef<
SignInWithIdentityProviderProps SignInWithIdentityProviderProps
>(function SignInWithGithub(props, ref) { >(function SignInWithGithub(props, ref) {
const { children, name, ...restProps } = props; const { children, name, ...restProps } = props;
const t = useTranslations("idp");
return ( return (
<BaseButton {...restProps} ref={ref}> <BaseButton {...restProps} ref={ref}>
<div className="mx-2 my-2 flex items-center justify-center"> <div className="mx-2 my-2 flex items-center justify-center">
@@ -41,7 +44,7 @@ export const SignInWithGithub = forwardRef<
{children ? ( {children ? (
children children
) : ( ) : (
<span className="ml-4">{name ? name : "Sign in with GitHub"}</span> <span className="ml-4">{name ? name : t("signInWithGithub")}</span>
)} )}
</BaseButton> </BaseButton>
); );

View File

@@ -1,5 +1,6 @@
"use client"; "use client";
import { useTranslations } from "next-intl";
import { forwardRef } from "react"; import { forwardRef } from "react";
import { BaseButton, SignInWithIdentityProviderProps } from "./base-button"; import { BaseButton, SignInWithIdentityProviderProps } from "./base-button";
@@ -8,6 +9,8 @@ export const SignInWithGitlab = forwardRef<
SignInWithIdentityProviderProps SignInWithIdentityProviderProps
>(function SignInWithGitlab(props, ref) { >(function SignInWithGitlab(props, ref) {
const { children, name, ...restProps } = props; const { children, name, ...restProps } = props;
const t = useTranslations("idp");
return ( return (
<BaseButton {...restProps} ref={ref}> <BaseButton {...restProps} ref={ref}>
<div className="h-12 w-12 flex items-center justify-center"> <div className="h-12 w-12 flex items-center justify-center">
@@ -38,7 +41,7 @@ export const SignInWithGitlab = forwardRef<
{children ? ( {children ? (
children children
) : ( ) : (
<span className="ml-4">{name ? name : "Sign in with GitLab"}</span> <span className="ml-4">{name ? name : t("signInWithGitlab")}</span>
)} )}
</BaseButton> </BaseButton>
); );

View File

@@ -1,5 +1,6 @@
"use client"; "use client";
import { useTranslations } from "next-intl";
import { forwardRef } from "react"; import { forwardRef } from "react";
import { BaseButton, SignInWithIdentityProviderProps } from "./base-button"; import { BaseButton, SignInWithIdentityProviderProps } from "./base-button";
@@ -8,6 +9,8 @@ export const SignInWithGoogle = forwardRef<
SignInWithIdentityProviderProps SignInWithIdentityProviderProps
>(function SignInWithGoogle(props, ref) { >(function SignInWithGoogle(props, ref) {
const { children, name, ...restProps } = props; const { children, name, ...restProps } = props;
const t = useTranslations("idp");
return ( return (
<BaseButton {...restProps} ref={ref}> <BaseButton {...restProps} ref={ref}>
<div className="h-12 w-12 flex items-center justify-center"> <div className="h-12 w-12 flex items-center justify-center">
@@ -51,7 +54,7 @@ export const SignInWithGoogle = forwardRef<
{children ? ( {children ? (
children children
) : ( ) : (
<span className="ml-4">{name ? name : "Sign in with Google"}</span> <span className="ml-4">{name ? name : t("signInWithGoogle")}</span>
)} )}
</BaseButton> </BaseButton>
); );

View File

@@ -9,8 +9,7 @@ import {
Transition, Transition,
} from "@headlessui/react"; } from "@headlessui/react";
import { CheckIcon, ChevronUpDownIcon } from "@heroicons/react/24/outline"; import { CheckIcon, ChevronUpDownIcon } from "@heroicons/react/24/outline";
import { useTranslations } from "next-intl"; import { useRouter } from "next/navigation";
import { usePathname, useRouter } from "next/navigation";
import { Fragment, useState } from "react"; import { Fragment, useState } from "react";
interface Lang { interface Lang {
@@ -46,37 +45,18 @@ type Props = {
}; };
export function LanguageSwitcher({ locale }: Props) { export function LanguageSwitcher({ locale }: Props) {
const { i18n } = useTranslations(); const currentLocale = locale || "en";
const currentLocale = locale || i18n.language || "en";
const [selected, setSelected] = useState( const [selected, setSelected] = useState(
LANGS.find((l) => l.code === currentLocale) || LANGS[0], LANGS.find((l) => l.code === currentLocale) || LANGS[0],
); );
const router = useRouter(); const router = useRouter();
const currentPathname = usePathname();
const handleChange = async (language: Lang) => { const handleChange = async (language: Lang) => {
setSelected(language); setSelected(language);
const newLocale = language.code; 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); await setLanguageCookie(newLocale);
router.refresh(); router.refresh();

View File

@@ -1,6 +1,7 @@
"use client"; "use client";
import { sendLoginname } from "@/lib/server/loginname"; import { sendLoginname } from "@/lib/server/loginname";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { ReactNode, useEffect, useState } from "react"; import { ReactNode, useEffect, useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
@@ -31,6 +32,7 @@ export function UsernameForm({
allowRegister, allowRegister,
children, children,
}: Props) { }: Props) {
const t = useTranslations("loginname");
const { register, handleSubmit, formState } = useForm<Inputs>({ const { register, handleSubmit, formState } = useForm<Inputs>({
mode: "onBlur", mode: "onBlur",
defaultValues: { defaultValues: {
@@ -96,7 +98,7 @@ export function UsernameForm({
type="button" type="button"
disabled={loading} disabled={loading}
> >
Register new user {t("registerButton")}
</button> </button>
)} )}
</div> </div>

View File

@@ -2,11 +2,10 @@ import { getRequestConfig } from "next-intl/server";
import { cookies } from "next/headers"; import { cookies } from "next/headers";
export default getRequestConfig(async () => { export default getRequestConfig(async () => {
// Provide a static locale, fetch a user setting,
// read from `cookies()`, `headers()`, etc.
const cookiesList = cookies(); 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 { return {
locale, locale,

View File

@@ -31,7 +31,7 @@ export async function setLanguageCookie(language: string) {
// @ts-ignore // @ts-ignore
return cookiesList.set({ return cookiesList.set({
name: "NEXT_LOCALE", name: "NEXT_LOCALE",
value: JSON.stringify(language), value: language,
httpOnly: true, httpOnly: true,
path: "/", path: "/",
}); });