@sybilion/uilib 1.2.8 → 1.2.9
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.
- package/dist/esm/components/widgets/SignInPage/SignInPage.js +25 -0
- package/dist/esm/components/widgets/SybilionAuthLayout/SybilionAuthHeadline.js +8 -0
- package/dist/esm/components/widgets/SybilionAuthLayout/SybilionAuthHeadline.styl.js +7 -0
- package/dist/esm/components/widgets/SybilionAuthLayout/SybilionAuthLayout.js +16 -0
- package/dist/esm/components/widgets/SybilionAuthLayout/SybilionAuthLayout.styl.js +7 -0
- package/dist/esm/components/widgets/SybilionSignInPanel/SybilionSignInPanel.js +11 -0
- package/dist/esm/components/widgets/SybilionSignInPanel/SybilionSignInPanel.styl.js +7 -0
- package/dist/esm/index.js +4 -0
- package/dist/esm/types/src/components/widgets/SignInPage/SignInPage.d.ts +10 -0
- package/dist/esm/types/src/components/widgets/SignInPage/index.d.ts +1 -0
- package/dist/esm/types/src/components/widgets/SybilionAuthLayout/SybilionAuthHeadline.d.ts +1 -0
- package/dist/esm/types/src/components/widgets/SybilionAuthLayout/SybilionAuthLayout.d.ts +14 -0
- package/dist/esm/types/src/components/widgets/SybilionAuthLayout/index.d.ts +2 -0
- package/dist/esm/types/src/components/widgets/SybilionSignInPanel/SybilionSignInPanel.d.ts +11 -0
- package/dist/esm/types/src/components/widgets/SybilionSignInPanel/index.d.ts +1 -0
- package/dist/esm/types/src/index.d.ts +3 -0
- package/docs/standalone-apps.md +36 -16
- package/package.json +3 -2
- package/src/assets/sybilion_bg.svg +8 -0
- package/src/components/widgets/SignInPage/SignInPage.tsx +84 -0
- package/src/components/widgets/SignInPage/index.ts +1 -0
- package/src/components/widgets/SybilionAuthLayout/SybilionAuthHeadline.styl +26 -0
- package/src/components/widgets/SybilionAuthLayout/SybilionAuthHeadline.styl.d.ts +2 -0
- package/src/components/widgets/SybilionAuthLayout/SybilionAuthHeadline.tsx +18 -0
- package/src/components/widgets/SybilionAuthLayout/SybilionAuthLayout.styl +79 -0
- package/src/components/widgets/SybilionAuthLayout/SybilionAuthLayout.styl.d.ts +2 -0
- package/src/components/widgets/SybilionAuthLayout/SybilionAuthLayout.tsx +64 -0
- package/src/components/widgets/SybilionAuthLayout/index.ts +6 -0
- package/src/components/widgets/SybilionSignInPanel/SybilionSignInPanel.styl +48 -0
- package/src/components/widgets/SybilionSignInPanel/SybilionSignInPanel.styl.d.ts +2 -0
- package/src/components/widgets/SybilionSignInPanel/SybilionSignInPanel.tsx +59 -0
- package/src/components/widgets/SybilionSignInPanel/index.ts +4 -0
- package/src/index.ts +3 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { SybilionAuthLayout } from '../SybilionAuthLayout/SybilionAuthLayout.js';
|
|
3
|
+
import '../SybilionAuthLayout/SybilionAuthHeadline.styl.js';
|
|
4
|
+
import { useSybilionAuth } from '../../../sybilion-auth/SybilionAuthProvider.js';
|
|
5
|
+
import { SybilionSignInPanel } from '../SybilionSignInPanel/SybilionSignInPanel.js';
|
|
6
|
+
|
|
7
|
+
const DEFAULT_TITLE = 'Sign In';
|
|
8
|
+
const DEFAULT_SUBTITLE = 'To get access authenticate through google or your email.';
|
|
9
|
+
function SignInPage({ title = DEFAULT_TITLE, subtitle = DEFAULT_SUBTITLE, forgotPasswordTo = '/forgot-password', releasesTo = '/releases', versionLabel, primaryButtonLabel, connectingLabel, loginRedirectOptions, heroBackgroundUrl, logoSize, containerClassName, }) {
|
|
10
|
+
const { error, loginWithRedirect, isLoading } = useSybilionAuth();
|
|
11
|
+
const handleSignIn = () => loginWithRedirect({
|
|
12
|
+
...loginRedirectOptions,
|
|
13
|
+
authorizationParams: {
|
|
14
|
+
prompt: 'login',
|
|
15
|
+
screen_hint: 'login',
|
|
16
|
+
...(typeof window !== 'undefined'
|
|
17
|
+
? { origin: window.location.origin }
|
|
18
|
+
: {}),
|
|
19
|
+
...loginRedirectOptions?.authorizationParams,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
return (jsx(SybilionAuthLayout, { title: title, subtitle: subtitle, heroBackgroundUrl: heroBackgroundUrl, logoSize: logoSize, containerClassName: containerClassName, children: jsx(SybilionSignInPanel, { onSignIn: handleSignIn, isSigningIn: isLoading, error: error, forgotPasswordTo: forgotPasswordTo, releasesTo: releasesTo, versionLabel: versionLabel, primaryButtonLabel: primaryButtonLabel, connectingLabel: connectingLabel }) }));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export { SignInPage };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import S from './SybilionAuthHeadline.styl.js';
|
|
3
|
+
|
|
4
|
+
function SybilionAuthHeadline() {
|
|
5
|
+
return (jsx("div", { className: S.root, children: jsxs("div", { className: S.headline, children: [jsxs("p", { className: S.headlineParagraph, children: [jsx("span", { children: "External volatility" }), jsx("span", {})] }), jsx("p", { className: S.headlineParagraph, children: "turned into" }), jsx("p", { className: S.headlineParagraph, children: jsx("span", { className: S.headlineCyan, children: "confident decisions" }) })] }) }));
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export { SybilionAuthHeadline };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styleInject from 'style-inject';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".SybilionAuthHeadline_root__iExEN{align-items:center;display:flex;flex-direction:column;font-family:var(--font-family-heading);font-weight:300;height:100%;justify-content:center;padding:64px 48px;position:relative;text-shadow:0 0 2px var(--background);width:100%;z-index:10}.SybilionAuthHeadline_headline__pkjEh{font-size:40px;line-height:48px;max-width:480px;text-align:left;width:100%}.SybilionAuthHeadline_headlineParagraph__jeOTl{margin:0}.SybilionAuthHeadline_headlineCyan__26sg2{color:#27d1ef}";
|
|
4
|
+
var S = {"root":"SybilionAuthHeadline_root__iExEN","headline":"SybilionAuthHeadline_headline__pkjEh","headlineParagraph":"SybilionAuthHeadline_headlineParagraph__jeOTl","headlineCyan":"SybilionAuthHeadline_headlineCyan__26sg2"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { S as default };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import cn from 'classnames';
|
|
3
|
+
import { Logo } from '../../ui/Logo/Logo.js';
|
|
4
|
+
import { SybilionAuthHeadline } from './SybilionAuthHeadline.js';
|
|
5
|
+
import S from './SybilionAuthLayout.styl.js';
|
|
6
|
+
|
|
7
|
+
/** Same convention as {@link SYBILION_STANDALONE_LOGO_PUBLIC_URL}: copy `sybilion-bg.svg` from the package into `public/`. */
|
|
8
|
+
const SYBILION_STANDALONE_AUTH_HERO_BG_PUBLIC_URL = '/sybilion_bg.svg';
|
|
9
|
+
function SybilionAuthLayout({ title, subtitle, children, logoSize, containerClassName, heroBackgroundUrl = SYBILION_STANDALONE_AUTH_HERO_BG_PUBLIC_URL, }) {
|
|
10
|
+
const bg = heroBackgroundUrl
|
|
11
|
+
? `url(${JSON.stringify(heroBackgroundUrl)})`
|
|
12
|
+
: 'none';
|
|
13
|
+
return (jsxs("div", { className: S.root, children: [jsxs("div", { className: S.leftPanel, children: [jsx("div", { className: S.bgImage, style: { backgroundImage: bg }, "aria-hidden": true }), jsx("div", { className: S.logoContainer, children: jsx(Logo, { className: S.logo, size: logoSize }) }), jsx(SybilionAuthHeadline, {})] }), jsx("div", { className: S.rightPanel, children: jsxs("div", { className: cn(S.formContainer, containerClassName), children: [jsxs("div", { className: S.header, children: [jsx("h1", { className: S.title, children: title }), subtitle && jsx("p", { className: S.subtitle, children: subtitle })] }), children] }) })] }));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export { SYBILION_STANDALONE_AUTH_HERO_BG_PUBLIC_URL, SybilionAuthLayout };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styleInject from 'style-inject';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".SybilionAuthLayout_root__jM5q5{display:flex;height:100vh;width:100%}.SybilionAuthLayout_leftPanel__MoyRZ{display:none}@media (min-width:768px){.SybilionAuthLayout_leftPanel__MoyRZ{background-color:var(--secondary);border-bottom-left-radius:var(--p-6);border-bottom-right-radius:var(--p-1);border-top-left-radius:var(--p-6);border-top-right-radius:var(--p-1);display:flex;overflow:hidden;position:relative;width:50%}.dark .SybilionAuthLayout_leftPanel__MoyRZ{background-color:var(--page-color-alpha-800)}}.SybilionAuthLayout_bgImage__LvCav{background-position:0 100%;background-repeat:no-repeat;background-size:contain;bottom:0;height:300px;left:0;position:absolute;width:300px}.SybilionAuthLayout_logoContainer__jR7Dw{align-items:center;display:flex;left:0;min-height:94px;padding:16px 48px;position:absolute;top:0;z-index:10}.SybilionAuthLayout_logo__LxBpo{height:24px;width:24px}.SybilionAuthLayout_rightPanel__pKcYC{align-items:center;background-color:var(--background);display:flex;flex:1;flex-direction:column;justify-content:center;padding:48px 64px}.SybilionAuthLayout_formContainer__xMCFZ{max-width:480px;width:100%}.SybilionAuthLayout_header__OOsdf{margin-bottom:36px}.SybilionAuthLayout_title__iYcZD{color:var(--foreground);font-family:var(--font-family-heading);font-size:30px;font-weight:400;line-height:42px;margin:0 0 6px}.SybilionAuthLayout_subtitle__sWv5p{color:var(--muted-foreground);font-family:Manrope,sans-serif;font-size:14px;font-weight:500;line-height:16px;margin:0}";
|
|
4
|
+
var S = {"root":"SybilionAuthLayout_root__jM5q5","leftPanel":"SybilionAuthLayout_leftPanel__MoyRZ","bgImage":"SybilionAuthLayout_bgImage__LvCav","logoContainer":"SybilionAuthLayout_logoContainer__jR7Dw","logo":"SybilionAuthLayout_logo__LxBpo","rightPanel":"SybilionAuthLayout_rightPanel__pKcYC","formContainer":"SybilionAuthLayout_formContainer__xMCFZ","header":"SybilionAuthLayout_header__OOsdf","title":"SybilionAuthLayout_title__iYcZD","subtitle":"SybilionAuthLayout_subtitle__sWv5p"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { S as default };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Link } from 'react-router-dom';
|
|
3
|
+
import { Button } from '../../ui/Button/Button.js';
|
|
4
|
+
import S from './SybilionSignInPanel.styl.js';
|
|
5
|
+
|
|
6
|
+
function SybilionSignInPanel({ onSignIn, isSigningIn = false, error, forgotPasswordTo, releasesTo, versionLabel, primaryButtonLabel = 'Sign-in', connectingLabel = 'Connecting...', }) {
|
|
7
|
+
const signingIn = Boolean(isSigningIn);
|
|
8
|
+
return (jsxs(Fragment, { children: [jsx("div", { className: S.socialButtonContainer, children: jsx(Button, { variant: "outline", type: "button", className: S.socialButton, onClick: () => void onSignIn(), disabled: signingIn, children: signingIn ? connectingLabel : primaryButtonLabel }) }), error ? jsx("div", { className: S.errorMessage, children: error }) : null, jsx("div", { className: S.forgotPassword, children: jsx(Link, { to: forgotPasswordTo, className: S.forgotPasswordLink, children: "Forgot password?" }) }), releasesTo && versionLabel ? (jsxs(Link, { className: S.version, to: releasesTo, children: ["v", versionLabel] })) : null] }));
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export { SybilionSignInPanel };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import styleInject from 'style-inject';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".SybilionSignInPanel_socialButtonContainer__lKNpp{display:flex;gap:10px;margin-bottom:10px;width:100%}.SybilionSignInPanel_socialButton__TqlKb{border:1px solid var(--border);border-radius:14px;flex:1;font-size:14px;font-weight:600;height:48px;padding:14px 16px}.SybilionSignInPanel_errorMessage__o8Q-m{color:red;font-size:14px;margin-bottom:10px;padding:10px}.SybilionSignInPanel_forgotPassword__47q20{margin-bottom:24px;text-align:right}.SybilionSignInPanel_forgotPasswordLink__lOJCv{color:var(--primary);font-family:Manrope,sans-serif;font-size:14px;font-weight:500;text-decoration:none;transition:opacity .2s}.SybilionSignInPanel_forgotPasswordLink__lOJCv:hover{opacity:.8}.SybilionSignInPanel_version__d5KAz{box-sizing:border-box;color:var(--muted-foreground);display:block;font-size:14px;margin-top:var(--p-8);opacity:.5;padding-bottom:var(--p-2);text-align:center;transition:opacity .3s ease-out;white-space:nowrap;width:100%}";
|
|
4
|
+
var S = {"socialButtonContainer":"SybilionSignInPanel_socialButtonContainer__lKNpp","socialButton":"SybilionSignInPanel_socialButton__TqlKb","errorMessage":"SybilionSignInPanel_errorMessage__o8Q-m","forgotPassword":"SybilionSignInPanel_forgotPassword__47q20","forgotPasswordLink":"SybilionSignInPanel_forgotPasswordLink__lOJCv","version":"SybilionSignInPanel_version__d5KAz"};
|
|
5
|
+
styleInject(css_248z);
|
|
6
|
+
|
|
7
|
+
export { S as default };
|
package/dist/esm/index.js
CHANGED
|
@@ -86,6 +86,10 @@ export { findWorkspaceAppByPathname, workspaceAppSlugPath } from './components/u
|
|
|
86
86
|
export { SidebarDatasetsItemsGrouped } from './components/widgets/SidebarDatasetsItemsGrouped/SidebarDatasetsItemsGrouped.js';
|
|
87
87
|
export { groupSidebarDatasets } from './components/widgets/SidebarDatasetsItemsGrouped/groupSidebarDatasets.js';
|
|
88
88
|
export { SybilionAppHeader } from './components/widgets/SybilionAppHeader/SybilionAppHeader.js';
|
|
89
|
+
export { SYBILION_STANDALONE_AUTH_HERO_BG_PUBLIC_URL, SybilionAuthLayout } from './components/widgets/SybilionAuthLayout/SybilionAuthLayout.js';
|
|
90
|
+
export { SybilionAuthHeadline } from './components/widgets/SybilionAuthLayout/SybilionAuthHeadline.js';
|
|
91
|
+
export { SybilionSignInPanel } from './components/widgets/SybilionSignInPanel/SybilionSignInPanel.js';
|
|
92
|
+
export { SignInPage } from './components/widgets/SignInPage/SignInPage.js';
|
|
89
93
|
export { ChartTooltipItem } from './components/ui/Chart/components/ChartTooltipItem.js';
|
|
90
94
|
export { ChartLegendItem } from './components/ui/Chart/components/ChartLegendItem.js';
|
|
91
95
|
export { CustomChartLegend } from './components/ui/Chart/components/CustomChartLegend/CustomChartLegend.js';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RedirectLoginOptions } from '@auth0/auth0-react';
|
|
2
|
+
import { type SybilionAuthLayoutProps } from '#uilib/components/widgets/SybilionAuthLayout';
|
|
3
|
+
import { type SybilionSignInPanelProps } from '../SybilionSignInPanel';
|
|
4
|
+
export type SignInPageProps = Pick<SybilionAuthLayoutProps, 'heroBackgroundUrl' | 'logoSize' | 'containerClassName'> & Pick<SybilionSignInPanelProps, 'forgotPasswordTo' | 'releasesTo' | 'versionLabel' | 'primaryButtonLabel' | 'connectingLabel'> & {
|
|
5
|
+
title?: string;
|
|
6
|
+
subtitle?: string;
|
|
7
|
+
/** Extra Auth0 `loginWithRedirect` options; merged with default sign-in params. */
|
|
8
|
+
loginRedirectOptions?: RedirectLoginOptions;
|
|
9
|
+
};
|
|
10
|
+
export declare function SignInPage({ title, subtitle, forgotPasswordTo, releasesTo, versionLabel, primaryButtonLabel, connectingLabel, loginRedirectOptions, heroBackgroundUrl, logoSize, containerClassName, }: SignInPageProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SignInPage, type SignInPageProps } from './SignInPage';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function SybilionAuthHeadline(): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { LogoSize } from '#uilib/components/ui/Logo/Logo.types';
|
|
3
|
+
/** Same convention as {@link SYBILION_STANDALONE_LOGO_PUBLIC_URL}: copy `sybilion-bg.svg` from the package into `public/`. */
|
|
4
|
+
export declare const SYBILION_STANDALONE_AUTH_HERO_BG_PUBLIC_URL: "/sybilion_bg.svg";
|
|
5
|
+
export type SybilionAuthLayoutProps = {
|
|
6
|
+
title: string;
|
|
7
|
+
subtitle?: string;
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
logoSize?: LogoSize;
|
|
10
|
+
containerClassName?: string;
|
|
11
|
+
/** Public URL for the hero watermark SVG (default {@link SYBILION_STANDALONE_AUTH_HERO_BG_PUBLIC_URL}). */
|
|
12
|
+
heroBackgroundUrl?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function SybilionAuthLayout({ title, subtitle, children, logoSize, containerClassName, heroBackgroundUrl, }: SybilionAuthLayoutProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type SybilionSignInPanelProps = {
|
|
2
|
+
onSignIn: () => void | Promise<void>;
|
|
3
|
+
isSigningIn?: boolean;
|
|
4
|
+
error?: string | null;
|
|
5
|
+
forgotPasswordTo: string;
|
|
6
|
+
releasesTo?: string;
|
|
7
|
+
versionLabel?: string;
|
|
8
|
+
primaryButtonLabel?: string;
|
|
9
|
+
connectingLabel?: string;
|
|
10
|
+
};
|
|
11
|
+
export declare function SybilionSignInPanel({ onSignIn, isSigningIn, error, forgotPasswordTo, releasesTo, versionLabel, primaryButtonLabel, connectingLabel, }: SybilionSignInPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SybilionSignInPanel, type SybilionSignInPanelProps, } from './SybilionSignInPanel';
|
|
@@ -58,3 +58,6 @@ export * from './components/ui/VimeoEmbed';
|
|
|
58
58
|
export * from './components/ui/WorkspaceAppSwitcher';
|
|
59
59
|
export * from './components/widgets/SidebarDatasetsItemsGrouped';
|
|
60
60
|
export * from './components/widgets/SybilionAppHeader';
|
|
61
|
+
export * from './components/widgets/SybilionAuthLayout';
|
|
62
|
+
export * from './components/widgets/SybilionSignInPanel';
|
|
63
|
+
export * from './components/widgets/SignInPage';
|
package/docs/standalone-apps.md
CHANGED
|
@@ -40,15 +40,17 @@ Import tokens/fonts once (typically `src/main.tsx`):
|
|
|
40
40
|
import '@sybilion/uilib/standalone-global.css';
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
### Branding (
|
|
43
|
+
### Branding (static SVGs + optional tab icon)
|
|
44
44
|
|
|
45
|
-
**Header:** **`
|
|
45
|
+
**Header + auth hero:** Copy packaged SVGs into **`public/`** so **`Logo`** (**`SYBILION_STANDALONE_LOGO_PUBLIC_URL`** → **`/logo.svg`**) and **`SybilionAuthLayout`** (**`SYBILION_STANDALONE_AUTH_HERO_BG_PUBLIC_URL`** → **`/sybilion_bg.svg`**) resolve at runtime. Package paths: **`@sybilion/uilib/logo.svg`**, **`@sybilion/uilib/sybilion-bg.svg`**.
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
mkdir -p public
|
|
48
|
+
mkdir -p public \
|
|
49
|
+
&& cp node_modules/@sybilion/uilib/logo.svg public/logo.svg \
|
|
50
|
+
&& cp node_modules/@sybilion/uilib/sybilion-bg.svg public/sybilion_bg.svg
|
|
49
51
|
```
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
Logo source in the package: **`src/assets/logo.svg`** (**cyan** glyph).
|
|
52
54
|
|
|
53
55
|
**Browser tab (optional):** The favicon (tiny icon next to the tab title) and the document title come from **`index.html`**, not from React. **`Logo`** does not set them. To replace Vite’s default tab icon with the package logo, add **`href="/logo.svg"`** — same as **`SYBILION_STANDALONE_LOGO_PUBLIC_URL`** from **`@sybilion/uilib`** — plus **`<title>`** in **`index.html`** `<head>`:
|
|
54
56
|
|
|
@@ -266,6 +268,20 @@ useEffect(() => {
|
|
|
266
268
|
|
|
267
269
|
Pass `user` (or `null` while loading with `isLoading` on `NavUserHeader`) and `isAuthenticated` to `SybilionAppHeader`.
|
|
268
270
|
|
|
271
|
+
### Sign-in page (unauthenticated)
|
|
272
|
+
|
|
273
|
+
Agents building the Auth0 entry route:
|
|
274
|
+
|
|
275
|
+
1. **Public assets:** Same **`public/`** SVG setup as §1 _Branding (static SVGs + optional tab icon)_ (**`/sybilion_bg.svg`** for **`SYBILION_STANDALONE_AUTH_HERO_BG_PUBLIC_URL`** / **`SybilionAuthLayout`**).
|
|
276
|
+
|
|
277
|
+
2. **Routing:** Register **`/sign-in`** (and your Auth0 **`/callback`** route if applicable) **outside** **`AppLayout`** — full viewport auth chrome must not sit under **`AppShell`** / sidebar / **`SybilionAppHeader`**. Pattern: top-level `<Routes>` with `<Route path="/sign-in" … />` as a sibling of the branch that renders **`AppLayout`**, both wrapped by **`SybilionAuthProvider`** (§3).
|
|
278
|
+
|
|
279
|
+
3. **Composition:**
|
|
280
|
+
- **`SignInPage`** (`@sybilion/uilib`) — drop-in when **`SybilionAuthProvider`** wraps the tree. Calls **`useSybilionAuth`**. **`loginWithRedirect`** merges defaults (`prompt`, `screen_hint`, `origin`) with optional **`loginRedirectOptions`** / **`authorizationParams`** for tenant-specific **`connection`** or audiences.
|
|
281
|
+
- **Custom:** compose **`SybilionAuthLayout`** + **`SybilionSignInPanel`** and wire **`loginWithRedirect`** yourself from **`useSybilionAuth`**.
|
|
282
|
+
|
|
283
|
+
4. **Footer chip:** Pass **`versionLabel`** into **`SignInPage`** (or **`SybilionSignInPanel`**) when you want **`v…`** linked to **`releasesTo`** (default **`/releases`**).
|
|
284
|
+
|
|
269
285
|
## 4. Layout (AppShell)
|
|
270
286
|
|
|
271
287
|
With §2 `sybilionSdk` and §3 `AppProviders` / `SybilionAuthProvider` defined, compose routing + shell so Auth0 callbacks and JWT-backed hooks wrap the whole UI.
|
|
@@ -488,18 +504,19 @@ Composition: `PageScroll` → `AppShell` → `AppSidebar` → `AppShellMainConte
|
|
|
488
504
|
|
|
489
505
|
### Greenfield checklist (agents)
|
|
490
506
|
|
|
491
|
-
| Step | Deliverable
|
|
492
|
-
| ------------------ |
|
|
493
|
-
| React / router | **`react`**, **`react-dom`**, **`react-router-dom`**, **`@auth0/auth0-react`** (and **`vite`** if applicable) aligned with **`@sybilion/uilib`** **`package.json`** — §1 _React ecosystem versions_.
|
|
494
|
-
| Env files | **`.env.example`** (committed) + **`.env`** locally; **`PORT=3000`** recommended for Auth0 test tenant; **`VITE_*`** as in §1 table.
|
|
495
|
-
| Scripts | **`package.json`** includes mandatory **`dev`** (e.g. `"vite"`); optional **`build`**, **`preview`**.
|
|
496
|
-
| Vite proxy | **`vite.config.ts`** spreads **`sybilionStandaloneViteDev({ mode })`**; SDK **`baseUrl`** empty in dev (§2).
|
|
497
|
-
| Files | `src/libs/sybilion-sdk.ts`, `AppProviders.tsx`, `AppLayout.tsx`, `AppSidebar.tsx`, `App.tsx`, `main.tsx`, route pages under e.g. `src/pages/`.
|
|
498
|
-
| Branding | **`public/logo.svg`**
|
|
499
|
-
|
|
|
500
|
-
|
|
|
501
|
-
|
|
|
502
|
-
|
|
|
507
|
+
| Step | Deliverable |
|
|
508
|
+
| ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
509
|
+
| React / router | **`react`**, **`react-dom`**, **`react-router-dom`**, **`@auth0/auth0-react`** (and **`vite`** if applicable) aligned with **`@sybilion/uilib`** **`package.json`** — §1 _React ecosystem versions_. |
|
|
510
|
+
| Env files | **`.env.example`** (committed) + **`.env`** locally; **`PORT=3000`** recommended for Auth0 test tenant; **`VITE_*`** as in §1 table. |
|
|
511
|
+
| Scripts | **`package.json`** includes mandatory **`dev`** (e.g. `"vite"`); optional **`build`**, **`preview`**. |
|
|
512
|
+
| Vite proxy | **`vite.config.ts`** spreads **`sybilionStandaloneViteDev({ mode })`**; SDK **`baseUrl`** empty in dev (§2). |
|
|
513
|
+
| Files | `src/libs/sybilion-sdk.ts`, `AppProviders.tsx`, `AppLayout.tsx`, `AppSidebar.tsx`, `App.tsx`, `main.tsx`, route pages under e.g. `src/pages/`. |
|
|
514
|
+
| Branding | §1 _Branding_: **`public/logo.svg`** + **`public/sybilion_bg.svg`** (one **`mkdir` + two `cp`** block). **`index.html`**: `<title>`; optional **`<link rel="icon">`** for tab icon. |
|
|
515
|
+
| Sign-in | §3 _Sign-in page (unauthenticated)_: **`SignInPage`** or **`SybilionAuthLayout`** + **`SybilionSignInPanel`**; **`/sign-in`** not inside **`AppLayout`**; **`SybilionAuthProvider`** wraps router. |
|
|
516
|
+
| Pages + UI | **§4 Route page body** (mandatory stack) + **Discovering** (barrel-first; bespoke markup only when no export fits). |
|
|
517
|
+
| Auth0 | SPA callback / logout URLs + allowed web origins → **`http://localhost:<PORT>`** for local dev and deploy URLs (and previews). |
|
|
518
|
+
| API | **Dev:** proxy handles API traffic (no browser CORS to API). **Prod:** Sybilion backend **CORS** → your deploy `Origin`, unless API is same-origin. |
|
|
519
|
+
| Go (if applicable) | Server proxies **`/api`** to Sybilion; SPA dev **`baseUrl`** stays `''` when same-origin. |
|
|
503
520
|
|
|
504
521
|
### Glossary (high-use pieces)
|
|
505
522
|
|
|
@@ -519,6 +536,9 @@ Composition: `PageScroll` → `AppShell` → `AppSidebar` → `AppShellMainConte
|
|
|
519
536
|
| `Gap` | Spacing primitive between flex children. |
|
|
520
537
|
| `PageHeader`, `PageContent`, `PageContentSection`, … | **§4 Route page body** (roles, `breadcrumbSidebarTrigger`, example). Same barrel also has `PageTabs`, `PageColumns`, `SectionHeader`, `PageEmptyCanvas`, … |
|
|
521
538
|
| `SybilionAuthProvider` | Auth0 + Sybilion JWT (§3). |
|
|
539
|
+
| `SignInPage` | Full sign-in route using **`SybilionAuthLayout`** + **`SybilionSignInPanel`** + **`useSybilionAuth`**; §3 sign-in subsection. |
|
|
540
|
+
| `SybilionAuthLayout` | Split-view auth chrome (hero + form column); optional **`heroBackgroundUrl`** (default **`/sybilion_bg.svg`**). |
|
|
541
|
+
| `SybilionSignInPanel` | Presentational primary button, error line, forgot-password link, optional version link; §3 sign-in subsection. |
|
|
522
542
|
| `useSybilionAuth` | User session + login/logout under provider. |
|
|
523
543
|
| `useSybilionApiFetch` | Authenticated `fetch` using stored JWT. |
|
|
524
544
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sybilion/uilib",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.9",
|
|
4
4
|
"description": "Sybilion Design System — React UI components (Webpack + Stylus)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"import": "./dist/standalone/vite-sybilion-standalone-dev.js",
|
|
37
37
|
"default": "./dist/standalone/vite-sybilion-standalone-dev.js"
|
|
38
38
|
},
|
|
39
|
-
"./logo.svg": "./src/assets/logo.svg"
|
|
39
|
+
"./logo.svg": "./src/assets/logo.svg",
|
|
40
|
+
"./sybilion-bg.svg": "./src/assets/sybilion_bg.svg"
|
|
40
41
|
},
|
|
41
42
|
"files": [
|
|
42
43
|
"assets",
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<svg width="312" height="309" viewBox="0 0 312 309" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect x="268.707" y="206.636" width="43.2928" height="57.7237" fill="#8EE9F7"/>
|
|
3
|
+
<rect width="43.2928" height="57.7237" transform="matrix(4.37114e-08 -1 -1 -4.37114e-08 106.365 43.848)" fill="#8EE9F7"/>
|
|
4
|
+
<rect x="268.707" y="206.639" width="57.7237" height="104.624" transform="rotate(180 268.707 206.639)" fill="#8EE9F7"/>
|
|
5
|
+
<rect x="48.6343" y="43.848" width="57.7237" height="104.624" transform="rotate(90 48.6343 43.848)" fill="#8EE9F7"/>
|
|
6
|
+
<rect width="57.7237" height="104.624" transform="matrix(-4.37114e-08 1 1 4.37114e-08 106.365 43.848)" fill="#8EE9F7"/>
|
|
7
|
+
<rect width="57.7237" height="104.624" transform="matrix(-1 0 0 1 268.707 264.36)" fill="#8EE9F7"/>
|
|
8
|
+
</svg>
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { RedirectLoginOptions } from '@auth0/auth0-react';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
SybilionAuthLayout,
|
|
5
|
+
type SybilionAuthLayoutProps,
|
|
6
|
+
} from '#uilib/components/widgets/SybilionAuthLayout';
|
|
7
|
+
import { useSybilionAuth } from '#uilib/sybilion-auth/SybilionAuthProvider';
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
SybilionSignInPanel,
|
|
11
|
+
type SybilionSignInPanelProps,
|
|
12
|
+
} from '../SybilionSignInPanel';
|
|
13
|
+
|
|
14
|
+
export type SignInPageProps = Pick<
|
|
15
|
+
SybilionAuthLayoutProps,
|
|
16
|
+
'heroBackgroundUrl' | 'logoSize' | 'containerClassName'
|
|
17
|
+
> &
|
|
18
|
+
Pick<
|
|
19
|
+
SybilionSignInPanelProps,
|
|
20
|
+
| 'forgotPasswordTo'
|
|
21
|
+
| 'releasesTo'
|
|
22
|
+
| 'versionLabel'
|
|
23
|
+
| 'primaryButtonLabel'
|
|
24
|
+
| 'connectingLabel'
|
|
25
|
+
> & {
|
|
26
|
+
title?: string;
|
|
27
|
+
subtitle?: string;
|
|
28
|
+
/** Extra Auth0 `loginWithRedirect` options; merged with default sign-in params. */
|
|
29
|
+
loginRedirectOptions?: RedirectLoginOptions;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const DEFAULT_TITLE = 'Sign In';
|
|
33
|
+
const DEFAULT_SUBTITLE =
|
|
34
|
+
'To get access authenticate through google or your email.';
|
|
35
|
+
|
|
36
|
+
export function SignInPage({
|
|
37
|
+
title = DEFAULT_TITLE,
|
|
38
|
+
subtitle = DEFAULT_SUBTITLE,
|
|
39
|
+
forgotPasswordTo = '/forgot-password',
|
|
40
|
+
releasesTo = '/releases',
|
|
41
|
+
versionLabel,
|
|
42
|
+
primaryButtonLabel,
|
|
43
|
+
connectingLabel,
|
|
44
|
+
loginRedirectOptions,
|
|
45
|
+
heroBackgroundUrl,
|
|
46
|
+
logoSize,
|
|
47
|
+
containerClassName,
|
|
48
|
+
}: SignInPageProps) {
|
|
49
|
+
const { error, loginWithRedirect, isLoading } = useSybilionAuth();
|
|
50
|
+
|
|
51
|
+
const handleSignIn = () =>
|
|
52
|
+
loginWithRedirect({
|
|
53
|
+
...loginRedirectOptions,
|
|
54
|
+
authorizationParams: {
|
|
55
|
+
prompt: 'login',
|
|
56
|
+
screen_hint: 'login',
|
|
57
|
+
...(typeof window !== 'undefined'
|
|
58
|
+
? { origin: window.location.origin }
|
|
59
|
+
: {}),
|
|
60
|
+
...loginRedirectOptions?.authorizationParams,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<SybilionAuthLayout
|
|
66
|
+
title={title}
|
|
67
|
+
subtitle={subtitle}
|
|
68
|
+
heroBackgroundUrl={heroBackgroundUrl}
|
|
69
|
+
logoSize={logoSize}
|
|
70
|
+
containerClassName={containerClassName}
|
|
71
|
+
>
|
|
72
|
+
<SybilionSignInPanel
|
|
73
|
+
onSignIn={handleSignIn}
|
|
74
|
+
isSigningIn={isLoading}
|
|
75
|
+
error={error}
|
|
76
|
+
forgotPasswordTo={forgotPasswordTo}
|
|
77
|
+
releasesTo={releasesTo}
|
|
78
|
+
versionLabel={versionLabel}
|
|
79
|
+
primaryButtonLabel={primaryButtonLabel}
|
|
80
|
+
connectingLabel={connectingLabel}
|
|
81
|
+
/>
|
|
82
|
+
</SybilionAuthLayout>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SignInPage, type SignInPageProps } from './SignInPage';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.root
|
|
2
|
+
display flex
|
|
3
|
+
flex-direction column
|
|
4
|
+
justify-content center
|
|
5
|
+
align-items center
|
|
6
|
+
width 100%
|
|
7
|
+
padding 64px 48px
|
|
8
|
+
position relative
|
|
9
|
+
z-index 10
|
|
10
|
+
height 100%
|
|
11
|
+
font-family var(--font-family-heading)
|
|
12
|
+
font-weight 300
|
|
13
|
+
text-shadow 0 0 2px var(--background)
|
|
14
|
+
|
|
15
|
+
.headline
|
|
16
|
+
font-size 40px
|
|
17
|
+
line-height 48px
|
|
18
|
+
text-align left
|
|
19
|
+
width 100%
|
|
20
|
+
max-width 480px
|
|
21
|
+
|
|
22
|
+
.headlineParagraph
|
|
23
|
+
margin 0
|
|
24
|
+
|
|
25
|
+
.headlineCyan
|
|
26
|
+
color #27d1ef
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import S from './SybilionAuthHeadline.styl';
|
|
2
|
+
|
|
3
|
+
export function SybilionAuthHeadline() {
|
|
4
|
+
return (
|
|
5
|
+
<div className={S.root}>
|
|
6
|
+
<div className={S.headline}>
|
|
7
|
+
<p className={S.headlineParagraph}>
|
|
8
|
+
<span>External volatility</span>
|
|
9
|
+
<span></span>
|
|
10
|
+
</p>
|
|
11
|
+
<p className={S.headlineParagraph}>turned into</p>
|
|
12
|
+
<p className={S.headlineParagraph}>
|
|
13
|
+
<span className={S.headlineCyan}>confident decisions</span>
|
|
14
|
+
</p>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
.root
|
|
2
|
+
height 100vh
|
|
3
|
+
display flex
|
|
4
|
+
width 100%
|
|
5
|
+
|
|
6
|
+
.leftPanel
|
|
7
|
+
display none
|
|
8
|
+
|
|
9
|
+
@media (min-width: 768px)
|
|
10
|
+
display flex
|
|
11
|
+
width 50%
|
|
12
|
+
position relative
|
|
13
|
+
overflow hidden
|
|
14
|
+
background-color var(--secondary)
|
|
15
|
+
border-top-left-radius var(--p-6)
|
|
16
|
+
border-bottom-left-radius var(--p-6)
|
|
17
|
+
border-top-right-radius var(--p-1)
|
|
18
|
+
border-bottom-right-radius var(--p-1)
|
|
19
|
+
|
|
20
|
+
:global(.dark) &
|
|
21
|
+
background-color var(--page-color-alpha-800)
|
|
22
|
+
|
|
23
|
+
.bgImage
|
|
24
|
+
position absolute
|
|
25
|
+
bottom 0
|
|
26
|
+
left 0
|
|
27
|
+
width 300px
|
|
28
|
+
height 300px
|
|
29
|
+
background-size contain
|
|
30
|
+
background-repeat no-repeat
|
|
31
|
+
background-position left bottom
|
|
32
|
+
|
|
33
|
+
.logoContainer
|
|
34
|
+
z-index 10
|
|
35
|
+
position absolute
|
|
36
|
+
top 0
|
|
37
|
+
left 0
|
|
38
|
+
display flex
|
|
39
|
+
align-items center
|
|
40
|
+
min-height 94px
|
|
41
|
+
padding 16px 48px
|
|
42
|
+
|
|
43
|
+
.logo
|
|
44
|
+
width 24px
|
|
45
|
+
height 24px
|
|
46
|
+
|
|
47
|
+
.rightPanel
|
|
48
|
+
flex 1
|
|
49
|
+
background-color var(--background)
|
|
50
|
+
display flex
|
|
51
|
+
flex-direction column
|
|
52
|
+
justify-content center
|
|
53
|
+
align-items center
|
|
54
|
+
padding 48px 64px
|
|
55
|
+
|
|
56
|
+
.formContainer
|
|
57
|
+
// position relative
|
|
58
|
+
max-width 480px
|
|
59
|
+
width 100%
|
|
60
|
+
|
|
61
|
+
.header
|
|
62
|
+
margin-bottom 36px
|
|
63
|
+
|
|
64
|
+
.title
|
|
65
|
+
font-family var(--font-family-heading)
|
|
66
|
+
font-weight normal
|
|
67
|
+
font-size 30px
|
|
68
|
+
line-height 42px
|
|
69
|
+
margin 0
|
|
70
|
+
margin-bottom 6px
|
|
71
|
+
color var(--foreground)
|
|
72
|
+
|
|
73
|
+
.subtitle
|
|
74
|
+
font-size 14px
|
|
75
|
+
color var(--muted-foreground)
|
|
76
|
+
line-height 16px
|
|
77
|
+
margin 0
|
|
78
|
+
font-family 'Manrope', sans-serif
|
|
79
|
+
font-weight 500
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import cn from 'classnames';
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
|
|
4
|
+
import { Logo } from '#uilib/components/ui/Logo/Logo';
|
|
5
|
+
import type { LogoSize } from '#uilib/components/ui/Logo/Logo.types';
|
|
6
|
+
|
|
7
|
+
import { SybilionAuthHeadline } from './SybilionAuthHeadline';
|
|
8
|
+
import S from './SybilionAuthLayout.styl';
|
|
9
|
+
|
|
10
|
+
/** Same convention as {@link SYBILION_STANDALONE_LOGO_PUBLIC_URL}: copy `sybilion-bg.svg` from the package into `public/`. */
|
|
11
|
+
export const SYBILION_STANDALONE_AUTH_HERO_BG_PUBLIC_URL =
|
|
12
|
+
'/sybilion_bg.svg' as const;
|
|
13
|
+
|
|
14
|
+
export type SybilionAuthLayoutProps = {
|
|
15
|
+
title: string;
|
|
16
|
+
subtitle?: string;
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
logoSize?: LogoSize;
|
|
19
|
+
containerClassName?: string;
|
|
20
|
+
/** Public URL for the hero watermark SVG (default {@link SYBILION_STANDALONE_AUTH_HERO_BG_PUBLIC_URL}). */
|
|
21
|
+
heroBackgroundUrl?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export function SybilionAuthLayout({
|
|
25
|
+
title,
|
|
26
|
+
subtitle,
|
|
27
|
+
children,
|
|
28
|
+
logoSize,
|
|
29
|
+
containerClassName,
|
|
30
|
+
heroBackgroundUrl = SYBILION_STANDALONE_AUTH_HERO_BG_PUBLIC_URL,
|
|
31
|
+
}: SybilionAuthLayoutProps) {
|
|
32
|
+
const bg = heroBackgroundUrl
|
|
33
|
+
? `url(${JSON.stringify(heroBackgroundUrl)})`
|
|
34
|
+
: 'none';
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<div className={S.root}>
|
|
38
|
+
<div className={S.leftPanel}>
|
|
39
|
+
<div
|
|
40
|
+
className={S.bgImage}
|
|
41
|
+
style={{ backgroundImage: bg }}
|
|
42
|
+
aria-hidden
|
|
43
|
+
/>
|
|
44
|
+
|
|
45
|
+
<div className={S.logoContainer}>
|
|
46
|
+
<Logo className={S.logo} size={logoSize} />
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<SybilionAuthHeadline />
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
<div className={S.rightPanel}>
|
|
53
|
+
<div className={cn(S.formContainer, containerClassName)}>
|
|
54
|
+
<div className={S.header}>
|
|
55
|
+
<h1 className={S.title}>{title}</h1>
|
|
56
|
+
{subtitle && <p className={S.subtitle}>{subtitle}</p>}
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
{children}
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
.socialButtonContainer
|
|
2
|
+
display flex
|
|
3
|
+
width 100%
|
|
4
|
+
gap 10px
|
|
5
|
+
margin-bottom 10px
|
|
6
|
+
|
|
7
|
+
.socialButton
|
|
8
|
+
flex 1
|
|
9
|
+
height 48px
|
|
10
|
+
padding 14px 16px
|
|
11
|
+
font-size 14px
|
|
12
|
+
font-weight 600
|
|
13
|
+
border-radius 14px
|
|
14
|
+
border 1px solid var(--border)
|
|
15
|
+
|
|
16
|
+
.errorMessage
|
|
17
|
+
color red
|
|
18
|
+
padding 10px
|
|
19
|
+
font-size 14px
|
|
20
|
+
margin-bottom 10px
|
|
21
|
+
|
|
22
|
+
.forgotPassword
|
|
23
|
+
text-align right
|
|
24
|
+
margin-bottom 24px
|
|
25
|
+
|
|
26
|
+
.forgotPasswordLink
|
|
27
|
+
color var(--primary)
|
|
28
|
+
text-decoration none
|
|
29
|
+
font-size 14px
|
|
30
|
+
font-family 'Manrope', sans-serif
|
|
31
|
+
font-weight 500
|
|
32
|
+
transition opacity 0.2s
|
|
33
|
+
|
|
34
|
+
&:hover
|
|
35
|
+
opacity 0.8
|
|
36
|
+
|
|
37
|
+
.version
|
|
38
|
+
display block
|
|
39
|
+
margin-top var(--p-8)
|
|
40
|
+
padding-bottom var(--p-2)
|
|
41
|
+
width 100%
|
|
42
|
+
box-sizing border-box
|
|
43
|
+
text-align center
|
|
44
|
+
font-size 14px
|
|
45
|
+
color var(--muted-foreground)
|
|
46
|
+
opacity 0.5
|
|
47
|
+
transition opacity 0.3s ease-out
|
|
48
|
+
white-space nowrap
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Link } from 'react-router-dom';
|
|
2
|
+
|
|
3
|
+
import { Button } from '#uilib/components/ui/Button';
|
|
4
|
+
|
|
5
|
+
import S from './SybilionSignInPanel.styl';
|
|
6
|
+
|
|
7
|
+
export type SybilionSignInPanelProps = {
|
|
8
|
+
onSignIn: () => void | Promise<void>;
|
|
9
|
+
isSigningIn?: boolean;
|
|
10
|
+
error?: string | null;
|
|
11
|
+
forgotPasswordTo: string;
|
|
12
|
+
releasesTo?: string;
|
|
13
|
+
versionLabel?: string;
|
|
14
|
+
primaryButtonLabel?: string;
|
|
15
|
+
connectingLabel?: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export function SybilionSignInPanel({
|
|
19
|
+
onSignIn,
|
|
20
|
+
isSigningIn = false,
|
|
21
|
+
error,
|
|
22
|
+
forgotPasswordTo,
|
|
23
|
+
releasesTo,
|
|
24
|
+
versionLabel,
|
|
25
|
+
primaryButtonLabel = 'Sign-in',
|
|
26
|
+
connectingLabel = 'Connecting...',
|
|
27
|
+
}: SybilionSignInPanelProps) {
|
|
28
|
+
const signingIn = Boolean(isSigningIn);
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<>
|
|
32
|
+
<div className={S.socialButtonContainer}>
|
|
33
|
+
<Button
|
|
34
|
+
variant="outline"
|
|
35
|
+
type="button"
|
|
36
|
+
className={S.socialButton}
|
|
37
|
+
onClick={() => void onSignIn()}
|
|
38
|
+
disabled={signingIn}
|
|
39
|
+
>
|
|
40
|
+
{signingIn ? connectingLabel : primaryButtonLabel}
|
|
41
|
+
</Button>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
{error ? <div className={S.errorMessage}>{error}</div> : null}
|
|
45
|
+
|
|
46
|
+
<div className={S.forgotPassword}>
|
|
47
|
+
<Link to={forgotPasswordTo} className={S.forgotPasswordLink}>
|
|
48
|
+
Forgot password?
|
|
49
|
+
</Link>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
{releasesTo && versionLabel ? (
|
|
53
|
+
<Link className={S.version} to={releasesTo}>
|
|
54
|
+
v{versionLabel}
|
|
55
|
+
</Link>
|
|
56
|
+
) : null}
|
|
57
|
+
</>
|
|
58
|
+
);
|
|
59
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -58,3 +58,6 @@ export * from './components/ui/VimeoEmbed';
|
|
|
58
58
|
export * from './components/ui/WorkspaceAppSwitcher';
|
|
59
59
|
export * from './components/widgets/SidebarDatasetsItemsGrouped';
|
|
60
60
|
export * from './components/widgets/SybilionAppHeader';
|
|
61
|
+
export * from './components/widgets/SybilionAuthLayout';
|
|
62
|
+
export * from './components/widgets/SybilionSignInPanel';
|
|
63
|
+
export * from './components/widgets/SignInPage';
|