Skip to content

Commit

Permalink
chore: better api on selfservice auth card
Browse files Browse the repository at this point in the history
  • Loading branch information
Benehiko committed Sep 22, 2022
1 parent 69f273a commit 863fb57
Show file tree
Hide file tree
Showing 12 changed files with 375 additions and 340 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"clean": "lerna clean --yes",
"build-storybook": "build-storybook",
"refresh": "lerna bootstrap --hoist",
"build:clean": "lerna run build --skip-nx-cache",
"build": "lerna run build --stream",
"build:react": "lerna run build --stream --scope=@ory/elements",
"build:preact": "lerna run build --stream --scope@ory/elements-preact",
Expand Down
44 changes: 44 additions & 0 deletions src/react-components/ory/common.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from "react"
import { colorSprinkle } from "../../theme"
import { ButtonLink } from "../button-link"
import { Message } from "../message"

export type ErrorProps = {
code: number
details: {
docs: string
hint: string
rejectReason: string
}
message: string
status: string
reason: string
}

export type AdditionalProps = {
forgotPasswordURL?: string
signupURL?: string
logoutURL?: string
loginURL?: string
}

export type MessageSectionProps = {
url: string | undefined
buttonText: string
dataTestId?: string
text?: React.ReactNode
}

export const MessageSection = ({
text,
url,
buttonText,
dataTestId,
}: MessageSectionProps): JSX.Element => (
<Message className={colorSprinkle({ color: "foregroundMuted" })}>
{text}&nbsp;
<ButtonLink data-testid={dataTestId} href={url}>
{buttonText}
</ButtonLink>
</Message>
)
5 changes: 5 additions & 0 deletions src/react-components/ory/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@ export * from "./node"
export * from "./self-service-error-card"
export * from "./self-service-auth-card"
export * from "./selfservice-flow-form"
export * from "./login-section"
export * from "./login-two-factor"
export * from "./registration-section"
export * from "./oidc-section"
export * from "./passwordless-section"
76 changes: 76 additions & 0 deletions src/react-components/ory/login-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import React from "react"
import { UiNode } from "@ory/client"
import { gridStyle } from "../../theme"
import { ButtonLink } from "../button-link"
import { Divider } from "../divider"
import { MessageSection, MessageSectionProps } from "./common"
import { FilterFlowNodes } from "./filter-flow-nodes"

export type LoginSectionAdditionalProps = {
forgotPasswordURL?: string
signupURL?: string
logoutURL?: string
}

export type LoginSectionProps = {
nodes: UiNode[]
isLoggedIn: boolean
} & LoginSectionAdditionalProps

export const LoginSection = ({
nodes,
forgotPasswordURL,
signupURL,
logoutURL,
isLoggedIn,
}: LoginSectionProps): JSX.Element => {
const message: MessageSectionProps = isLoggedIn
? {
text: <>Something&#39;s not working?</>,
buttonText: "Logout",
url: logoutURL,
}
: {
buttonText: "Sign up",
url: signupURL,
text: <>Don&#39;t have an account?</>,
dataTestId: "signup-link",
}

return isLoggedIn ? (
<div className={gridStyle({ gap: 32 })}>
<Divider />
<FilterFlowNodes
filter={{
nodes: nodes,
excludeAttributes: "hidden",
}}
/>
{MessageSection(message)}
</div>
) : (
<div className={gridStyle({ gap: 32 })}>
<Divider />
<div className={gridStyle({ gap: 16 })}>
<FilterFlowNodes
filter={{
nodes: nodes,
groups: ["default", "password"],
excludeAttributes: ["submit", "hidden"],
}}
/>
<ButtonLink data-testid="forgot-password-link" href={forgotPasswordURL}>
Forgot Password?
</ButtonLink>
</div>
<FilterFlowNodes
filter={{
nodes: nodes,
groups: ["password"],
attributes: "submit",
}}
/>
{MessageSection(message)}
</div>
)
}
53 changes: 53 additions & 0 deletions src/react-components/ory/login-two-factor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from "react"
import { UiNode } from "@ory/client"
import { gridStyle } from "../../theme"
import { MessageSection } from "./common"
import { FilterFlowNodes } from "./filter-flow-nodes"

