mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-12 07:24:51 +00:00
client side i18n
This commit is contained in:
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
)}
|
)}
|
||||||
@@ -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" });
|
||||||
|
|
||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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: "/",
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user