Skip to content

Commit 5e3f222

Browse files
authored
Merge pull request #30 from damienlethiec/feature/add-login-verify-email-page
feat: add themed LoginVerifyEmail page
2 parents 83f47b4 + 6452f5f commit 5e3f222

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

src/login/KcPage.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const Login = lazy(() => import("./pages/Login"));
1313
const Register = lazy(() => import("./pages/Register"));
1414
const LoginUpdateProfile = lazy(() => import("./pages/LoginUpdateProfile"));
1515
const LoginUpdatePassword = lazy(() => import("./pages/LoginUpdatePassword"));
16+
const LoginVerifyEmail = lazy(() => import("./pages/LoginVerifyEmail"));
1617

1718
const doMakeUserConfirmPassword = false;
1819

@@ -77,6 +78,14 @@ export default function KcPage(props: { kcContext: KcContext }) {
7778
doUseDefaultCss={false}
7879
/>
7980
);
81+
case "login-verify-email.ftl":
82+
return (
83+
<LoginVerifyEmail
84+
{...{ kcContext, i18n, classes }}
85+
Template={Template}
86+
doUseDefaultCss={false}
87+
/>
88+
);
8089
default:
8190
return (
8291
<DefaultPage
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import type { Meta, StoryObj } from "@storybook/react";
2+
import { createKcPageStory } from "../KcPageStory";
3+
4+
const { KcPageStory } = createKcPageStory({ pageId: "login-verify-email.ftl" });
5+
6+
const meta = {
7+
title: "login/login-verify-email.ftl",
8+
component: KcPageStory
9+
} satisfies Meta<typeof KcPageStory>;
10+
11+
export default meta;
12+
13+
type Story = StoryObj<typeof meta>;
14+
15+
export const Default: Story = {
16+
render: () => (
17+
<KcPageStory
18+
kcContext={{
19+
user: {
20+
email: "user@example.com"
21+
}
22+
}}
23+
/>
24+
)
25+
};
26+
27+
/**
28+
* WithCustomEmail:
29+
* - Purpose: Tests the page with a specific email address.
30+
* - Scenario: Simulates a user with a custom email address to verify the display.
31+
* - Key Aspect: Ensures the email is correctly displayed in the verification message.
32+
*/
33+
export const WithCustomEmail: Story = {
34+
render: () => (
35+
<KcPageStory
36+
kcContext={{
37+
user: {
38+
email: "thais@hubee.com"
39+
}
40+
}}
41+
/>
42+
)
43+
};
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { getKcClsx } from "keycloakify/login/lib/kcClsx";
2+
import type { PageProps } from "keycloakify/login/pages/PageProps";
3+
import type { KcContext } from "../KcContext";
4+
import type { I18n } from "../i18n";
5+
import Alert from "@codegouvfr/react-dsfr/Alert";
6+
import { fr } from "@codegouvfr/react-dsfr";
7+
8+
export default function LoginVerifyEmail(props: PageProps<Extract<KcContext, { pageId: "login-verify-email.ftl" }>, I18n>) {
9+
const { kcContext, i18n, doUseDefaultCss, Template, classes } = props;
10+
11+
const { kcClsx } = getKcClsx({
12+
doUseDefaultCss,
13+
classes
14+
});
15+
16+
const { url, user } = kcContext;
17+
18+
const { msg, msgStr } = i18n;
19+
20+
return (
21+
<Template
22+
kcContext={kcContext}
23+
i18n={i18n}
24+
doUseDefaultCss={doUseDefaultCss}
25+
classes={classes}
26+
displayMessage={false}
27+
headerNode={msg("emailVerifyTitle")}
28+
>
29+
<Alert
30+
severity="info"
31+
description={msgStr("emailVerifyInstruction1", user?.email ?? "")}
32+
className={fr.cx("fr-mb-4w")}
33+
small
34+
/>
35+
36+
<div className={kcClsx("kcFormGroupClass")}>
37+
<p className={fr.cx("fr-text--sm", "fr-mb-3w")}>
38+
{msgStr("emailVerifyInstruction2")}{" "}
39+
<form action={url.loginAction} method="post" style={{ display: "inline" }}>
40+
<input type="hidden" name="email" value={user?.email ?? ""} />
41+
<button
42+
type="submit"
43+
className={fr.cx("fr-link")}
44+
style={{
45+
background: "none",
46+
border: "none",
47+
padding: 0,
48+
cursor: "pointer"
49+
}}
50+
>
51+
{msgStr("doClickHere")} {msgStr("emailVerifyInstruction3")}
52+
</button>
53+
</form>
54+
</p>
55+
</div>
56+
57+
<div className={kcClsx("kcFormGroupClass")} style={{ display: "flex", justifyContent: "flex-end" }}>
58+
<a className={fr.cx("fr-link")} href={url.loginUrl}>
59+
{msg("backToLogin")}
60+
</a>
61+
</div>
62+
</Template>
63+
);
64+
}

0 commit comments

Comments
 (0)