From 920933312f6a11a4f76bb770797e3866624f1afc Mon Sep 17 00:00:00 2001 From: Damien Le Thiec Date: Mon, 10 Nov 2025 09:30:36 +0100 Subject: [PATCH] feat: add themed LoginPageExpired page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add DSFR-styled LoginPageExpired page (login-page-expired.ftl) that displays: - Two action options in DSFR callouts with grid layout - pageExpiredMsg1: Restart authentication flow (secondary button with refresh icon) - pageExpiredMsg2: Continue where you left off (primary button with arrow icon) - Fully DSFR-adapted with native components (fr-callout, fr-btn, fr-grid) - No custom Alert component, uses Keycloak default messages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/login/KcPage.tsx | 9 ++++ src/login/pages/LoginPageExpired.stories.tsx | 35 +++++++++++++++ src/login/pages/LoginPageExpired.tsx | 47 ++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 src/login/pages/LoginPageExpired.stories.tsx create mode 100644 src/login/pages/LoginPageExpired.tsx diff --git a/src/login/KcPage.tsx b/src/login/KcPage.tsx index c6b4bc54..2a2bd365 100644 --- a/src/login/KcPage.tsx +++ b/src/login/KcPage.tsx @@ -13,6 +13,7 @@ const Login = lazy(() => import("./pages/Login")); const Register = lazy(() => import("./pages/Register")); const LoginUpdateProfile = lazy(() => import("./pages/LoginUpdateProfile")); const LoginUpdatePassword = lazy(() => import("./pages/LoginUpdatePassword")); +const LoginPageExpired = lazy(() => import("./pages/LoginPageExpired")); const doMakeUserConfirmPassword = false; @@ -77,6 +78,14 @@ export default function KcPage(props: { kcContext: KcContext }) { doUseDefaultCss={false} /> ); + case "login-page-expired.ftl": + return ( + + ); default: return ( ; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = { + render: () => +}; + +/** + * WithCustomUrl: + * - Purpose: Tests the page with a custom restart flow URL. + * - Scenario: Simulates a page expired scenario with a specific URL to restart the authentication flow. + * - Key Aspect: Ensures the "click here to login" link points to the correct restart URL. + */ +export const WithCustomUrl: Story = { + render: () => ( + + ) +}; diff --git a/src/login/pages/LoginPageExpired.tsx b/src/login/pages/LoginPageExpired.tsx new file mode 100644 index 00000000..749a824c --- /dev/null +++ b/src/login/pages/LoginPageExpired.tsx @@ -0,0 +1,47 @@ +import type { PageProps } from "keycloakify/login/pages/PageProps"; +import type { KcContext } from "../KcContext"; +import type { I18n } from "../i18n"; +import { fr } from "@codegouvfr/react-dsfr"; + +export default function LoginPageExpired(props: PageProps, I18n>) { + const { kcContext, i18n, doUseDefaultCss, Template, classes } = props; + + const { url } = kcContext; + + const { msg } = i18n; + + return ( + + ); +}