translated component

This commit is contained in:
Max Peintner
2025-06-19 14:39:52 +02:00
parent 3cb8729f20
commit ef8931a17c
20 changed files with 85 additions and 89 deletions

View File

@@ -2,7 +2,7 @@
import { Boundary } from "@/components/boundary"; import { Boundary } from "@/components/boundary";
import { Button } from "@/components/button"; import { Button } from "@/components/button";
import { useTranslations } from "next-intl"; import { Translated } from "@/components/translated";
import { useEffect } from "react"; import { useEffect } from "react";
export default function Error({ error, reset }: any) { export default function Error({ error, reset }: any) {
@@ -10,8 +10,6 @@ export default function Error({ error, reset }: any) {
console.log("logging error:", error); console.log("logging error:", error);
}, [error]); }, [error]);
const t = useTranslations("error");
return ( return (
<Boundary labels={["Login Error"]} color="red"> <Boundary labels={["Login Error"]} color="red">
<div className="space-y-4"> <div className="space-y-4">
@@ -20,7 +18,7 @@ export default function Error({ error, reset }: any) {
</div> </div>
<div> <div>
<Button data-i18n-key="error.tryagain" onClick={() => reset()}> <Button data-i18n-key="error.tryagain" onClick={() => reset()}>
{t("tryagain")} <Translated i18nKey="tryagain" namespace="error" />
</Button> </Button>
</div> </div>
</div> </div>

View File

@@ -3,7 +3,7 @@
import { Boundary } from "@/components/boundary"; import { Boundary } from "@/components/boundary";
import { Button } from "@/components/button"; import { Button } from "@/components/button";
import { ThemeWrapper } from "@/components/theme-wrapper"; import { ThemeWrapper } from "@/components/theme-wrapper";
import { useTranslations } from "next-intl"; import { Translated } from "@/components/translated";
export default function GlobalError({ export default function GlobalError({
error, error,
@@ -12,8 +12,6 @@ export default function GlobalError({
error: Error & { digest?: string }; error: Error & { digest?: string };
reset: () => void; reset: () => void;
}) { }) {
const t = useTranslations("error");
return ( return (
// global-error must include html and body tags // global-error must include html and body tags
<html> <html>
@@ -26,7 +24,7 @@ export default function GlobalError({
</div> </div>
<div> <div>
<Button data-i18n-key="error.tryagain" onClick={() => reset()}> <Button data-i18n-key="error.tryagain" onClick={() => reset()}>
{t("tryagain")} <Translated i18nKey="tryagain" namespace="error" />
</Button> </Button>
</div> </div>
</div> </div>

View File

@@ -13,7 +13,6 @@ import {
import { create } from "@zitadel/client"; import { create } from "@zitadel/client";
import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb"; import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb"; import { PasswordComplexitySettings } from "@zitadel/proto/zitadel/settings/v2/password_settings_pb";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { FieldValues, useForm } from "react-hook-form"; import { FieldValues, useForm } from "react-hook-form";
@@ -23,6 +22,7 @@ import { Button, ButtonVariants } from "./button";
import { TextInput } from "./input"; import { TextInput } from "./input";
import { PasswordComplexity } from "./password-complexity"; import { PasswordComplexity } from "./password-complexity";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
type Inputs = type Inputs =
| { | {
@@ -46,7 +46,6 @@ export function ChangePasswordForm({
requestId, requestId,
organization, organization,
}: Props) { }: Props) {
const t = useTranslations("password");
const router = useRouter(); const router = useRouter();
const { register, handleSubmit, watch, formState } = useForm<Inputs>({ const { register, handleSubmit, watch, formState } = useForm<Inputs>({
@@ -203,8 +202,8 @@ export function ChangePasswordForm({
onClick={handleSubmit(submitChange)} onClick={handleSubmit(submitChange)}
data-testid="submit-button" data-testid="submit-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
{t("change.submit")} <Translated i18nKey="change.submit" namespace="password" />
</Button> </Button>
</div> </div>
</form> </form>

View File

@@ -3,9 +3,9 @@ import {
PasskeysType, PasskeysType,
} from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { useTranslations } from "next-intl";
import { Alert, AlertType } from "./alert"; import { Alert, AlertType } from "./alert";
import { PASSKEYS, PASSWORD } from "./auth-methods"; import { PASSKEYS, PASSWORD } from "./auth-methods";
import { Translated } from "./translated";
type Props = { type Props = {
authMethods: AuthenticationMethodType[]; authMethods: AuthenticationMethodType[];
@@ -18,16 +18,23 @@ export function ChooseAuthenticatorToSetup({
params, params,
loginSettings, loginSettings,
}: Props) { }: Props) {
const t = useTranslations("authenticator");
if (authMethods.length !== 0) { if (authMethods.length !== 0) {
return <Alert type={AlertType.ALERT}>{t("allSetup")}</Alert>; return (
<Alert type={AlertType.ALERT}>
<Translated i18nKey="allSetup" namespace="authenticator" />
</Alert>
);
} else { } else {
return ( return (
<> <>
{loginSettings.passkeysType == PasskeysType.NOT_ALLOWED && {loginSettings.passkeysType == PasskeysType.NOT_ALLOWED &&
!loginSettings.allowUsernamePassword && ( !loginSettings.allowUsernamePassword && (
<Alert type={AlertType.ALERT}>{t("noMethodsAvailable")}</Alert> <Alert type={AlertType.ALERT}>
<Translated
i18nKey="noMethodsAvailable"
namespace="authenticator"
/>
</Alert>
)} )}
<div className="grid grid-cols-1 gap-5 w-full pt-4"> <div className="grid grid-cols-1 gap-5 w-full pt-4">

View File

@@ -6,9 +6,9 @@ import {
SecondFactorType, SecondFactorType,
} from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { AuthenticationMethodType } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { EMAIL, SMS, TOTP, U2F } from "./auth-methods"; import { EMAIL, SMS, TOTP, U2F } from "./auth-methods";
import { Translated } from "./translated";
type Props = { type Props = {
userId: string; userId: string;
@@ -37,7 +37,6 @@ export function ChooseSecondFactorToSetup({
emailVerified, emailVerified,
force, force,
}: Props) { }: Props) {
const t = useTranslations("mfa");
const router = useRouter(); const router = useRouter();
const params = new URLSearchParams({}); const params = new URLSearchParams({});
@@ -112,7 +111,7 @@ export function ChooseSecondFactorToSetup({
type="button" type="button"
data-testid="reset-button" data-testid="reset-button"
> >
{t("set.skip")} <Translated i18nKey="set.skip" namespace="mfa" />
</button> </button>
)} )}
</> </>

View File

@@ -8,6 +8,7 @@ import { useState } from "react";
import { Alert } from "./alert"; import { Alert } from "./alert";
import { Button, ButtonVariants } from "./button"; import { Button, ButtonVariants } from "./button";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
export function ConsentScreen({ export function ConsentScreen({
scope, scope,
@@ -50,7 +51,7 @@ export function ConsentScreen({
<ul className="list-disc space-y-2 w-full"> <ul className="list-disc space-y-2 w-full">
{scopes?.length === 0 && ( {scopes?.length === 0 && (
<span className="w-full text-sm flex flex-row items-center bg-background-light-400 dark:bg-background-dark-400 border border-divider-light py-2 px-4 rounded-md transition-all"> <span className="w-full text-sm flex flex-row items-center bg-background-light-400 dark:bg-background-dark-400 border border-divider-light py-2 px-4 rounded-md transition-all">
{t("device.scope.openid")} <Translated i18nKey="device.scope.openid" namespace="device" />
</span> </span>
)} )}
{scopes?.map((s) => { {scopes?.map((s) => {
@@ -91,7 +92,7 @@ export function ConsentScreen({
data-testid="deny-button" data-testid="deny-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}
{t("device.request.deny")} <Translated i18nKey="device.request.deny" namespace="device" />
</Button> </Button>
<span className="flex-grow"></span> <span className="flex-grow"></span>
@@ -102,7 +103,7 @@ export function ConsentScreen({
className="self-end" className="self-end"
variant={ButtonVariants.Primary} variant={ButtonVariants.Primary}
> >
{t("device.request.submit")} <Translated i18nKey="device.request.submit" namespace="device" />
</Button> </Button>
</Link> </Link>
</div> </div>

View File

@@ -2,7 +2,6 @@
import { Alert } from "@/components/alert"; import { Alert } from "@/components/alert";
import { getDeviceAuthorizationRequest } from "@/lib/server/oidc"; import { getDeviceAuthorizationRequest } from "@/lib/server/oidc";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
@@ -10,14 +9,13 @@ import { BackButton } from "./back-button";
import { Button, ButtonVariants } from "./button"; import { Button, ButtonVariants } from "./button";
import { TextInput } from "./input"; import { TextInput } from "./input";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
type Inputs = { type Inputs = {
userCode: string; userCode: string;
}; };
export function DeviceCodeForm({ userCode }: { userCode?: string }) { export function DeviceCodeForm({ userCode }: { userCode?: string }) {
const t = useTranslations("verify");
const router = useRouter(); const router = useRouter();
const { register, handleSubmit, formState } = useForm<Inputs>({ const { register, handleSubmit, formState } = useForm<Inputs>({
@@ -87,8 +85,8 @@ export function DeviceCodeForm({ userCode }: { userCode?: string }) {
onClick={handleSubmit(submitCodeAndContinue)} onClick={handleSubmit(submitCodeAndContinue)}
data-testid="submit-button" data-testid="submit-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
{t("verify.submit")} <Translated i18nKey="verify.submit" namespace="verify" />
</Button> </Button>
</div> </div>
</form> </form>

View File

@@ -6,7 +6,6 @@ import { create } from "@zitadel/client";
import { RequestChallengesSchema } from "@zitadel/proto/zitadel/session/v2/challenge_pb"; import { RequestChallengesSchema } from "@zitadel/proto/zitadel/session/v2/challenge_pb";
import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb"; import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
@@ -15,6 +14,7 @@ import { BackButton } from "./back-button";
import { Button, ButtonVariants } from "./button"; import { Button, ButtonVariants } from "./button";
import { TextInput } from "./input"; import { TextInput } from "./input";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
// either loginName or sessionId must be provided // either loginName or sessionId must be provided
type Props = { type Props = {
@@ -42,8 +42,6 @@ export function LoginOTP({
code, code,
loginSettings, loginSettings,
}: Props) { }: Props) {
const t = useTranslations("otp");
const [error, setError] = useState<string>(""); const [error, setError] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
@@ -223,7 +221,7 @@ export function LoginOTP({
<Alert type={AlertType.INFO}> <Alert type={AlertType.INFO}>
<div className="flex flex-row"> <div className="flex flex-row">
<span className="flex-1 mr-auto text-left"> <span className="flex-1 mr-auto text-left">
{t("verify.noCodeReceived")} <Translated i18nKey="verify.noCodeReceived" namespace="otp" />
</span> </span>
<button <button
aria-label="Resend OTP Code" aria-label="Resend OTP Code"
@@ -243,7 +241,7 @@ export function LoginOTP({
}} }}
data-testid="resend-button" data-testid="resend-button"
> >
{t("verify.resendCode")} <Translated i18nKey="verify.resendCode" namespace="otp" />
</button> </button>
</div> </div>
</Alert> </Alert>
@@ -277,8 +275,8 @@ export function LoginOTP({
})} })}
data-testid="submit-button" data-testid="submit-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
{t("verify.submit")} <Translated i18nKey="verify.submit" namespace="otp" />
</Button> </Button>
</div> </div>
</form> </form>

View File

@@ -9,13 +9,13 @@ import {
UserVerificationRequirement, UserVerificationRequirement,
} from "@zitadel/proto/zitadel/session/v2/challenge_pb"; } from "@zitadel/proto/zitadel/session/v2/challenge_pb";
import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb"; import { Checks } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useEffect, useRef, useState } from "react"; import { useEffect, useRef, useState } from "react";
import { Alert } from "./alert"; import { Alert } from "./alert";
import { BackButton } from "./back-button"; import { BackButton } from "./back-button";
import { Button, ButtonVariants } from "./button"; import { Button, ButtonVariants } from "./button";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
// either loginName or sessionId must be provided // either loginName or sessionId must be provided
type Props = { type Props = {
@@ -35,8 +35,6 @@ export function LoginPasskey({
organization, organization,
login = true, login = true,
}: Props) { }: Props) {
const t = useTranslations("passkey");
const [error, setError] = useState<string>(""); const [error, setError] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
@@ -234,7 +232,7 @@ export function LoginPasskey({
}} }}
data-testid="password-button" data-testid="password-button"
> >
{t("verify.usePassword")} <Translated i18nKey="verify.usePassword" namespace="passkey" />
</Button> </Button>
) : ( ) : (
<BackButton /> <BackButton />
@@ -273,8 +271,8 @@ export function LoginPasskey({
}} }}
data-testid="submit-button" data-testid="submit-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
{t("verify.submit")} <Translated i18nKey="verify.submit" namespace="passkey" />
</Button> </Button>
</div> </div>
</div> </div>

View File

@@ -4,7 +4,6 @@ import { resetPassword, sendPassword } from "@/lib/server/password";
import { create } from "@zitadel/client"; import { create } from "@zitadel/client";
import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb"; import { ChecksSchema } from "@zitadel/proto/zitadel/session/v2/session_service_pb";
import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
@@ -13,6 +12,7 @@ import { BackButton } from "./back-button";
import { Button, ButtonVariants } from "./button"; import { Button, ButtonVariants } from "./button";
import { TextInput } from "./input"; import { TextInput } from "./input";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
type Inputs = { type Inputs = {
password: string; password: string;
@@ -35,8 +35,6 @@ export function PasswordForm({
promptPasswordless, promptPasswordless,
isAlternative, isAlternative,
}: Props) { }: Props) {
const t = useTranslations("password");
const { register, handleSubmit, formState } = useForm<Inputs>({ const { register, handleSubmit, formState } = useForm<Inputs>({
mode: "onBlur", mode: "onBlur",
}); });
@@ -136,7 +134,7 @@ export function PasswordForm({
disabled={loading} disabled={loading}
data-testid="reset-button" data-testid="reset-button"
> >
{t("verify.resetPassword")} <Translated i18nKey="verify.resetPassword" namespace="password" />
</button> </button>
)} )}
@@ -173,8 +171,8 @@ export function PasswordForm({
onClick={handleSubmit(submitPassword)} onClick={handleSubmit(submitPassword)}
data-testid="submit-button" data-testid="submit-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
{t("verify.submit")} <Translated i18nKey="verify.submit" namespace="password" />
</Button> </Button>
</div> </div>
</form> </form>

View File

@@ -1,9 +1,9 @@
"use client"; "use client";
import { LegalAndSupportSettings } from "@zitadel/proto/zitadel/settings/v2/legal_settings_pb"; import { LegalAndSupportSettings } from "@zitadel/proto/zitadel/settings/v2/legal_settings_pb";
import { useTranslations } from "next-intl";
import Link from "next/link"; import Link from "next/link";
import { useState } from "react"; import { useState } from "react";
import { Checkbox } from "./checkbox"; import { Checkbox } from "./checkbox";
import { Translated } from "./translated";
type Props = { type Props = {
legal: LegalAndSupportSettings; legal: LegalAndSupportSettings;
@@ -16,7 +16,6 @@ type AcceptanceState = {
}; };
export function PrivacyPolicyCheckboxes({ legal, onChange }: Props) { export function PrivacyPolicyCheckboxes({ legal, onChange }: Props) {
const t = useTranslations("register");
const [acceptanceState, setAcceptanceState] = useState<AcceptanceState>({ const [acceptanceState, setAcceptanceState] = useState<AcceptanceState>({
tosAccepted: false, tosAccepted: false,
privacyPolicyAccepted: false, privacyPolicyAccepted: false,
@@ -25,7 +24,7 @@ export function PrivacyPolicyCheckboxes({ legal, onChange }: Props) {
return ( return (
<> <>
<p className="flex flex-row items-center text-text-light-secondary-500 dark:text-text-dark-secondary-500 mt-4 text-sm"> <p className="flex flex-row items-center text-text-light-secondary-500 dark:text-text-dark-secondary-500 mt-4 text-sm">
{t("agreeTo")} <Translated i18nKey="agreeTo" namespace="register" />
{legal?.helpLink && ( {legal?.helpLink && (
<span> <span>
<Link href={legal.helpLink} target="_blank"> <Link href={legal.helpLink} target="_blank">
@@ -66,7 +65,7 @@ export function PrivacyPolicyCheckboxes({ legal, onChange }: Props) {
<div className="mr-4 w-[28rem]"> <div className="mr-4 w-[28rem]">
<p className="text-sm text-text-light-500 dark:text-text-dark-500"> <p className="text-sm text-text-light-500 dark:text-text-dark-500">
<Link href={legal.tosLink} className="underline" target="_blank"> <Link href={legal.tosLink} className="underline" target="_blank">
{t("termsOfService")} <Translated i18nKey="termsOfService" namespace="register" />
</Link> </Link>
</p> </p>
</div> </div>
@@ -95,7 +94,7 @@ export function PrivacyPolicyCheckboxes({ legal, onChange }: Props) {
className="underline" className="underline"
target="_blank" target="_blank"
> >
{t("privacyPolicy")} <Translated i18nKey="privacyPolicy" namespace="register" />
</Link> </Link>
</p> </p>
</div> </div>

View File

@@ -1,7 +1,6 @@
"use client"; "use client";
import { registerUserAndLinkToIDP } from "@/lib/server/register"; import { registerUserAndLinkToIDP } from "@/lib/server/register";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { FieldValues, useForm } from "react-hook-form"; import { FieldValues, useForm } from "react-hook-form";
@@ -10,6 +9,7 @@ import { BackButton } from "./back-button";
import { Button, ButtonVariants } from "./button"; import { Button, ButtonVariants } from "./button";
import { TextInput } from "./input"; import { TextInput } from "./input";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
type Inputs = type Inputs =
| { | {
@@ -45,8 +45,6 @@ export function RegisterFormIDPIncomplete({
idpId, idpId,
idpUserName, idpUserName,
}: Props) { }: Props) {
const t = useTranslations("register");
const { register, handleSubmit, formState } = useForm<Inputs>({ const { register, handleSubmit, formState } = useForm<Inputs>({
mode: "onBlur", mode: "onBlur",
defaultValues: { defaultValues: {
@@ -149,8 +147,8 @@ export function RegisterFormIDPIncomplete({
onClick={handleSubmit(submitAndRegister)} onClick={handleSubmit(submitAndRegister)}
data-testid="submit-button" data-testid="submit-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
{t("submit")} <Translated i18nKey="submit" namespace="register" />
</Button> </Button>
</div> </div>
</form> </form>

View File

@@ -6,7 +6,6 @@ import {
LoginSettings, LoginSettings,
PasskeysType, PasskeysType,
} from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { FieldValues, useForm } from "react-hook-form"; import { FieldValues, useForm } from "react-hook-form";
@@ -21,6 +20,7 @@ import { Button, ButtonVariants } from "./button";
import { TextInput } from "./input"; import { TextInput } from "./input";
import { PrivacyPolicyCheckboxes } from "./privacy-policy-checkboxes"; import { PrivacyPolicyCheckboxes } from "./privacy-policy-checkboxes";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
type Inputs = type Inputs =
| { | {
@@ -51,8 +51,6 @@ export function RegisterForm({
loginSettings, loginSettings,
idpCount = 0, idpCount = 0,
}: Props) { }: Props) {
const t = useTranslations("register");
const { register, handleSubmit, formState } = useForm<Inputs>({ const { register, handleSubmit, formState } = useForm<Inputs>({
mode: "onBlur", mode: "onBlur",
defaultValues: { defaultValues: {
@@ -173,7 +171,7 @@ export function RegisterForm({
loginSettings.passkeysType == PasskeysType.ALLOWED && ( loginSettings.passkeysType == PasskeysType.ALLOWED && (
<> <>
<p className="mt-4 ztdl-p mb-6 block text-left"> <p className="mt-4 ztdl-p mb-6 block text-left">
{t("selectMethod")} <Translated i18nKey="selectMethod" namespace="register" />
</p> </p>
<div className="pb-4"> <div className="pb-4">
@@ -184,12 +182,16 @@ export function RegisterForm({
</div> </div>
</> </>
)} )}
{!loginSettings?.allowUsernamePassword && {!loginSettings?.allowUsernamePassword &&
loginSettings?.passkeysType != PasskeysType.ALLOWED && loginSettings?.passkeysType !== PasskeysType.ALLOWED &&
(!loginSettings?.allowExternalIdp || !idpCount) && ( (!loginSettings?.allowExternalIdp || !idpCount) && (
<div className="py-4"> <div className="py-4">
<Alert type={AlertType.INFO}>{t("noMethodAvailableWarning")}</Alert> <Alert type={AlertType.INFO}>
<Translated
i18nKey="noMethodAvailableWarning"
namespace="register"
/>
</Alert>
</div> </div>
)} )}
@@ -217,7 +219,7 @@ export function RegisterForm({
data-testid="submit-button" data-testid="submit-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}
{t("submit")} <Translated i18nKey="submit" namespace="register" />
</Button> </Button>
</div> </div>
</form> </form>

View File

@@ -5,7 +5,6 @@ import {
registerPasskeyLink, registerPasskeyLink,
verifyPasskeyRegistration, verifyPasskeyRegistration,
} from "@/lib/server/passkeys"; } from "@/lib/server/passkeys";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
@@ -13,6 +12,7 @@ import { Alert } from "./alert";
import { BackButton } from "./back-button"; import { BackButton } from "./back-button";
import { Button, ButtonVariants } from "./button"; import { Button, ButtonVariants } from "./button";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
type Inputs = {}; type Inputs = {};
@@ -29,8 +29,6 @@ export function RegisterPasskey({
organization, organization,
requestId, requestId,
}: Props) { }: Props) {
const t = useTranslations("passkey");
const { handleSubmit, formState } = useForm<Inputs>({ const { handleSubmit, formState } = useForm<Inputs>({
mode: "onBlur", mode: "onBlur",
}); });
@@ -198,7 +196,7 @@ export function RegisterPasskey({
continueAndLogin(); continueAndLogin();
}} }}
> >
{t("set.skip")} <Translated i18nKey="set.skip" namespace="passkey" />
</Button> </Button>
) : ( ) : (
<BackButton /> <BackButton />
@@ -213,8 +211,8 @@ export function RegisterPasskey({
onClick={handleSubmit(submitRegisterAndContinue)} onClick={handleSubmit(submitRegisterAndContinue)}
data-testid="submit-button" data-testid="submit-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
{t("set.submit")} <Translated i18nKey="set.submit" namespace="passkey" />
</Button> </Button>
</div> </div>
</form> </form>

View File

@@ -5,13 +5,13 @@ import { getNextUrl } from "@/lib/client";
import { addU2F, verifyU2F } from "@/lib/server/u2f"; import { addU2F, verifyU2F } from "@/lib/server/u2f";
import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb"; import { LoginSettings } from "@zitadel/proto/zitadel/settings/v2/login_settings_pb";
import { RegisterU2FResponse } from "@zitadel/proto/zitadel/user/v2/user_service_pb"; import { RegisterU2FResponse } from "@zitadel/proto/zitadel/user/v2/user_service_pb";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { Alert } from "./alert"; import { Alert } from "./alert";
import { BackButton } from "./back-button"; import { BackButton } from "./back-button";
import { Button, ButtonVariants } from "./button"; import { Button, ButtonVariants } from "./button";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
type Props = { type Props = {
loginName?: string; loginName?: string;
@@ -30,8 +30,6 @@ export function RegisterU2f({
checkAfter, checkAfter,
loginSettings, loginSettings,
}: Props) { }: Props) {
const t = useTranslations("u2f");
const [error, setError] = useState<string>(""); const [error, setError] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false); const [loading, setLoading] = useState<boolean>(false);
@@ -218,8 +216,8 @@ export function RegisterU2f({
onClick={submitRegisterAndContinue} onClick={submitRegisterAndContinue}
data-testid="submit-button" data-testid="submit-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
{t("set.submit")} <Translated i18nKey="set.submit" namespace="u2f" />
</Button> </Button>
</div> </div>
</form> </form>

View File

@@ -9,6 +9,7 @@ import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { Avatar } from "./avatar"; import { Avatar } from "./avatar";
import { isSessionValid } from "./session-item"; import { isSessionValid } from "./session-item";
import { Translated } from "./translated";
export function SessionClearItem({ export function SessionClearItem({
session, session,
@@ -89,7 +90,7 @@ export function SessionClearItem({
<span className="flex-grow"></span> <span className="flex-grow"></span>
<div className="relative flex flex-row items-center"> <div className="relative flex flex-row items-center">
<div className="mr-6 px-2 py-[2px] text-xs hidden group-hover:block transition-all text-warn-light-500 dark:text-warn-dark-500 bg-[#ff0000]/10 dark:bg-[#ff0000]/10 rounded-full flex items-center justify-center"> <div className="mr-6 px-2 py-[2px] text-xs hidden group-hover:block transition-all text-warn-light-500 dark:text-warn-dark-500 bg-[#ff0000]/10 dark:bg-[#ff0000]/10 rounded-full flex items-center justify-center">
{t("clear")} <Translated i18nKey="clear" namespace="logout" />
</div> </div>
{valid ? ( {valid ? (

View File

@@ -3,11 +3,11 @@
import { clearSession } from "@/lib/server/session"; import { clearSession } from "@/lib/server/session";
import { timestampDate } from "@zitadel/client"; import { timestampDate } from "@zitadel/client";
import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb"; import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { useTranslations } from "next-intl";
import { redirect, useRouter } from "next/navigation"; import { redirect, useRouter } from "next/navigation";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Alert, AlertType } from "./alert"; import { Alert, AlertType } from "./alert";
import { SessionClearItem } from "./session-clear-item"; import { SessionClearItem } from "./session-clear-item";
import { Translated } from "./translated";
type Props = { type Props = {
sessions: Session[]; sessions: Session[];
@@ -22,7 +22,6 @@ export function SessionsClearList({
postLogoutRedirectUri, postLogoutRedirectUri,
organization, organization,
}: Props) { }: Props) {
const t = useTranslations("logout");
const [list, setList] = useState<Session[]>(sessions); const [list, setList] = useState<Session[]>(sessions);
const router = useRouter(); const router = useRouter();
@@ -97,10 +96,14 @@ export function SessionsClearList({
); );
})} })}
{list.length === 0 && ( {list.length === 0 && (
<Alert type={AlertType.INFO}>{t("noResults")}</Alert> <Alert type={AlertType.INFO}>
<Translated i18nKey="noResults" namespace="logout" />
</Alert>
)} )}
</div> </div>
) : ( ) : (
<Alert>{t("noResults")}</Alert> <Alert>
<Translated i18nKey="noResults" namespace="logout" />
</Alert>
); );
} }

View File

@@ -2,10 +2,10 @@
import { timestampDate } from "@zitadel/client"; import { timestampDate } from "@zitadel/client";
import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb"; import { Session } from "@zitadel/proto/zitadel/session/v2/session_pb";
import { useTranslations } from "next-intl";
import { useState } from "react"; import { useState } from "react";
import { Alert } from "./alert"; import { Alert } from "./alert";
import { SessionItem } from "./session-item"; import { SessionItem } from "./session-item";
import { Translated } from "./translated";
type Props = { type Props = {
sessions: Session[]; sessions: Session[];
@@ -13,7 +13,6 @@ type Props = {
}; };
export function SessionsList({ sessions, requestId }: Props) { export function SessionsList({ sessions, requestId }: Props) {
const t = useTranslations("accounts");
const [list, setList] = useState<Session[]>(sessions); const [list, setList] = useState<Session[]>(sessions);
return sessions ? ( return sessions ? (
<div className="flex flex-col space-y-2"> <div className="flex flex-col space-y-2">
@@ -44,6 +43,8 @@ export function SessionsList({ sessions, requestId }: Props) {
})} })}
</div> </div>
) : ( ) : (
<Alert>{t("noResults")}</Alert> <Alert>
<Translated i18nKey="noResults" namespace="accounts" />
</Alert>
); );
} }

View File

@@ -24,6 +24,7 @@ import { Button, ButtonVariants } from "./button";
import { TextInput } from "./input"; import { TextInput } from "./input";
import { PasswordComplexity } from "./password-complexity"; import { PasswordComplexity } from "./password-complexity";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
type Inputs = type Inputs =
| { | {
@@ -207,7 +208,7 @@ export function SetPasswordForm({
}} }}
data-testid="resend-button" data-testid="resend-button"
> >
{t("set.resend")} <Translated i18nKey="set.resend" namespace="password" />
</button> </button>
</div> </div>
</Alert> </Alert>
@@ -279,8 +280,8 @@ export function SetPasswordForm({
onClick={handleSubmit(submitPassword)} onClick={handleSubmit(submitPassword)}
data-testid="submit-button" data-testid="submit-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
{t("set.submit")} <Translated i18nKey="set.submit" namespace="password" />
</Button> </Button>
</div> </div>
</form> </form>

View File

@@ -18,6 +18,7 @@ import { Button, ButtonVariants } from "./button";
import { TextInput } from "./input"; import { TextInput } from "./input";
import { PasswordComplexity } from "./password-complexity"; import { PasswordComplexity } from "./password-complexity";
import { Spinner } from "./spinner"; import { Spinner } from "./spinner";
import { Translated } from "./translated";
type Inputs = type Inputs =
| { | {
@@ -163,8 +164,8 @@ export function SetRegisterPasswordForm({
onClick={handleSubmit(submitRegister)} onClick={handleSubmit(submitRegister)}
data-testid="submit-button" data-testid="submit-button"
> >
{loading && <Spinner className="h-5 w-5 mr-2" />} {loading && <Spinner className="h-5 w-5 mr-2" />}{" "}
{t("password.submit")} <Translated i18nKey="password.submit" namespace="register" />
</Button> </Button>
</div> </div>
</form> </form>