@oussemasahbeni/keycloakify-login-shadcn 250004.0.3 → 250004.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/keycloak-theme/components/langauges.tsx +1 -1
  2. package/keycloak-theme/components/theme-toggle.tsx +0 -1
  3. package/keycloak-theme/components/ui/alert.tsx +1 -2
  4. package/keycloak-theme/components/ui/button.tsx +1 -2
  5. package/keycloak-theme/components/ui/card.tsx +0 -1
  6. package/keycloak-theme/components/ui/checkbox.tsx +0 -1
  7. package/keycloak-theme/components/ui/dropdown-menu.tsx +14 -4
  8. package/keycloak-theme/components/ui/field.tsx +0 -1
  9. package/keycloak-theme/components/ui/input-otp.tsx +0 -1
  10. package/keycloak-theme/components/ui/input.tsx +0 -1
  11. package/keycloak-theme/components/ui/label.tsx +1 -2
  12. package/keycloak-theme/components/ui/radio-group.tsx +0 -1
  13. package/keycloak-theme/components/ui/select.tsx +12 -4
  14. package/keycloak-theme/components/ui/separator.tsx +0 -1
  15. package/keycloak-theme/components/ui/tooltip.tsx +0 -1
  16. package/keycloak-theme/login/KcContext.ts +23 -23
  17. package/keycloak-theme/login/KcPage.tsx +45 -47
  18. package/keycloak-theme/login/assets/img/auth-logo.svg +100 -100
  19. package/keycloak-theme/login/assets/img/shape.svg +71 -71
  20. package/keycloak-theme/login/components/LogoutOtherSessions.tsx +24 -26
  21. package/keycloak-theme/login/components/PasswordWrapper.tsx +35 -35
  22. package/keycloak-theme/login/components/Template/Template.tsx +279 -227
  23. package/keycloak-theme/login/components/Template/index.ts +1 -1
  24. package/keycloak-theme/login/components/Template/useInitializeTemplate.ts +61 -61
  25. package/keycloak-theme/login/components/UserProfileFormFields/AddRemoveButtonsMultiValuedAttribute.tsx +65 -61
  26. package/keycloak-theme/login/components/UserProfileFormFields/DO_MAKE_USER_CONFIRM_PASSWORD.ts +2 -2
  27. package/keycloak-theme/login/components/UserProfileFormFields/FieldErrors.tsx +33 -29
  28. package/keycloak-theme/login/components/UserProfileFormFields/GroupLabel.tsx +90 -71
  29. package/keycloak-theme/login/components/UserProfileFormFields/InputFieldByType.tsx +66 -59
  30. package/keycloak-theme/login/components/UserProfileFormFields/InputLabel.tsx +0 -1
  31. package/keycloak-theme/login/components/UserProfileFormFields/InputTag.tsx +133 -116
  32. package/keycloak-theme/login/components/UserProfileFormFields/InputTagSelects.tsx +150 -136
  33. package/keycloak-theme/login/components/UserProfileFormFields/SelectTag.tsx +135 -114
  34. package/keycloak-theme/login/components/UserProfileFormFields/TextareaTag.tsx +55 -43
  35. package/keycloak-theme/login/components/UserProfileFormFields/UserProfileFormFields.tsx +133 -127
  36. package/keycloak-theme/login/components/UserProfileFormFields/index.ts +1 -1
  37. package/keycloak-theme/login/i18n.ts +47 -47
  38. package/keycloak-theme/login/mocks/KcPageStory.tsx +6 -2
  39. package/keycloak-theme/login/mocks/getKcContextMock.ts +22 -22
  40. package/keycloak-theme/login/pages/PageIndex.tsx +130 -134
  41. package/keycloak-theme/login/pages/code/Page.stories.tsx +57 -70
  42. package/keycloak-theme/login/pages/code/Page.tsx +89 -89
  43. package/keycloak-theme/login/pages/code/index.ts +3 -3
  44. package/keycloak-theme/login/pages/delete-account-confirm/Page.stories.tsx +37 -46
  45. package/keycloak-theme/login/pages/delete-account-confirm/Page.tsx +60 -63
  46. package/keycloak-theme/login/pages/delete-account-confirm/index.ts +3 -3
  47. package/keycloak-theme/login/pages/delete-credential/Page.stories.tsx +25 -30
  48. package/keycloak-theme/login/pages/delete-credential/Page.tsx +56 -51
  49. package/keycloak-theme/login/pages/delete-credential/index.ts +3 -3
  50. package/keycloak-theme/login/pages/error/Page.stories.tsx +46 -58
  51. package/keycloak-theme/login/pages/error/Page.tsx +43 -42
  52. package/keycloak-theme/login/pages/error/index.ts +3 -3
  53. package/keycloak-theme/login/pages/frontchannel-logout/Page.stories.tsx +25 -32
  54. package/keycloak-theme/login/pages/frontchannel-logout/Page.tsx +82 -84
  55. package/keycloak-theme/login/pages/frontchannel-logout/index.ts +3 -3
  56. package/keycloak-theme/login/pages/idp-review-user-profile/Page.stories.tsx +46 -59
  57. package/keycloak-theme/login/pages/idp-review-user-profile/Page.tsx +49 -52
  58. package/keycloak-theme/login/pages/idp-review-user-profile/index.ts +3 -3
  59. package/keycloak-theme/login/pages/info/Page.stories.tsx +50 -60
  60. package/keycloak-theme/login/pages/info/Page.tsx +94 -92
  61. package/keycloak-theme/login/pages/link-idp-action/Page.stories.tsx +32 -16
  62. package/keycloak-theme/login/pages/link-idp-action/Page.tsx +45 -43
  63. package/keycloak-theme/login/pages/link-idp-action/index.ts +3 -3
  64. package/keycloak-theme/login/pages/login/Form.tsx +242 -242
  65. package/keycloak-theme/login/pages/login/Info.tsx +29 -29
  66. package/keycloak-theme/login/pages/login/Page.stories.tsx +346 -365
  67. package/keycloak-theme/login/pages/login/Page.tsx +43 -44
  68. package/keycloak-theme/login/pages/login/SocialProviders.tsx +93 -107
  69. package/keycloak-theme/login/pages/login/index.ts +3 -3
  70. package/keycloak-theme/login/pages/login/providers/apple.svg +3 -3
  71. package/keycloak-theme/login/pages/login/providers/bitbucket.svg +11 -11
  72. package/keycloak-theme/login/pages/login/providers/discord.svg +4 -4
  73. package/keycloak-theme/login/pages/login/providers/facebook.svg +5 -5
  74. package/keycloak-theme/login/pages/login/providers/github.svg +3 -3
  75. package/keycloak-theme/login/pages/login/providers/gitlab.svg +7 -7
  76. package/keycloak-theme/login/pages/login/providers/google.svg +7 -7
  77. package/keycloak-theme/login/pages/login/providers/instagram.svg +31 -31
  78. package/keycloak-theme/login/pages/login/providers/linkedin.svg +3 -3
  79. package/keycloak-theme/login/pages/login/providers/microsoft.svg +6 -6
  80. package/keycloak-theme/login/pages/login/providers/oidc.svg +5 -5
  81. package/keycloak-theme/login/pages/login/providers/openshift.svg +7 -7
  82. package/keycloak-theme/login/pages/login/providers/paypal.svg +6 -6
  83. package/keycloak-theme/login/pages/login/providers/slack.svg +11 -11
  84. package/keycloak-theme/login/pages/login/providers/stackoverflow.svg +5 -5
  85. package/keycloak-theme/login/pages/login/providers/x.svg +3 -3
  86. package/keycloak-theme/login/pages/login/useProviderLogos.tsx +39 -39
  87. package/keycloak-theme/login/pages/login/useScript.tsx +62 -62
  88. package/keycloak-theme/login/pages/login-config-totp/Page.stories.tsx +45 -60
  89. package/keycloak-theme/login/pages/login-config-totp/Page.tsx +253 -240
  90. package/keycloak-theme/login/pages/login-config-totp/index.ts +3 -3
  91. package/keycloak-theme/login/pages/login-idp-link-confirm/Page.stories.tsx +30 -35
  92. package/keycloak-theme/login/pages/login-idp-link-confirm/Page.tsx +40 -43
  93. package/keycloak-theme/login/pages/login-idp-link-confirm/index.ts +3 -3
  94. package/keycloak-theme/login/pages/login-idp-link-confirm-override/Page.stories.tsx +16 -23
  95. package/keycloak-theme/login/pages/login-idp-link-confirm-override/Page.tsx +44 -47
  96. package/keycloak-theme/login/pages/login-idp-link-confirm-override/index.ts +3 -3
  97. package/keycloak-theme/login/pages/login-idp-link-email/Page.stories.tsx +54 -63
  98. package/keycloak-theme/login/pages/login-idp-link-email/Page.tsx +51 -54
  99. package/keycloak-theme/login/pages/login-idp-link-email/index.ts +3 -3
  100. package/keycloak-theme/login/pages/login-oauth-grant/Page.stories.tsx +39 -45
  101. package/keycloak-theme/login/pages/login-oauth-grant/Page.tsx +136 -126
  102. package/keycloak-theme/login/pages/login-oauth-grant/index.ts +3 -3
  103. package/keycloak-theme/login/pages/login-oauth2-device-verify-user-code/Page.stories.tsx +38 -48
  104. package/keycloak-theme/login/pages/login-oauth2-device-verify-user-code/Page.tsx +56 -58
  105. package/keycloak-theme/login/pages/login-oauth2-device-verify-user-code/index.ts +3 -3
  106. package/keycloak-theme/login/pages/login-otp/Page.stories.tsx +82 -97
  107. package/keycloak-theme/login/pages/login-otp/Page.tsx +117 -108
  108. package/keycloak-theme/login/pages/login-otp/index.ts +3 -3
  109. package/keycloak-theme/login/pages/login-page-expired/Page.stories.tsx +28 -37
  110. package/keycloak-theme/login/pages/login-page-expired/Page.tsx +45 -47
  111. package/keycloak-theme/login/pages/login-page-expired/index.ts +3 -3
  112. package/keycloak-theme/login/pages/login-passkeys-conditional-authenticate/Page.stories.tsx +20 -0
  113. package/keycloak-theme/login/pages/login-passkeys-conditional-authenticate/Page.tsx +290 -233
  114. package/keycloak-theme/login/pages/login-passkeys-conditional-authenticate/index.ts +3 -3
  115. package/keycloak-theme/login/pages/login-passkeys-conditional-authenticate/useScript.tsx +63 -63
  116. package/keycloak-theme/login/pages/login-password/Page.stories.tsx +55 -56
  117. package/keycloak-theme/login/pages/login-password/Page.tsx +148 -149
  118. package/keycloak-theme/login/pages/login-password/index.ts +3 -3
  119. package/keycloak-theme/login/pages/login-password/useScript.tsx +62 -63
  120. package/keycloak-theme/login/pages/login-recovery-authn-code-config/Page.stories.tsx +28 -36
  121. package/keycloak-theme/login/pages/login-recovery-authn-code-config/Page.tsx +178 -181
  122. package/keycloak-theme/login/pages/login-recovery-authn-code-config/index.ts +3 -3
  123. package/keycloak-theme/login/pages/login-recovery-authn-code-config/useScript.tsx +145 -145
  124. package/keycloak-theme/login/pages/login-recovery-authn-code-input/Page.stories.tsx +16 -22
  125. package/keycloak-theme/login/pages/login-recovery-authn-code-input/Page.tsx +69 -70
  126. package/keycloak-theme/login/pages/login-recovery-authn-code-input/index.ts +3 -3
  127. package/keycloak-theme/login/pages/login-reset-otp/Page.stories.tsx +62 -75
  128. package/keycloak-theme/login/pages/login-reset-otp/Page.tsx +85 -86
  129. package/keycloak-theme/login/pages/login-reset-otp/index.ts +3 -3
  130. package/keycloak-theme/login/pages/login-reset-password/Form.tsx +67 -68
  131. package/keycloak-theme/login/pages/login-reset-password/Page.stories.tsx +44 -55
  132. package/keycloak-theme/login/pages/login-reset-password/Page.tsx +27 -27
  133. package/keycloak-theme/login/pages/login-reset-password/index.ts +3 -3
  134. package/keycloak-theme/login/pages/login-update-password/Page.stories.tsx +40 -51
  135. package/keycloak-theme/login/pages/login-update-password/Page.tsx +109 -111
  136. package/keycloak-theme/login/pages/login-update-password/index.ts +3 -3
  137. package/keycloak-theme/login/pages/login-update-profile/Page.stories.tsx +28 -37
  138. package/keycloak-theme/login/pages/login-update-profile/Page.tsx +67 -68
  139. package/keycloak-theme/login/pages/login-update-profile/index.ts +3 -3
  140. package/keycloak-theme/login/pages/login-username/Page.stories.tsx +32 -43
  141. package/keycloak-theme/login/pages/login-username/Page.tsx +246 -246
  142. package/keycloak-theme/login/pages/login-username/index.ts +3 -3
  143. package/keycloak-theme/login/pages/login-username/useScript.tsx +62 -62
  144. package/keycloak-theme/login/pages/login-verify-email/Page.stories.tsx +68 -81
  145. package/keycloak-theme/login/pages/login-verify-email/Page.tsx +37 -38
  146. package/keycloak-theme/login/pages/login-verify-email/index.ts +3 -3
  147. package/keycloak-theme/login/pages/login-x509-info/Page.stories.tsx +29 -38
  148. package/keycloak-theme/login/pages/login-x509-info/Page.tsx +72 -75
  149. package/keycloak-theme/login/pages/login-x509-info/index.ts +3 -3
  150. package/keycloak-theme/login/pages/logout-confirm/Page.stories.tsx +34 -43
  151. package/keycloak-theme/login/pages/logout-confirm/Page.tsx +50 -53
  152. package/keycloak-theme/login/pages/logout-confirm/index.ts +3 -3
  153. package/keycloak-theme/login/pages/register/Form.tsx +107 -106
  154. package/keycloak-theme/login/pages/register/Page.stories.tsx +40 -14
  155. package/keycloak-theme/login/pages/register/Page.tsx +26 -26
  156. package/keycloak-theme/login/pages/register/TermsAcceptance.tsx +55 -56
  157. package/keycloak-theme/login/pages/register/index.ts +3 -3
  158. package/keycloak-theme/login/pages/saml-post-form/Page.stories.tsx +16 -23
  159. package/keycloak-theme/login/pages/saml-post-form/Page.tsx +64 -66
  160. package/keycloak-theme/login/pages/saml-post-form/index.ts +3 -3
  161. package/keycloak-theme/login/pages/select-authenticator/Page.stories.tsx +83 -96
  162. package/keycloak-theme/login/pages/select-authenticator/Page.tsx +97 -100
  163. package/keycloak-theme/login/pages/select-authenticator/index.ts +3 -3
  164. package/keycloak-theme/login/pages/select-organization/Page.stories.tsx +62 -49
  165. package/keycloak-theme/login/pages/select-organization/Page.tsx +123 -126
  166. package/keycloak-theme/login/pages/select-organization/index.ts +3 -3
  167. package/keycloak-theme/login/pages/terms/Page.stories.tsx +15 -0
  168. package/keycloak-theme/login/pages/terms/Page.tsx +49 -51
  169. package/keycloak-theme/login/pages/terms/index.ts +3 -3
  170. package/keycloak-theme/login/pages/update-email/Page.stories.tsx +27 -36
  171. package/keycloak-theme/login/pages/update-email/Page.tsx +61 -62
  172. package/keycloak-theme/login/pages/update-email/index.ts +3 -3
  173. package/keycloak-theme/login/pages/webauthn-authenticate/Page.stories.tsx +112 -127
  174. package/keycloak-theme/login/pages/webauthn-authenticate/Page.tsx +206 -202
  175. package/keycloak-theme/login/pages/webauthn-authenticate/index.ts +3 -3
  176. package/keycloak-theme/login/pages/webauthn-authenticate/useScript.tsx +55 -55
  177. package/keycloak-theme/login/pages/webauthn-error/Page.stories.tsx +52 -67
  178. package/keycloak-theme/login/pages/webauthn-error/Page.tsx +70 -73
  179. package/keycloak-theme/login/pages/webauthn-error/index.ts +3 -3
  180. package/keycloak-theme/login/pages/webauthn-register/Page.stories.tsx +39 -50
  181. package/keycloak-theme/login/pages/webauthn-register/Page.tsx +78 -78
  182. package/keycloak-theme/login/pages/webauthn-register/index.ts +3 -3
  183. package/keycloak-theme/login/pages/webauthn-register/useScript.tsx +62 -62
  184. package/keycloak-theme/login/shared/getColorScheme.ts +45 -45
  185. package/keycloak-theme/login/styleLevelCustomization.tsx +34 -36
  186. package/keycloak-theme/public/site.webmanifest +11 -1
  187. package/package.json +6 -2
