mirror of
https://github.com/teamhanko/hanko.git
synced 2025-10-27 14:17:56 +08:00
fix: merge conflicts. remove import in quickstart
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@teamhanko/hanko-elements",
|
||||
"version": "0.2.0-alpha",
|
||||
"version": "0.2.1-alpha",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
@ -47,10 +47,10 @@
|
||||
],
|
||||
"homepage": "https://hanko.io",
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.51.0",
|
||||
"@typescript-eslint/parser": "^5.53.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.54.0",
|
||||
"@typescript-eslint/parser": "^5.54.0",
|
||||
"css-loader": "^6.7.3",
|
||||
"eslint": "^8.33.0",
|
||||
"eslint": "^8.35.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
"eslint-config-preact": "^1.3.0",
|
||||
"eslint-config-prettier": "^8.6.0",
|
||||
|
||||
@ -5,9 +5,8 @@ import { TranslateContext } from "@denysvuika/preact-translate";
|
||||
|
||||
import { HankoError, TechnicalError } from "@teamhanko/hanko-frontend-sdk";
|
||||
|
||||
import ExclamationMark from "../icons/ExclamationMark";
|
||||
|
||||
import styles from "./styles.sass";
|
||||
import Icon from "../icons/Icon";
|
||||
|
||||
type Props = {
|
||||
error?: Error;
|
||||
@ -28,7 +27,7 @@ const ErrorMessage = ({ error = defaultError }: Props) => {
|
||||
hidden={!error}
|
||||
>
|
||||
<span>
|
||||
<ExclamationMark />
|
||||
<Icon name={"exclamation"} />
|
||||
</span>
|
||||
<span
|
||||
id="errorMessage"
|
||||
|
||||
@ -16,5 +16,8 @@
|
||||
align-items: center
|
||||
box-sizing: border-box
|
||||
|
||||
&>span:first-child
|
||||
display: inline-flex
|
||||
|
||||
&[hidden]
|
||||
display: none
|
||||
|
||||
@ -7,9 +7,10 @@ import cx from "classnames";
|
||||
import styles from "./styles.sass";
|
||||
|
||||
import LoadingSpinner from "../icons/LoadingSpinner";
|
||||
import Icon, { IconName } from "../icons/Icon";
|
||||
|
||||
type Props = {
|
||||
title?: string
|
||||
title?: string;
|
||||
children: ComponentChildren;
|
||||
secondary?: boolean;
|
||||
isLoading?: boolean;
|
||||
@ -17,6 +18,7 @@ type Props = {
|
||||
disabled?: boolean;
|
||||
autofocus?: boolean;
|
||||
onClick?: (event: Event) => void;
|
||||
icon?: IconName;
|
||||
};
|
||||
|
||||
const Button = ({
|
||||
@ -28,6 +30,7 @@ const Button = ({
|
||||
isSuccess,
|
||||
autofocus,
|
||||
onClick,
|
||||
icon,
|
||||
}: Props) => {
|
||||
const ref = useRef(null);
|
||||
|
||||
@ -56,7 +59,15 @@ const Button = ({
|
||||
isLoading={isLoading}
|
||||
isSuccess={isSuccess}
|
||||
secondary={true}
|
||||
hasIcon={!!icon}
|
||||
>
|
||||
{icon ? (
|
||||
<Icon
|
||||
name={icon}
|
||||
secondary={secondary}
|
||||
disabled={disabled || isLoading || isSuccess}
|
||||
/>
|
||||
) : null}
|
||||
{children}
|
||||
</LoadingSpinner>
|
||||
</button>
|
||||
|
||||
@ -1,21 +1,25 @@
|
||||
import * as preact from "preact";
|
||||
|
||||
import { IconProps } from "./Icon";
|
||||
import styles from "./styles.sass";
|
||||
import cx from "classnames";
|
||||
|
||||
import styles from "./styles.sass";
|
||||
|
||||
type Props = {
|
||||
fadeOut?: boolean;
|
||||
secondary?: boolean;
|
||||
};
|
||||
|
||||
const Checkmark = ({ fadeOut, secondary }: Props) => {
|
||||
const Checkmark = ({ secondary, size, fadeOut, disabled }: IconProps) => {
|
||||
return (
|
||||
<div className={cx(styles.checkmark, fadeOut && styles.fadeOut)}>
|
||||
<div className={cx(styles.circle, secondary && styles.secondary)} />
|
||||
<div className={cx(styles.stem, secondary && styles.secondary)} />
|
||||
<div className={cx(styles.kick, secondary && styles.secondary)} />
|
||||
</div>
|
||||
<svg
|
||||
id="icon-checkmark"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="4 4 40 40"
|
||||
width={size}
|
||||
height={size}
|
||||
className={cx(
|
||||
styles.checkmark,
|
||||
secondary && styles.secondary,
|
||||
fadeOut && styles.fadeOut,
|
||||
disabled && styles.disabled
|
||||
)}
|
||||
>
|
||||
<path d="M21.05 33.1 35.2 18.95l-2.3-2.25-11.85 11.85-6-6-2.25 2.25ZM24 44q-4.1 0-7.75-1.575-3.65-1.575-6.375-4.3-2.725-2.725-4.3-6.375Q4 28.1 4 24q0-4.15 1.575-7.8 1.575-3.65 4.3-6.35 2.725-2.7 6.375-4.275Q19.9 4 24 4q4.15 0 7.8 1.575 3.65 1.575 6.35 4.275 2.7 2.7 4.275 6.35Q44 19.85 44 24q0 4.1-1.575 7.75-1.575 3.65-4.275 6.375t-6.35 4.3Q28.15 44 24 44Zm0-3q7.1 0 12.05-4.975Q41 31.05 41 24q0-7.1-4.95-12.05Q31.1 7 24 7q-7.05 0-12.025 4.95Q7 16.9 7 24q0 7.05 4.975 12.025Q16.95 41 24 41Zm0-17Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -1,14 +1,24 @@
|
||||
import * as preact from "preact";
|
||||
|
||||
import styles from "./styles.sass";
|
||||
import { IconProps } from "./Icon";
|
||||
import cx from "classnames";
|
||||
|
||||
const ExclamationMark = () => {
|
||||
const ExclamationMark = ({ size, secondary, disabled }: IconProps) => {
|
||||
return (
|
||||
<div className={styles.exclamationMark}>
|
||||
<div className={styles.circle} />
|
||||
<div className={styles.stem} />
|
||||
<div className={styles.dot} />
|
||||
</div>
|
||||
<svg
|
||||
id="icon-exclamation"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
className={cx(
|
||||
styles.exclamationMark,
|
||||
secondary && styles.secondary,
|
||||
disabled && styles.disabled
|
||||
)}
|
||||
>
|
||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-2h2v2zm0-4h-2V7h2v6z"/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
26
frontend/elements/src/components/icons/GitHub.tsx
Normal file
26
frontend/elements/src/components/icons/GitHub.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import * as preact from "preact";
|
||||
import { IconProps } from "./Icon";
|
||||
import cx from "classnames";
|
||||
import styles from "./styles.sass";
|
||||
|
||||
const GitHub = ({ size, secondary, disabled }: IconProps) => {
|
||||
return (
|
||||
<svg
|
||||
id="icon-github"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="#fff"
|
||||
viewBox="0 0 97.63 96"
|
||||
width={size}
|
||||
height={size}
|
||||
className={cx(
|
||||
styles.icon,
|
||||
secondary && styles.secondary,
|
||||
disabled && styles.disabled
|
||||
)}
|
||||
>
|
||||
<path d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z" />{" "}
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default GitHub;
|
||||
49
frontend/elements/src/components/icons/Google.tsx
Normal file
49
frontend/elements/src/components/icons/Google.tsx
Normal file
@ -0,0 +1,49 @@
|
||||
import * as preact from "preact";
|
||||
import styles from "./styles.sass";
|
||||
import { IconProps } from "./Icon";
|
||||
import cx from "classnames";
|
||||
|
||||
const Google = ({ size, disabled }: IconProps) => {
|
||||
return (
|
||||
<svg
|
||||
id="icon-google"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
className={styles.googleIcon}
|
||||
>
|
||||
<path
|
||||
className={cx(
|
||||
styles.googleIcon,
|
||||
disabled ? styles.disabled : styles.blue
|
||||
)}
|
||||
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
|
||||
/>
|
||||
<path
|
||||
className={cx(
|
||||
styles.googleIcon,
|
||||
disabled ? styles.disabled : styles.green
|
||||
)}
|
||||
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
|
||||
/>
|
||||
<path
|
||||
className={cx(
|
||||
styles.googleIcon,
|
||||
disabled ? styles.disabled : styles.yellow
|
||||
)}
|
||||
d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
|
||||
/>
|
||||
<path
|
||||
className={cx(
|
||||
styles.googleIcon,
|
||||
disabled ? styles.disabled : styles.red
|
||||
)}
|
||||
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
|
||||
/>
|
||||
<path d="M1 1h22v22H1z" fill="none" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default Google;
|
||||
36
frontend/elements/src/components/icons/Icon.tsx
Normal file
36
frontend/elements/src/components/icons/Icon.tsx
Normal file
@ -0,0 +1,36 @@
|
||||
import * as preact from "preact";
|
||||
import * as icons from "./icons";
|
||||
|
||||
export type IconName = keyof typeof icons;
|
||||
|
||||
export type IconProps = {
|
||||
secondary?: boolean;
|
||||
fadeOut?: boolean;
|
||||
disabled?: boolean;
|
||||
size?: number;
|
||||
};
|
||||
|
||||
type Props = IconProps & {
|
||||
name: IconName;
|
||||
};
|
||||
|
||||
const Icon = ({
|
||||
name,
|
||||
secondary,
|
||||
size = 18,
|
||||
fadeOut,
|
||||
disabled,
|
||||
}: Props) => {
|
||||
const Ico = icons[name];
|
||||
|
||||
return (
|
||||
<Ico
|
||||
size={size}
|
||||
secondary={secondary}
|
||||
fadeOut={fadeOut}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default Icon;
|
||||
@ -1,11 +1,7 @@
|
||||
import * as preact from "preact";
|
||||
import { ComponentChildren } from "preact";
|
||||
|
||||
import cx from "classnames";
|
||||
|
||||
import Checkmark from "./Checkmark";
|
||||
|
||||
import { ComponentChildren, Fragment } from "preact";
|
||||
import styles from "./styles.sass";
|
||||
import Icon from "./Icon";
|
||||
|
||||
export type Props = {
|
||||
children?: ComponentChildren;
|
||||
@ -13,6 +9,7 @@ export type Props = {
|
||||
isSuccess?: boolean;
|
||||
fadeOut?: boolean;
|
||||
secondary?: boolean;
|
||||
hasIcon?: boolean;
|
||||
};
|
||||
|
||||
const LoadingSpinner = ({
|
||||
@ -21,19 +18,30 @@ const LoadingSpinner = ({
|
||||
isSuccess,
|
||||
fadeOut,
|
||||
secondary,
|
||||
hasIcon,
|
||||
}: Props) => {
|
||||
return (
|
||||
<div className={styles.loadingSpinnerWrapper}>
|
||||
<Fragment>
|
||||
{isLoading ? (
|
||||
<div
|
||||
className={cx(styles.loadingSpinner, secondary && styles.secondary)}
|
||||
/>
|
||||
<div className={styles.loadingSpinnerWrapper}>
|
||||
<Icon name={"spinner"} secondary={secondary} />
|
||||
</div>
|
||||
) : isSuccess ? (
|
||||
<Checkmark fadeOut={fadeOut} secondary={secondary} />
|
||||
<div className={styles.loadingSpinnerWrapper}>
|
||||
<Icon name={"checkmark"} secondary={secondary} fadeOut={fadeOut} />
|
||||
</div>
|
||||
) : (
|
||||
children
|
||||
<div
|
||||
className={
|
||||
hasIcon
|
||||
? styles.loadingSpinnerWrapperIcon
|
||||
: styles.loadingSpinnerWrapper
|
||||
}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
35
frontend/elements/src/components/icons/Passkey.tsx
Normal file
35
frontend/elements/src/components/icons/Passkey.tsx
Normal file
@ -0,0 +1,35 @@
|
||||
import * as preact from "preact";
|
||||
import { IconProps } from "./Icon";
|
||||
import styles from "./styles.sass";
|
||||
import cx from "classnames";
|
||||
|
||||
const Passkey = ({ size, secondary, disabled }: IconProps) => {
|
||||
return (
|
||||
<svg
|
||||
id="icon-passkey"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="3 1.5 19.5 19"
|
||||
width={size}
|
||||
height={size}
|
||||
className={cx(
|
||||
styles.icon,
|
||||
secondary && styles.secondary,
|
||||
disabled && styles.disabled
|
||||
)}
|
||||
>
|
||||
<g id="icon-passkey-all">
|
||||
<circle id="icon-passkey-head" cx="10.5" cy="6" r="4.5" />
|
||||
<path
|
||||
id="icon-passkey-key"
|
||||
d="M22.5,10.5a3.5,3.5,0,1,0-5,3.15V19L19,20.5,21.5,18,20,16.5,21.5,15l-1.24-1.24A3.5,3.5,0,0,0,22.5,10.5Zm-3.5,0a1,1,0,1,1,1-1A1,1,0,0,1,19,10.5Z"
|
||||
/>
|
||||
<path
|
||||
id="icon-passkey-body"
|
||||
d="M14.44,12.52A6,6,0,0,0,12,12H9a6,6,0,0,0-6,6v2H16V14.49A5.16,5.16,0,0,1,14.44,12.52Z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default Passkey;
|
||||
25
frontend/elements/src/components/icons/Spinner.tsx
Normal file
25
frontend/elements/src/components/icons/Spinner.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import * as preact from "preact";
|
||||
import { IconProps } from "./Icon";
|
||||
import styles from "./styles.sass";
|
||||
import cx from "classnames";
|
||||
|
||||
const Spinner = ({ size, disabled }: IconProps) => {
|
||||
return (
|
||||
<svg
|
||||
id="icon-spinner"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
width={size}
|
||||
height={size}
|
||||
className={cx(styles.loadingSpinner, disabled && styles.disabled)}
|
||||
>
|
||||
<path
|
||||
d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z"
|
||||
opacity=".25"
|
||||
/>
|
||||
<path d="M10.72,19.9a8,8,0,0,1-6.5-9.79A7.77,7.77,0,0,1,10.4,4.16a8,8,0,0,1,9.49,6.52A1.54,1.54,0,0,0,21.38,12h.13a1.37,1.37,0,0,0,1.38-1.54,11,11,0,1,0-12.7,12.39A1.54,1.54,0,0,0,12,21.34h0A1.47,1.47,0,0,0,10.72,19.9Z" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default Spinner;
|
||||
8
frontend/elements/src/components/icons/icons.ts
Normal file
8
frontend/elements/src/components/icons/icons.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { default as passkey } from "./Passkey";
|
||||
import { default as spinner } from "./Spinner";
|
||||
import { default as checkmark } from "./Checkmark";
|
||||
import { default as exclamation } from "./ExclamationMark";
|
||||
import { default as google } from "./Google";
|
||||
import { default as github } from "./GitHub";
|
||||
|
||||
export { passkey, spinner, checkmark, exclamation, google, github };
|
||||
@ -1,50 +1,24 @@
|
||||
@use '../../variables'
|
||||
|
||||
.icon
|
||||
display: inline-block
|
||||
fill: variables.$brand-contrast-color
|
||||
width: 18px
|
||||
|
||||
&.secondary
|
||||
fill: variables.$color
|
||||
|
||||
&.disabled
|
||||
fill: variables.$color-shade-1
|
||||
|
||||
// Checkmark Styles
|
||||
|
||||
.checkmark
|
||||
display: inline-block
|
||||
width: 16px
|
||||
height: 16px
|
||||
transform: rotate(45deg)
|
||||
@extend .icon
|
||||
fill: variables.$brand-color
|
||||
|
||||
.circle
|
||||
box-sizing: border-box
|
||||
display: inline-block
|
||||
border-width: 2px
|
||||
border-style: solid
|
||||
border-color: variables.$brand-color
|
||||
position: absolute
|
||||
width: 16px
|
||||
height: 16px
|
||||
border-radius: 11px
|
||||
left: 0
|
||||
top: 0
|
||||
|
||||
&.secondary
|
||||
border-color: variables.$color-shade-1
|
||||
|
||||
.stem
|
||||
position: absolute
|
||||
width: 2px
|
||||
height: 7px
|
||||
background-color: variables.$brand-color
|
||||
left: 8px
|
||||
top: 3px
|
||||
|
||||
&.secondary
|
||||
background-color: variables.$color-shade-1
|
||||
|
||||
.kick
|
||||
position: absolute
|
||||
width: 5px
|
||||
height: 2px
|
||||
background-color: variables.$brand-color
|
||||
left: 5px
|
||||
top: 10px
|
||||
|
||||
&.secondary
|
||||
background-color: variables.$color-shade-1
|
||||
&.secondary
|
||||
fill: variables.$color-shade-1
|
||||
|
||||
&.fadeOut
|
||||
animation: fadeOut ease-out 1.5s forwards !important
|
||||
@ -59,59 +33,32 @@
|
||||
// ExclamationMark Styles
|
||||
|
||||
.exclamationMark
|
||||
width: 16px
|
||||
height: 16px
|
||||
position: relative
|
||||
margin: 5px
|
||||
|
||||
.circle
|
||||
box-sizing: border-box
|
||||
display: inline-block
|
||||
background-color: variables.$error-color
|
||||
position: absolute
|
||||
width: 16px
|
||||
height: 16px
|
||||
border-radius: 11px
|
||||
left: 0
|
||||
top: 0
|
||||
|
||||
.stem
|
||||
position: absolute
|
||||
width: 2px
|
||||
height: 6px
|
||||
background: variables.$background-color
|
||||
left: 7px
|
||||
top: 3px
|
||||
|
||||
.dot
|
||||
position: absolute
|
||||
width: 2px
|
||||
height: 2px
|
||||
background: variables.$background-color
|
||||
left: 7px
|
||||
top: 10px
|
||||
@extend .icon
|
||||
fill: variables.$error-color
|
||||
padding-right: 5px
|
||||
|
||||
// Loading Spinner Styles
|
||||
|
||||
.loadingSpinnerWrapperIcon
|
||||
@extend .loadingSpinnerWrapper
|
||||
justify-content: flex-start
|
||||
width: 100%
|
||||
column-gap: 10px
|
||||
margin-left: 10px
|
||||
|
||||
.loadingSpinnerWrapper
|
||||
display: inline-block
|
||||
display: inline-flex
|
||||
align-items: center
|
||||
height: 100%
|
||||
margin: 0 5px
|
||||
|
||||
.loadingSpinner
|
||||
box-sizing: border-box
|
||||
display: inline-block
|
||||
border-width: 2px
|
||||
border-style: solid
|
||||
border-color: variables.$background-color
|
||||
border-top: 2px solid variables.$brand-color
|
||||
border-radius: 50%
|
||||
width: 16px
|
||||
height: 16px
|
||||
@extend .icon
|
||||
fill: variables.$brand-color
|
||||
animation: spin 500ms ease-in-out infinite
|
||||
|
||||
&.secondary
|
||||
border-color: variables.$color-shade-1
|
||||
border-top: 2px solid variables.$color-shade-2
|
||||
&.secondary
|
||||
fill: variables.$color-shade-1
|
||||
|
||||
@keyframes spin
|
||||
0%
|
||||
@ -119,3 +66,18 @@
|
||||
|
||||
100%
|
||||
transform: rotate(360deg)
|
||||
|
||||
// Google Styles
|
||||
|
||||
.googleIcon
|
||||
&.disabled
|
||||
fill: variables.$color-shade-1
|
||||
|
||||
&.blue
|
||||
fill: #4285F4
|
||||
&.green
|
||||
fill: #34A853
|
||||
&.yellow
|
||||
fill: #FBBC05
|
||||
&.red
|
||||
fill: #EA4335
|
||||
|
||||
@ -77,7 +77,7 @@ const AppProvider = ({
|
||||
const ref = useRef<HTMLElement>(null);
|
||||
|
||||
const hanko = useMemo(() => {
|
||||
if (api.length) {
|
||||
if (api) {
|
||||
return new Hanko(api, 13000);
|
||||
}
|
||||
return null;
|
||||
|
||||
@ -31,7 +31,7 @@ const InitPage = () => {
|
||||
.then((shouldRegister) =>
|
||||
shouldRegister ? <RegisterPasskeyPage /> : <LoginFinishedPage />
|
||||
),
|
||||
[hanko.webauthn]
|
||||
[hanko]
|
||||
);
|
||||
|
||||
const initHankoAuth = useCallback(() => {
|
||||
@ -56,7 +56,7 @@ const InitPage = () => {
|
||||
}
|
||||
return <LoginEmailPage />;
|
||||
});
|
||||
}, [afterLogin, hanko.config, hanko.user, setConfig, setUser]);
|
||||
}, [afterLogin, hanko, setConfig, setUser]);
|
||||
|
||||
const initHankoProfile = useCallback(
|
||||
() =>
|
||||
@ -81,13 +81,14 @@ const InitPage = () => {
|
||||
}, [componentName, initHankoAuth, initHankoProfile]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!hanko) return;
|
||||
const initializer = getInitializer();
|
||||
if (initializer) {
|
||||
initializer()
|
||||
.then(setPage)
|
||||
.catch((e) => setPage(<ErrorPage initialError={e} />));
|
||||
}
|
||||
}, [getInitializer, setPage]);
|
||||
}, [hanko, getInitializer, setPage]);
|
||||
|
||||
return <LoadingSpinner isLoading />;
|
||||
};
|
||||
|
||||
@ -30,6 +30,7 @@ import Form from "../components/form/Form";
|
||||
import Divider from "../components/divider/Divider";
|
||||
import ErrorMessage from "../components/error/ErrorMessage";
|
||||
import Headline1 from "../components/headline/Headline1";
|
||||
import { IconName } from "../components/icons/Icon";
|
||||
|
||||
import LoginPasscodePage from "./LoginPasscodePage";
|
||||
import RegisterConfirmPage from "./RegisterConfirmPage";
|
||||
@ -405,6 +406,7 @@ const LoginEmailPage = (props: Props) => {
|
||||
isLoading={isPasskeyLoginLoading}
|
||||
isSuccess={isPasskeyLoginSuccess}
|
||||
disabled={disabled}
|
||||
icon={"passkey"}
|
||||
>
|
||||
{t("labels.signInPasskey")}
|
||||
</Button>
|
||||
@ -421,6 +423,7 @@ const LoginEmailPage = (props: Props) => {
|
||||
secondary
|
||||
isLoading={isThirdPartyLoginLoading === provider}
|
||||
disabled={disabled}
|
||||
icon={provider.toLowerCase() as IconName}
|
||||
>
|
||||
{t("labels.signInWith", {
|
||||
provider,
|
||||
|
||||
@ -82,6 +82,7 @@ const RegisterPasskeyPage = () => {
|
||||
isSuccess={isSuccess}
|
||||
isLoading={isPasskeyLoading}
|
||||
disabled={disabled}
|
||||
icon={"passkey"}
|
||||
>
|
||||
{t("labels.registerAuthenticator")}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user