export type LinkSectionAdditionalProps = {
loginURL?: string
signupURL?: string
}

export type LinkSectionProps = {
nodes: UiNode[]
} & LinkSectionAdditionalProps

export const LinkSection = ({
nodes,
loginURL,
signupURL,
}: LinkSectionProps): JSX.Element => (
<div className={gridStyle({ gap: 32 })}>
<div className={gridStyle({ gap: 16 })}>
<FilterFlowNodes
filter={{
nodes: nodes,
groups: ["default", "link"],
excludeAttributes: "submit",
}}
/>
</div>
<FilterFlowNodes
filter={{
nodes: nodes,
groups: ["link"],
attributes: "submit",
}}
/>
{loginURL &&
MessageSection({
text: "Already have an account?",
url: loginURL,
buttonText: "Sign in",
dataTestId: "login-link",
})}
{signupURL &&
MessageSection({
text: "Don't have an account?",
url: signupURL,
buttonText: "Sign up",
dataTestId: "signup-link",
})}
</div>
)
31 changes: 31 additions & 0 deletions src/react-components/ory/oidc-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from "react"
import { filterNodesByGroups } from "@ory/integrations/ui"
import { gridStyle } from "../../theme"
import { SelfServiceFlow } from "../../types"
import { Divider } from "../divider"
import { FilterFlowNodes } from "./filter-flow-nodes"
import { SelfServiceFlowForm } from "./selfservice-flow-form"

export const OIDCSection = (flow: SelfServiceFlow): JSX.Element | null => {
const hasOIDC =
filterNodesByGroups({
nodes: flow.ui.nodes,
groups: "oidc",
withoutDefaultGroup: true,
}).length > 0

return hasOIDC ? (
<SelfServiceFlowForm flow={flow}>
<div className={gridStyle({ gap: 32 })}>
<Divider />
<FilterFlowNodes
filter={{
nodes: flow.ui.nodes,
groups: "oidc",
attributes: "submit",
}}
/>
</div>
</SelfServiceFlowForm>
) : null
}
19 changes: 19 additions & 0 deletions src/react-components/ory/passwordless-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from "react"
import { FilterFlowNodes } from "./filter-flow-nodes"
import { filterNodesByGroups } from "@ory/integrations/ui"
import { SelfServiceFlow } from "../../types"

export const PasswordlessSection = (
flow: SelfServiceFlow,
): JSX.Element | null => {
const hasPasswordless =
filterNodesByGroups({
nodes: flow.ui.nodes,
groups: "webauthn",
withoutDefaultGroup: true,
}).length > 0

return hasPasswordless ? (
<FilterFlowNodes filter={{ nodes: flow.ui.nodes, groups: "webauthn" }} />
) : null
}
46 changes: 46 additions & 0 deletions src/react-components/ory/registration-section.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import React from "react"
import { UiNode } from "@ory/client"
import { gridStyle } from "../../theme"
import { Divider } from "../divider"
import { MessageSection } from "./common"
import { FilterFlowNodes } from "./filter-flow-nodes"

export type RegistrationSectionAdditionalProps = {
loginURL?: string
}

export type RegistrationSectionProps = {
nodes: UiNode[]
} & RegistrationSectionAdditionalProps

export const RegistrationSection = ({
nodes,
loginURL,
}: RegistrationSectionProps): JSX.Element => (
<div className={gridStyle({ gap: 32 })}>
<Divider />

<div className={gridStyle({ gap: 16 })}>
<FilterFlowNodes
filter={{
nodes: nodes,
groups: ["default", "password"],
excludeAttributes: "submit",
}}
/>
</div>
<FilterFlowNodes
filter={{
nodes: nodes,
groups: ["password"],
attributes: "submit",
}}
/>
{MessageSection({
text: "Already have an account?",
url: loginURL,
buttonText: "Sign in",
dataTestId: "login-link",
})}
</div>
)
Loading

0 comments on commit 863fb57

Please sign in to comment.