Account:完整深色账户控制台、响应式侧栏、表单、表格和状态提示。
Admin:深色导航外壳、浅色操作区、统一按钮/表格/表单以及新 Logo。 Email:所有 HTML 邮件统一品牌卡片、渐变操作按钮和移动端布局。
This commit is contained in:
1 parent
9253ab4e32
commit
bb49401545
9 files changed
+1141
-6
No files matched your search
+3
-3
@@ -1,6 +1,9 @@
|
||||
# This file is managed by Keycloakify, do not edit it manually.
|
||||
|
||||
# === Owned files start ===
|
||||
# admin/index.css
|
||||
# admin/assets/logo.svg
|
||||
# email/html/template.ftl
|
||||
# === Owned files end =====
|
||||
|
||||
# === @keycloakify/email-native v260007.0.0 ===
|
||||
@@ -21,7 +24,6 @@
|
||||
/email/html/identity-provider-link.ftl
|
||||
/email/html/org-invite.ftl
|
||||
/email/html/password-reset.ftl
|
||||
/email/html/template.ftl
|
||||
/email/messages/messages_ar.properties
|
||||
/email/messages/messages_ca.properties
|
||||
/email/messages/messages_cs.properties
|
||||
@@ -79,7 +81,6 @@
|
||||
/admin/ForbiddenSection.tsx
|
||||
/admin/help-urls.ts
|
||||
/admin/i18next.d.ts
|
||||
/admin/index.css
|
||||
/admin/KcAdminUi.tsx
|
||||
/admin/KcContext.ts
|
||||
/admin/KcPage.tsx
|
||||
@@ -94,7 +95,6 @@
|
||||
/admin/assets/favicon.svg
|
||||
/admin/assets/icon.svg
|
||||
/admin/assets/img_avatar.svg
|
||||
/admin/assets/logo.svg
|
||||
/admin/authentication/AuthenticationSection.tsx
|
||||
/admin/authentication/BindFlowDialog.tsx
|
||||
/admin/authentication/build-in-label.module.css
|
||||
|
||||
+25
-3
@@ -3,7 +3,8 @@ import type { ClassKey } from "keycloakify/account";
|
||||
import type { KcContext } from "./KcContext";
|
||||
import { useI18n } from "./i18n";
|
||||
import DefaultPage from "keycloakify/account/DefaultPage";
|
||||
import Template from "keycloakify/account/Template";
|
||||
import Template from "./Template";
|
||||
import "./theme.css";
|
||||
|
||||
export default function KcPage(props: { kcContext: KcContext }) {
|
||||
const { kcContext } = props;
|
||||
@@ -15,11 +16,32 @@ export default function KcPage(props: { kcContext: KcContext }) {
|
||||
{(() => {
|
||||
switch (kcContext.pageId) {
|
||||
default:
|
||||
return <DefaultPage kcContext={kcContext} i18n={i18n} classes={classes} Template={Template} doUseDefaultCss={true} />;
|
||||
return (
|
||||
<DefaultPage
|
||||
kcContext={kcContext}
|
||||
i18n={i18n}
|
||||
classes={classes}
|
||||
Template={Template}
|
||||
doUseDefaultCss={false}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})()}
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
const classes = {} satisfies { [key in ClassKey]?: string };
|
||||
const classes = {
|
||||
kcHtmlClass: "nexus-account-html",
|
||||
kcBodyClass: "nexus-account-body",
|
||||
kcButtonClass: "nexus-account-button",
|
||||
kcButtonPrimaryClass: "nexus-account-button--primary",
|
||||
kcButtonDefaultClass: "nexus-account-button--default",
|
||||
kcButtonLargeClass: "nexus-account-button--large",
|
||||
kcFormClass: "nexus-account-form",
|
||||
kcFormGroupClass: "nexus-account-field",
|
||||
kcLabelClass: "nexus-account-label",
|
||||
kcInputClass: "nexus-account-input",
|
||||
kcInputWrapperClass: "nexus-account-input-wrapper",
|
||||
kcInputErrorMessageClass: "nexus-account-field-error"
|
||||
} satisfies { [key in ClassKey]?: string };
|
||||
@@ -0,0 +1,124 @@
|
||||
import { useEffect } from "react";
|
||||
import { clsx } from "keycloakify/tools/clsx";
|
||||
import { kcSanitize } from "keycloakify/lib/kcSanitize";
|
||||
import { getKcClsx } from "keycloakify/account/lib/kcClsx";
|
||||
import { useSetClassName } from "keycloakify/tools/useSetClassName";
|
||||
import { useInitialize } from "keycloakify/account/Template.useInitialize";
|
||||
import type { TemplateProps } from "keycloakify/account/TemplateProps";
|
||||
import type { I18n } from "./i18n";
|
||||
import type { KcContext } from "./KcContext";
|
||||
|
||||
export default function Template(props: TemplateProps<KcContext, I18n>) {
|
||||
const { kcContext, i18n, doUseDefaultCss, active, classes, children } = props;
|
||||
const { kcClsx } = getKcClsx({ doUseDefaultCss, classes });
|
||||
const { msg, msgStr, currentLanguage, enabledLanguages } = i18n;
|
||||
const { url, features, realm, message, referrer } = kcContext;
|
||||
|
||||
useEffect(() => {
|
||||
document.title = msgStr("accountManagementTitle");
|
||||
}, [msgStr]);
|
||||
|
||||
useSetClassName({ qualifiedName: "html", className: kcClsx("kcHtmlClass") });
|
||||
useSetClassName({ qualifiedName: "body", className: kcClsx("kcBodyClass") });
|
||||
|
||||
const { isReadyToRender } = useInitialize({ kcContext, doUseDefaultCss });
|
||||
|
||||
if (!isReadyToRender) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const navigationItems = [
|
||||
{ id: "account", href: url.accountUrl, label: msg("account"), visible: true },
|
||||
{ id: "password", href: url.passwordUrl, label: msg("password"), visible: features.passwordUpdateSupported },
|
||||
{ id: "totp", href: url.totpUrl, label: msg("authenticator"), visible: true },
|
||||
{ id: "social", href: url.socialUrl, label: msg("federatedIdentity"), visible: features.identityFederation },
|
||||
{ id: "sessions", href: url.sessionsUrl, label: msg("sessions"), visible: true },
|
||||
{ id: "applications", href: url.applicationsUrl, label: msg("applications"), visible: true },
|
||||
{ id: "log", href: url.logUrl, label: msg("log"), visible: features.log },
|
||||
{
|
||||
id: "authorization",
|
||||
href: url.resourceUrl,
|
||||
label: msg("myResources"),
|
||||
visible: realm.userManagedAccessAllowed && features.authorization
|
||||
}
|
||||
].filter(item => item.visible);
|
||||
|
||||
return (
|
||||
<div className="nexus-account-shell">
|
||||
<header className="nexus-account-header">
|
||||
<a className="nexus-account-brand" href={url.accountUrl} aria-label={msgStr("accountManagementTitle")}>
|
||||
<span className="nexus-account-brand__mark">N</span>
|
||||
<span>
|
||||
NEXUS <b>/ ID</b>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<div className="nexus-account-header__realm">
|
||||
<span>IDENTITY CONTROL</span>
|
||||
<strong>{msg("accountManagementTitle")}</strong>
|
||||
</div>
|
||||
|
||||
<nav className="nexus-account-utility" aria-label="Account utilities">
|
||||
{enabledLanguages.length > 1 && (
|
||||
<details className="nexus-account-language">
|
||||
<summary>{currentLanguage.label}</summary>
|
||||
<ul>
|
||||
{enabledLanguages.map(({ languageTag, label, href }) => (
|
||||
<li key={languageTag}>
|
||||
<a href={href}>{label}</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</details>
|
||||
)}
|
||||
{referrer?.url && (
|
||||
<a href={referrer.url} id="referrer">
|
||||
{msg("backTo", referrer.name)}
|
||||
</a>
|
||||
)}
|
||||
<a className="nexus-account-signout" href={url.getLogoutUrl()}>
|
||||
{msg("doSignOut")}
|
||||
</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div className="nexus-account-layout">
|
||||
<aside className="nexus-account-sidebar">
|
||||
<div className="nexus-account-orbit" aria-hidden="true">
|
||||
<span />
|
||||
</div>
|
||||
<p className="nexus-account-sidebar__label">ACCOUNT MATRIX</p>
|
||||
<nav aria-label={msgStr("accountManagementTitle")}>
|
||||
<ul>
|
||||
{navigationItems.map(item => (
|
||||
<li key={item.id} className={clsx(active === item.id && "active")}>
|
||||
<a href={item.href}>
|
||||
<span className="nexus-account-nav__signal" />
|
||||
{item.label}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
<div className="nexus-account-sidebar__status">
|
||||
<span /> SECURE SESSION
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
<main className="nexus-account-content" id="nexus-account-main">
|
||||
{message !== undefined && (
|
||||
<div className={clsx("nexus-account-alert", `nexus-account-alert--${message.type}`)} role="status">
|
||||
<span className="nexus-account-alert__signal" />
|
||||
<span
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: kcSanitize(message.summary)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<section className="nexus-account-panel">{children}</section>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loaded 3 of 9 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user