@@ -1,227 +1,279 @@
1
- import { Languages } from '@/components/langauges';
2
- import { ModeToggle } from '@/components/theme-toggle';
3
- import { Alert, AlertDescription } from '@/components/ui/alert';
4
- import { Button } from '@/components/ui/button';
5
- import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
6
- import { redirectUrlOrigin } from '@/login/shared/redirectUrlOrigin';
7
- import { kcSanitize } from "@keycloakify/login-ui/kcSanitize";
8
- import { useKcClsx } from "@keycloakify/login-ui/useKcClsx";
9
- import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@radix-ui/react-tooltip';
10
- import { useSetClassName } from "keycloakify/tools/useSetClassName";
11
- import { RotateCcw } from 'lucide-react';
12
- import type { ReactNode } from "react";
13
- import { useEffect } from "react";
14
- import { FiHome } from 'react-icons/fi';
15
- import { useI18n } from "../../i18n";
16
- import { useKcContext } from "../../KcContext";
17
- import companylogo from "./../../assets/img/auth-logo.svg";
18
- import shape from "./../../assets/img/shape.svg";
19
- import { useInitializeTemplate } from "./useInitializeTemplate";
20
-
21
- const APP_NAME = "Acme Inc.";
22
-
23
- export function Template(props: {
24
- displayInfo?: boolean;
25
- displayMessage?: boolean;
26
- displayRequiredFields?: boolean;
27
- headerNode: ReactNode;
28
- socialProvidersNode?: ReactNode;
29
- infoNode?: ReactNode;
30
- documentTitle?: string;
31
- bodyClassName?: string;
32
- children: ReactNode;
33
- }) {
34
- const {
35
- displayInfo = false,
36
- displayMessage = true,
37
- displayRequiredFields = false,
38
- headerNode,
39
- socialProvidersNode = null,
40
- infoNode = null,
41
- documentTitle,
42
- bodyClassName,
43
- children
44
- } = props;
45
-
46
- const { kcContext } = useKcContext();
47
-
48
- const { auth, url, message, isAppInitiatedAction } = kcContext;
49
-
50
-
51
- const { msg, msgStr, enabledLanguages } = useI18n();
52
-
53
- const { kcClsx } = useKcClsx();
54
-
55
- useEffect(() => {
56
- document.title =
57
- documentTitle ?? msgStr("loginTitle", kcContext.realm.displayName);
58
- }, []);
59
-
60
- useSetClassName({
61
- qualifiedName: "html",
62
- className: kcClsx("kcHtmlClass")
63
- });
64
-
65
- useSetClassName({
66
- qualifiedName: "body",
67
- className: bodyClassName ?? kcClsx("kcBodyClass")
68
- });
69
-
70
- const { isReadyToRender } = useInitializeTemplate();
71
-
72
- if (!isReadyToRender) {
73
- return null;
74
- }
75
-
76
- return (
77
- <div className="grid min-h-svh lg:grid-cols-2 bg-white dark:bg-background lg:bg-transparent">
78
- {/* Main content */}
79
- <div className="flex flex-col gap-4 px-0 py-0 pb-6 lg:p-6 lg:md:p-10 lg:pt-10 min-h-screen lg:min-h-0">
80
- {/* navigation */}
81
- <div className="absolute top-4 right-4 lg:left-4 z-20 flex gap-2">
82
- <Button variant="outline" size="icon" >
83
- <a href={kcContext.client.baseUrl ?? redirectUrlOrigin}>
84
- <FiHome />
85
- </a>
86
- </Button>
87
-
88
- {enabledLanguages.length > 1 && (
89
- <Languages />
90
- )}
91
-
92
-
93
- {kcContext.darkMode !== false && (
94
- <ModeToggle />
95
- )}
96
- </div>
97
-
98
- {/* Mobile header with logo */}
99
- <div className="lg:hidden relative pt-8 px-6">
100
- {/* Logo and welcome message */}
101
- <div className="flex flex-col items-center justify-center gap-3 mt-4">
102
- <div className=" mb-4 flex items-center gap-3">
103
- <img src={companylogo} alt="Logo" />
104
- <span className=" text-xl"> {APP_NAME}</span>
105
- </div>
106
- </div>
107
- </div>
108
-
109
- <div className="flex flex-1 items-start lg:items-center justify-center lg:mt-0 ">
110
- <div className="w-full max-w-xl ">
111
- <Card className=" shadow-none bg-transparent lg:bg-card border-0 lg:rounded-lg lg:border lg:shadow-sm rounded-t-2xl">
112
- <CardHeader className="text-center mb-3 px-6 pt-8 pb-4 lg:pt-6">
113
- <CardTitle>
114
- {(() => {
115
- const node = !(auth !== undefined && auth.showUsername && !auth.showResetCredentials) ? (
116
- <h1 className="text-xl">{headerNode}</h1>
117
- ) : (
118
- <div id="kc-username" className="flex items-center justify-center gap-2">
119
- <label className="font-semibold text-lg" id="kc-attempted-username">
120
- {auth.attemptedUsername}
121
- </label>
122
-
123
- <TooltipProvider>
124
- <Tooltip>
125
- <TooltipTrigger asChild>
126
- <Button variant="outline" size="icon" asChild>
127
- <a
128
- id="reset-login"
129
- href={url.loginRestartFlowUrl}
130
- aria-label={msgStr("restartLoginTooltip")}
131
- >
132
- <RotateCcw className="h-4 w-4" />
133
- </a>
134
- </Button>
135
- </TooltipTrigger>
136
- <TooltipContent>
137
- <p>{msg("restartLoginTooltip")}</p>
138
- </TooltipContent>
139
- </Tooltip>
140
- </TooltipProvider>
141
- </div>
142
- );
143
-
144
- if (displayRequiredFields) {
145
- return (
146
- <div className="flex items-center justify-between gap-2">
147
- <div>{node}</div>
148
- <div>
149
- <span className="subtitle">
150
- <span className="text-red-500">*</span>
151
- {msg("requiredFields")}
152
- </span>
153
- </div>
154
- </div>
155
- );
156
- }
157
-
158
- return node;
159
- })()}
160
- </CardTitle>
161
- </CardHeader>
162
- <CardContent className="px-6 pb-8">
163
- <div id="kc-content">
164
- <div id="kc-content-wrapper">
165
- {displayMessage && message !== undefined && (message.type !== "warning" || !isAppInitiatedAction) && (
166
- <Alert variant={message.type} className="my-3">
167
- <AlertDescription>
168
- <div>
169
- <span
170
- dangerouslySetInnerHTML={{
171
- __html: kcSanitize(message.summary)
172
- }}
173
- />
174
- </div>
175
- </AlertDescription>
176
- </Alert>
177
- )}
178
- <div className="children">{children}</div>
179
- {socialProvidersNode}
180
- {auth !== undefined && auth.showTryAnotherWayLink && (
181
- <form id="kc-select-try-another-way-form" action={url.loginAction} method="post">
182
- <div className={kcClsx("kcFormGroupClass")}>
183
- <input type="hidden" name="tryAnotherWay" value="on" />
184
- <a
185
- href="#"
186
- id="try-another-way"
187
- onClick={() => {
188
- document.forms["kc-select-try-another-way-form" as never].submit();
189
- return false;
190
- }}
191
- >
192
- {msg("doTryAnotherWay")}
193
- </a>
194
- </div>
195
- </form>
196
- )}
197
- {displayInfo && <div className="text-center text-sm mt-4">{infoNode}</div>}
198
- </div>
199
- </div>
200
- </CardContent>
201
- </Card>
202
- </div>
203
- </div>
204
- </div>
205
-
206
- <div className="bg-slate-950 relative hidden lg:block dark:bg-white/5">
207
- <div className="flex items-center pt-20 h-full justify-center z-1">
208
- <div className="absolute right-0 top-0 w-full max-w-62.5 xl:max-w-112.5">
209
- <img src={shape} alt="grid" />
210
- </div>
211
- <div className="absolute bottom-0 left-0 w-full max-w-62.5 rotate-180 xl:max-w-112.5">
212
- <img src={shape} alt="grid" />
213
- </div>
214
-
215
- <div className="flex justify-center my-auto flex-col items-center max-w-xs">
216
- <div className=" mb-4 flex items-center gap-3">
217
- <img src={companylogo} alt="Logo" />
218
- <span className="text-white text-xl"> {APP_NAME}</span>
219
- </div>
220
-
221
- <p className="text-center text-gray-400 dark:text-white/60">{msg("welcomeMessage")}</p>
222
- </div>
223
- </div>
224
- </div>
225
- </div>
226
- );
227
- }
1
+ import { Languages } from "@/components/langauges";
2
+ import { ModeToggle } from "@/components/theme-toggle";
3
+ import { Alert, AlertDescription } from "@/components/ui/alert";
4
+ import { Button } from "@/components/ui/button";
5
+ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
6
+ import { redirectUrlOrigin } from "@/login/shared/redirectUrlOrigin";
7
+ import { kcSanitize } from "@keycloakify/login-ui/kcSanitize";
8
+ import { useKcClsx } from "@keycloakify/login-ui/useKcClsx";
9
+ import {
10
+ Tooltip,
11
+ TooltipContent,
12
+ TooltipProvider,
13
+ TooltipTrigger
14
+ } from "@radix-ui/react-tooltip";
15
+ import { useSetClassName } from "keycloakify/tools/useSetClassName";
16
+ import { RotateCcw } from "lucide-react";
17
+ import type { ReactNode } from "react";
18
+ import { useEffect } from "react";
19
+ import { FiHome } from "react-icons/fi";
20
+ import { useI18n } from "../../i18n";
21
+ import { useKcContext } from "../../KcContext";
22
+ import companylogo from "./../../assets/img/auth-logo.svg";
23
+ import shape from "./../../assets/img/shape.svg";
24
+ import { useInitializeTemplate } from "./useInitializeTemplate";
25
+
26
+ const APP_NAME = "Acme Inc.";
27
+
28
+ export function Template(props: {
29
+ displayInfo?: boolean;
30
+ displayMessage?: boolean;
31
+ displayRequiredFields?: boolean;
32
+ headerNode: ReactNode;
33
+ socialProvidersNode?: ReactNode;
34
+ infoNode?: ReactNode;
35
+ documentTitle?: string;
36
+ bodyClassName?: string;
37
+ children: ReactNode;
38
+ }) {
39
+ const {
40
+ displayInfo = false,
41
+ displayMessage = true,
42
+ displayRequiredFields = false,
43
+ headerNode,
44
+ socialProvidersNode = null,
45
+ infoNode = null,
46
+ documentTitle,
47
+ bodyClassName,
48
+ children
49
+ } = props;
50
+
51
+ const { kcContext } = useKcContext();
52
+
53
+ const { auth, url, message, isAppInitiatedAction } = kcContext;
54
+
55
+ const { msg, msgStr, enabledLanguages } = useI18n();
56
+
57
+ const { kcClsx } = useKcClsx();
58
+
59
+ useEffect(() => {
60
+ document.title =
61
+ documentTitle ?? msgStr("loginTitle", kcContext.realm.displayName);
62
+ }, []);
63
+
64
+ useSetClassName({
65
+ qualifiedName: "html",
66
+ className: kcClsx("kcHtmlClass")
67
+ });
68
+
69
+ useSetClassName({
70
+ qualifiedName: "body",
71
+ className: bodyClassName ?? kcClsx("kcBodyClass")
72
+ });
73
+
74
+ const { isReadyToRender } = useInitializeTemplate();
75
+
76
+ if (!isReadyToRender) {
77
+ return null;
78
+ }
79
+
80
+ return (
81
+ <div className="grid min-h-svh lg:grid-cols-2 bg-white dark:bg-background lg:bg-transparent">
82
+ {/* Main content */}
83
+ <div className="flex flex-col gap-4 px-0 py-0 pb-6 lg:p-6 lg:md:p-10 lg:pt-10 min-h-screen lg:min-h-0">
84
+ {/* navigation */}
85
+ <div className="absolute top-4 right-4 lg:left-4 z-20 flex gap-2">
86
+ <Button variant="outline" size="icon">
87
+ <a href={kcContext.client.baseUrl ?? redirectUrlOrigin}>
88
+ <FiHome />
89
+ </a>
90
+ </Button>
91
+
92
+ {enabledLanguages.length > 1 && <Languages />}
93
+
94
+ {kcContext.darkMode !== false && <ModeToggle />}
95
+ </div>
96
+
97
+ {/* Mobile header with logo */}
98
+ <div className="lg:hidden relative pt-8 px-6">
99
+ {/* Logo and welcome message */}
100
+ <div className="flex flex-col items-center justify-center gap-3 mt-4">
101
+ <div className=" mb-4 flex items-center gap-3">
102
+ <img src={companylogo} alt="Logo" />
103
+ <span className=" text-xl"> {APP_NAME}</span>
104
+ </div>
105
+ </div>
106
+ </div>
107
+
108
+ <div className="flex flex-1 items-start lg:items-center justify-center lg:mt-0 ">
109
+ <div className="w-full max-w-xl ">
110
+ <Card className=" shadow-none bg-transparent lg:bg-card border-0 lg:rounded-lg lg:border lg:shadow-sm rounded-t-2xl">
111
+ <CardHeader className="text-center mb-3 px-6 pt-8 pb-4 lg:pt-6">
112
+ <CardTitle>
113
+ {(() => {
114
+ const node = !(
115
+ auth !== undefined &&
116
+ auth.showUsername &&
117
+ !auth.showResetCredentials
118
+ ) ? (
119
+ <h1 className="text-xl">{headerNode}</h1>
120
+ ) : (
121
+ <div
122
+ id="kc-username"
123
+ className="flex items-center justify-center gap-2"
124
+ >
125
+ <label
126
+ className="font-semibold text-lg"
127
+ id="kc-attempted-username"
128
+ >
129
+ {auth.attemptedUsername}
130
+ </label>
131
+
132
+ <TooltipProvider>
133
+ <Tooltip>
134
+ <TooltipTrigger asChild>
135
+ <Button
136
+ variant="outline"
137
+ size="icon"
138
+ asChild
139
+ >
140
+ <a
141
+ id="reset-login"
142
+ href={
143
+ url.loginRestartFlowUrl
144
+ }
145
+ aria-label={msgStr(
146
+ "restartLoginTooltip"
147
+ )}
148
+ >
149
+ <RotateCcw className="h-4 w-4" />
150
+ </a>
151
+ </Button>
152
+ </TooltipTrigger>
153
+ <TooltipContent>
154
+ <p>
155
+ {msg(
156
+ "restartLoginTooltip"
157
+ )}
158
+ </p>
159
+ </TooltipContent>
160
+ </Tooltip>
161
+ </TooltipProvider>
162
+ </div>
163
+ );
164
+
165
+ if (displayRequiredFields) {
166
+ return (
167
+ <div className="flex items-center justify-between gap-2">
168
+ <div>{node}</div>
169
+ <div>
170
+ <span className="subtitle">
171
+ <span className="text-red-500">
172
+ *
173
+ </span>
174
+ {msg("requiredFields")}
175
+ </span>
176
+ </div>
177
+ </div>
178
+ );
179
+ }
180
+
181
+ return node;
182
+ })()}
183
+ </CardTitle>
184
+ </CardHeader>
185
+ <CardContent className="px-6 pb-8">
186
+ <div id="kc-content">
187
+ <div id="kc-content-wrapper">
188
+ {displayMessage &&
189
+ message !== undefined &&
190
+ (message.type !== "warning" ||
191
+ !isAppInitiatedAction) && (
192
+ <Alert
193
+ variant={message.type}
194
+ className="my-3"
195
+ >
196
+ <AlertDescription>
197
+ <div>
198
+ <span
199
+ dangerouslySetInnerHTML={{
200
+ __html: kcSanitize(
201
+ message.summary
202
+ )
203
+ }}
204
+ />
205
+ </div>
206
+ </AlertDescription>
207
+ </Alert>
208
+ )}
209
+ <div className="children">{children}</div>
210
+ {socialProvidersNode}
211
+ {auth !== undefined &&
212
+ auth.showTryAnotherWayLink && (
213
+ <form
214
+ id="kc-select-try-another-way-form"
215
+ action={url.loginAction}
216
+ method="post"
217
+ >
218
+ <div
219
+ className={kcClsx(
220
+ "kcFormGroupClass"
221
+ )}
222
+ >
223
+ <input
224
+ type="hidden"
225
+ name="tryAnotherWay"
226
+ value="on"
227
+ />
228
+ <a
229
+ href="#"
230
+ id="try-another-way"
231
+ onClick={() => {
232
+ document.forms[
233
+ "kc-select-try-another-way-form" as never
234
+ ].submit();
235
+ return false;
236
+ }}
237
+ >
238
+ {msg("doTryAnotherWay")}
239
+ </a>
240
+ </div>
241
+ </form>
242
+ )}
243
+ {displayInfo && (
244
+ <div className="text-center text-sm mt-4">
245
+ {infoNode}
246
+ </div>
247
+ )}
248
+ </div>
249
+ </div>
250
+ </CardContent>
251
+ </Card>
252
+ </div>
253
+ </div>
254
+ </div>
255
+
256
+ <div className="bg-slate-950 relative hidden lg:block dark:bg-white/5">
257
+ <div className="flex items-center pt-20 h-full justify-center z-1">
258
+ <div className="absolute right-0 top-0 w-full max-w-62.5 xl:max-w-112.5">
259
+ <img src={shape} alt="grid" />
260
+ </div>
261
+ <div className="absolute bottom-0 left-0 w-full max-w-62.5 rotate-180 xl:max-w-112.5">
262
+ <img src={shape} alt="grid" />
263
+ </div>
264
+
265
+ <div className="flex justify-center my-auto flex-col items-center max-w-xs">
266
+ <div className=" mb-4 flex items-center gap-3">
267
+ <img src={companylogo} alt="Logo" />
268
+ <span className="text-white text-xl"> {APP_NAME}</span>
269
+ </div>
270
+
271
+ <p className="text-center text-gray-400 dark:text-white/60">
272
+ {msg("welcomeMessage")}
273
+ </p>
274
+ </div>
275
+ </div>
276
+ </div>
277
+ </div>
278
+ );
279
+ }
@@ -1 +1 @@
1
- export * from "./Template";
1
+ export * from "./Template";