From 2508a521aa3f43a7577b68ca2ed3e46eb1f8a7f6 Mon Sep 17 00:00:00 2001 From: Andy Luo Date: Tue, 19 Nov 2024 10:33:10 -0800 Subject: [PATCH 001/122] Added payout on hold alert and text props --- packages/mint-components/src/components.d.ts | 20 ++++++++++++++++++ .../tax-and-cash/TaxForm.stories.tsx | 21 +++++++++++++++++++ .../sqm-tax-and-cash-dashboard-view.tsx | 18 ++++++++++++++++ .../sqm-tax-and-cash-dashboard.tsx | 13 ++++++++++++ 4 files changed, 72 insertions(+) diff --git a/packages/mint-components/src/components.d.ts b/packages/mint-components/src/components.d.ts index c3e07cf81..99da419ea 100644 --- a/packages/mint-components/src/components.d.ts +++ b/packages/mint-components/src/components.d.ts @@ -4801,6 +4801,16 @@ export namespace Components { * @uiName Payout missing information subtext */ "payoutMissingInformationText": string; + /** + * Part of the alert displayed at the top of the page. + * @uiName Payout on hold warning message header + */ + "payoutOnHoldAlertHeader"?: string; + /** + * Part of the alert displayed at the top of the page. + * @uiName Payout on hold warning warning message description + */ + "payoutOnHoldAlertMessage"?: string; /** * Displayed to participants registered in Quebec, Canada. * @uiName QST indirect tax details @@ -10607,6 +10617,16 @@ declare namespace LocalJSX { * @uiName Payout missing information subtext */ "payoutMissingInformationText"?: string; + /** + * Part of the alert displayed at the top of the page. + * @uiName Payout on hold warning message header + */ + "payoutOnHoldAlertHeader"?: string; + /** + * Part of the alert displayed at the top of the page. + * @uiName Payout on hold warning warning message description + */ + "payoutOnHoldAlertMessage"?: string; /** * Displayed to participants registered in Quebec, Canada. * @uiName QST indirect tax details diff --git a/packages/mint-components/src/components/tax-and-cash/TaxForm.stories.tsx b/packages/mint-components/src/components/tax-and-cash/TaxForm.stories.tsx index b530cbc8c..75e824752 100644 --- a/packages/mint-components/src/components/tax-and-cash/TaxForm.stories.tsx +++ b/packages/mint-components/src/components/tax-and-cash/TaxForm.stories.tsx @@ -1243,6 +1243,27 @@ export const TaxAndCashDashboardIndirectTaxNotRegistered = () => { ); }; +export const TaxAndCashDashboardPayoutOnHold = () => { + return ( + + ); +}; + export const TaxAndCashDashboardNewTaxForm = () => { return ( {
+ {states.payoutOnHold && ( +
+ + + {text.payoutOnHoldAlertHeader} +
+ {text.payoutOnHoldAlertMessage} +
+
+ )} {states.loadingError && (
Date: Tue, 19 Nov 2024 12:08:09 -0800 Subject: [PATCH 002/122] Added more text props and stories --- packages/mint-components/src/components.d.ts | 32 ++++++++- .../tax-and-cash/TaxForm.stories.tsx | 22 ++++++ .../sqm-tax-and-cash-dashboard-view.tsx | 68 +++++++++++++++---- .../sqm-tax-and-cash-dashboard.tsx | 20 +++++- 4 files changed, 124 insertions(+), 18 deletions(-) diff --git a/packages/mint-components/src/components.d.ts b/packages/mint-components/src/components.d.ts index 99da419ea..73a13036c 100644 --- a/packages/mint-components/src/components.d.ts +++ b/packages/mint-components/src/components.d.ts @@ -4694,6 +4694,16 @@ export namespace Components { * @uiWidget textArea */ "generalErrorTitle": string; + /** + * Part of the alert displayed at the top of the page. + * @uiName Identity verification warning message header + */ + "identityRequiredAlertHeader"?: string; + /** + * Part of the alert displayed at the top of the page. + * @uiName Identity verificationwarning message description + */ + "identityRequiredAlertMessage"?: string; /** * Part of the Invoice table displayed at the bottom of the page. * @uiName Indirect tax column title @@ -4808,7 +4818,7 @@ export namespace Components { "payoutOnHoldAlertHeader"?: string; /** * Part of the alert displayed at the top of the page. - * @uiName Payout on hold warning warning message description + * @uiName Payout on hold warning message description */ "payoutOnHoldAlertMessage"?: string; /** @@ -4887,6 +4897,10 @@ export namespace Components { * @uiName Payout schedule by threshold text */ "thresholdPayoutText": string; + /** + * @uiName Verify button label + */ + "verifyButton": string; } interface SqmText { } @@ -10510,6 +10524,16 @@ declare namespace LocalJSX { * @uiWidget textArea */ "generalErrorTitle"?: string; + /** + * Part of the alert displayed at the top of the page. + * @uiName Identity verification warning message header + */ + "identityRequiredAlertHeader"?: string; + /** + * Part of the alert displayed at the top of the page. + * @uiName Identity verificationwarning message description + */ + "identityRequiredAlertMessage"?: string; /** * Part of the Invoice table displayed at the bottom of the page. * @uiName Indirect tax column title @@ -10624,7 +10648,7 @@ declare namespace LocalJSX { "payoutOnHoldAlertHeader"?: string; /** * Part of the alert displayed at the top of the page. - * @uiName Payout on hold warning warning message description + * @uiName Payout on hold warning message description */ "payoutOnHoldAlertMessage"?: string; /** @@ -10703,6 +10727,10 @@ declare namespace LocalJSX { * @uiName Payout schedule by threshold text */ "thresholdPayoutText"?: string; + /** + * @uiName Verify button label + */ + "verifyButton"?: string; } interface SqmText { } diff --git a/packages/mint-components/src/components/tax-and-cash/TaxForm.stories.tsx b/packages/mint-components/src/components/tax-and-cash/TaxForm.stories.tsx index 75e824752..d0ddcbb69 100644 --- a/packages/mint-components/src/components/tax-and-cash/TaxForm.stories.tsx +++ b/packages/mint-components/src/components/tax-and-cash/TaxForm.stories.tsx @@ -1264,6 +1264,28 @@ export const TaxAndCashDashboardPayoutOnHold = () => { ); }; +export const TaxAndCashDashboardIdentityVerifcationRequired = () => { + return ( + + ); +}; + export const TaxAndCashDashboardNewTaxForm = () => { return ( {
- {states.payoutOnHold && ( -
- - - {text.payoutOnHoldAlertHeader} -
- {text.payoutOnHoldAlertMessage} -
-
- )} {states.loadingError && (
{ {text.error.generalDescription} )} + {states.payoutOnHold && ( +
+ + + {text.payoutOnHoldAlertHeader} +
+ {text.payoutOnHoldAlertMessage} +
+
+ )} + {states.identiyRequired && ( +
+ + + {text.identityRequiredAlertHeader} +
+ {text.identityRequiredAlertMessage} +
+ {/* AL: TODO add onClick for button to open modal */} + {text.verifyButton} +
+
+ )} + +
+
Date: Tue, 19 Nov 2024 14:47:18 -0800 Subject: [PATCH 003/122] initial hook work for verification gates --- .../sqb-auth-template-switch.tsx | 6 +- .../useAuthTemplateSwitch.ts | 9 ++- .../src/hooks/environment/index.ts | 2 + .../src/hooks/environment/useQueryToken.ts | 9 +++ .../environment/useVerificationContext.ts | 30 +++++++++ .../src/hooks/graphql/useBaseQuery.ts | 4 +- .../src/hooks/graphql/useGraphQLClient.ts | 11 +++- .../src/hooks/graphql/useQuery.ts | 3 +- .../src/contexts/VerificationContext.ts | 58 +++++++++++++++++ packages/component-environment/src/index.ts | 1 + packages/component-environment/src/types.ts | 8 +++ packages/mint-components/src/components.d.ts | 26 ++++++++ .../sqm-widget-verification/keys.ts | 1 + .../sqm-widget-verification/readme.md | 10 +++ .../sqm-email-check/sqm-email-check.tsx | 65 +++++++++++++++++++ .../sqm-widget-verification.tsx | 60 +++++++++++++++++ .../useWidgetVerification.ts | 64 ++++++++++++++++++ packages/mint-components/src/index.html | 13 +++- 18 files changed, 369 insertions(+), 11 deletions(-) create mode 100644 packages/component-boilerplate/src/hooks/environment/useQueryToken.ts create mode 100644 packages/component-boilerplate/src/hooks/environment/useVerificationContext.ts create mode 100644 packages/component-environment/src/contexts/VerificationContext.ts create mode 100644 packages/mint-components/src/components/sqm-widget-verification/keys.ts create mode 100644 packages/mint-components/src/components/sqm-widget-verification/readme.md create mode 100644 packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/sqm-email-check.tsx create mode 100644 packages/mint-components/src/components/sqm-widget-verification/sqm-widget-verification.tsx create mode 100644 packages/mint-components/src/components/sqm-widget-verification/useWidgetVerification.ts diff --git a/packages/bedrock-components/src/components/sqb-auth-template-switch/sqb-auth-template-switch.tsx b/packages/bedrock-components/src/components/sqb-auth-template-switch/sqb-auth-template-switch.tsx index baa4f89fe..d5034f756 100644 --- a/packages/bedrock-components/src/components/sqb-auth-template-switch/sqb-auth-template-switch.tsx +++ b/packages/bedrock-components/src/components/sqb-auth-template-switch/sqb-auth-template-switch.tsx @@ -1,5 +1,5 @@ import { withHooks } from '@saasquatch/stencil-hooks'; -import { Component, h, Host } from '@stencil/core'; +import { Component, h, Host, Prop } from '@stencil/core'; import { useAuthTemplateSwitch } from './useAuthTemplateSwitch'; /** @@ -13,6 +13,8 @@ import { useAuthTemplateSwitch } from './useAuthTemplateSwitch'; tag: 'sqb-auth-template-switch', }) export class SqbAuthTemplateSwitch { + @Prop() verification: boolean = false; + constructor() { withHooks(this); } @@ -20,7 +22,7 @@ export class SqbAuthTemplateSwitch { disconnectedCallback() {} render() { - const { setContainer, setSlot } = useAuthTemplateSwitch(); + const { setContainer, setSlot } = useAuthTemplateSwitch({ verification: this.verification }); return ( diff --git a/packages/bedrock-components/src/components/sqb-auth-template-switch/useAuthTemplateSwitch.ts b/packages/bedrock-components/src/components/sqb-auth-template-switch/useAuthTemplateSwitch.ts index c1a7b443f..fe1af7023 100644 --- a/packages/bedrock-components/src/components/sqb-auth-template-switch/useAuthTemplateSwitch.ts +++ b/packages/bedrock-components/src/components/sqb-auth-template-switch/useAuthTemplateSwitch.ts @@ -1,11 +1,14 @@ -import { useToken } from '@saasquatch/component-boilerplate'; +import { useToken, useVerificationContext } from '@saasquatch/component-boilerplate'; import { useCallback, useEffect, useState } from '@saasquatch/universal-hooks'; import debugFn from 'debug'; import { useTemplateChildren } from '../../utils/useTemplateChildren'; const debug = debugFn('sq:useAuthTemplateSwitch'); -export function useAuthTemplateSwitch() { - const authToken = useToken(); +type Options = { verification?: boolean }; +export function useAuthTemplateSwitch(options?: Options) { + const token = useToken(); + const verificationToken = useVerificationContext()?.token; + const authToken = options.verification ? verificationToken : token; const [container, setContainer] = useState(undefined); const [slot, setSlot] = useState(undefined); diff --git a/packages/component-boilerplate/src/hooks/environment/index.ts b/packages/component-boilerplate/src/hooks/environment/index.ts index 545ca8a46..47e9fbea0 100644 --- a/packages/component-boilerplate/src/hooks/environment/index.ts +++ b/packages/component-boilerplate/src/hooks/environment/index.ts @@ -12,6 +12,7 @@ export const useEngagementMedium = getEngagementMedium; export { getEnvironmentSDK, setUserIdentity, + setVerificationContext, setProgramId, isDemo, DecodedSquatchJWT, @@ -20,3 +21,4 @@ export { export * from "./useLocale"; export * from "./useProgramId"; export * from "./useUserIdentity"; +export * from "./useVerificationContext"; diff --git a/packages/component-boilerplate/src/hooks/environment/useQueryToken.ts b/packages/component-boilerplate/src/hooks/environment/useQueryToken.ts new file mode 100644 index 000000000..a3f139929 --- /dev/null +++ b/packages/component-boilerplate/src/hooks/environment/useQueryToken.ts @@ -0,0 +1,9 @@ +import { useUserIdentity } from "./useUserIdentity"; +import { useVerificationContext } from "./useVerificationContext"; + +export function useQueryToken() { + const verificationToken = useVerificationContext()?.token; + const userJwt = useUserIdentity()?.jwt; + + return verificationToken || userJwt; +} diff --git a/packages/component-boilerplate/src/hooks/environment/useVerificationContext.ts b/packages/component-boilerplate/src/hooks/environment/useVerificationContext.ts new file mode 100644 index 000000000..47d32372d --- /dev/null +++ b/packages/component-boilerplate/src/hooks/environment/useVerificationContext.ts @@ -0,0 +1,30 @@ +import { + checkVerificationToken, + isDemo, + lazilyStartVerificationContext, + setVerificationContext, + VERIFICATION_CONTEXT_NAME, + VerificationContext, +} from "@saasquatch/component-environment"; +import { useDomContext } from "@saasquatch/dom-context-hooks"; +import { useHost } from "../useHost"; + +export function useVerificationContext(): VerificationContext | undefined { + lazilyStartVerificationContext(); + const host = useHost(); + const context = useDomContext(host, VERIFICATION_CONTEXT_NAME) as + | VerificationContext + | undefined; + + const valid = checkVerificationToken(context?.token); + if (!isDemo() && context && !valid) { + setVerificationContext(undefined); + return undefined; + } + + return context; +} + +export function useVerificationToken() { + return useVerificationContext()?.token; +} diff --git a/packages/component-boilerplate/src/hooks/graphql/useBaseQuery.ts b/packages/component-boilerplate/src/hooks/graphql/useBaseQuery.ts index 26ca8ea33..f186361a0 100644 --- a/packages/component-boilerplate/src/hooks/graphql/useBaseQuery.ts +++ b/packages/component-boilerplate/src/hooks/graphql/useBaseQuery.ts @@ -80,12 +80,12 @@ function reducer( export function useBaseQuery( query: GqlType, initialState: BaseQueryData, - options = { batch: true } + options = { batch: true, protected: false } ): [ BaseQueryData, (variables: unknown, skipLoading?: boolean) => Promise ] { - const client = useGraphQLClient(); + const client = useGraphQLClient({ protected: options.protected }); const [state, dispatch] = useReducer, Action>( reducer, initialState diff --git a/packages/component-boilerplate/src/hooks/graphql/useGraphQLClient.ts b/packages/component-boilerplate/src/hooks/graphql/useGraphQLClient.ts index e52254fd3..24e3b0947 100644 --- a/packages/component-boilerplate/src/hooks/graphql/useGraphQLClient.ts +++ b/packages/component-boilerplate/src/hooks/graphql/useGraphQLClient.ts @@ -3,6 +3,12 @@ import memoize from "fast-memoize"; import { BatchedGraphQLClient } from "../../BatchedGraphQLClient"; import { useAppDomain, useTenantAlias, useToken } from "../environment"; import { useHost } from "../useHost"; +import { useQueryToken } from "../environment/useQueryToken"; +import { useVerificationContext } from "../environment/useVerificationContext"; + +type Options = { + protected?: boolean; +}; export const GRAPHQL_CONTEXT = "sq:graphql-client"; @@ -23,8 +29,9 @@ function createGraphQlClient( export const memoizedGraphQLClient = memoize(createGraphQlClient); -function useGraphQLClient(): BatchedGraphQLClient { +function useGraphQLClient(options?: Options): BatchedGraphQLClient { const token = useToken(); + const verifiedToken = useVerificationContext()?.token; const appDomain = useAppDomain(); const tenantAlias = useTenantAlias(); @@ -32,7 +39,7 @@ function useGraphQLClient(): BatchedGraphQLClient { const localClient: BatchedGraphQLClient = memoizedGraphQLClient( appDomain, tenantAlias, - token + options?.protected ? verifiedToken : token ); const host = useHost(); const clientFromContext = useDomContext( diff --git a/packages/component-boilerplate/src/hooks/graphql/useQuery.ts b/packages/component-boilerplate/src/hooks/graphql/useQuery.ts index c4a8ae638..8f4cc733d 100644 --- a/packages/component-boilerplate/src/hooks/graphql/useQuery.ts +++ b/packages/component-boilerplate/src/hooks/graphql/useQuery.ts @@ -36,13 +36,14 @@ export function useQuery( query: GqlType, variables: unknown, skip?: boolean, - options?: { batch?: boolean } + options?: { batch?: boolean; protected?: boolean } ): QueryData { const [state, update] = useBaseQuery( query, initialQueryState as BaseQueryData, { batch: true, + protected: false, ...(options || {}), } ); diff --git a/packages/component-environment/src/contexts/VerificationContext.ts b/packages/component-environment/src/contexts/VerificationContext.ts new file mode 100644 index 000000000..9d8f2b340 --- /dev/null +++ b/packages/component-environment/src/contexts/VerificationContext.ts @@ -0,0 +1,58 @@ +import equal from "@wry/equality"; +import decode from "jwt-decode"; +import { ContextProvider } from "dom-context"; +import { + DecodedSquatchJWT, + VERIFICATION_CONTEXT_NAME, + VerificationContext, +} from "../types"; +import { getUserIdentity } from "./UserIdentityContext"; + +export function lazilyStartVerificationContext() { + let globalProvider = window.squatchVerification; + if (!globalProvider) { + globalProvider = new ContextProvider({ + element: document.documentElement, + // Unless we want to do session management, verified status should be renewed on each widget load + initialState: undefined, + contextName: VERIFICATION_CONTEXT_NAME, + }).start(); + + window.squatchVerification = globalProvider; + } + + return globalProvider; +} + +export function checkVerificationToken(token: string) { + if (!token) return false; + + const decoded = decode(token); + + // Check if token is valid object + const isSquatchJWT = + decoded.user && decoded.user.id && decoded.user.accountId; + if (!isSquatchJWT) return false; + + // Check if verification JWT credentials match with current user + const currentUser = getUserIdentity(); + if ( + decoded.user.id !== currentUser?.id || + decoded.user.accountId !== currentUser?.accountId + ) + return false; + + return true; +} + +export function setVerificationContext(context: VerificationContext) { + const globalProvider = lazilyStartVerificationContext(); + + if (!equal(globalProvider.context, context)) { + globalProvider.context = context; + } +} + +export function getVerificationContext() { + return window.squatchVerification?.context; +} diff --git a/packages/component-environment/src/index.ts b/packages/component-environment/src/index.ts index 5501ee171..7e809a371 100644 --- a/packages/component-environment/src/index.ts +++ b/packages/component-environment/src/index.ts @@ -5,3 +5,4 @@ export * from "./history"; export * from "./contexts/UserIdentityContext"; export * from "./contexts/LocaleContext"; export * from "./contexts/ProgramContext"; +export * from "./contexts/VerificationContext"; diff --git a/packages/component-environment/src/types.ts b/packages/component-environment/src/types.ts index 4faea9e7a..1b2c24f2d 100644 --- a/packages/component-environment/src/types.ts +++ b/packages/component-environment/src/types.ts @@ -7,17 +7,25 @@ declare global { squatchUserIdentity?: ContextProvider; squatchLocale?: ContextProvider; squatchProgramId?: ContextProvider; + squatchVerification?: ContextProvider; } } export type UserContextName = "sq:user-identity"; export type LocaleContextName = "sq:locale"; export type ProgramContextName = "sq:program-id"; +export type VerificationContextName = "sq:verification"; export const USER_CONTEXT_NAME: UserContextName = "sq:user-identity" as const; export const LOCALE_CONTEXT_NAME: LocaleContextName = "sq:locale" as const; export const PROGRAM_CONTEXT_NAME: ProgramContextName = "sq:program-id" as const; +export const VERIFICATION_CONTEXT_NAME: VerificationContextName = + "sq:verification" as const; + +export type VerificationContext = { + token: string; +}; /** * The value stored in the UserContext diff --git a/packages/mint-components/src/components.d.ts b/packages/mint-components/src/components.d.ts index c3e07cf81..434347c70 100644 --- a/packages/mint-components/src/components.d.ts +++ b/packages/mint-components/src/components.d.ts @@ -715,6 +715,8 @@ export namespace Components { */ "updatetext": string; } + interface SqmEmailCheck { + } interface SqmEmpty { /** * @uiName Title @@ -5123,6 +5125,8 @@ export namespace Components { */ "loadingText": string; } + interface SqmWidgetVerification { + } } declare global { interface HTMLRaisinsPlopTargetElement extends Components.RaisinsPlopTarget, HTMLStencilElement { @@ -5209,6 +5213,12 @@ declare global { prototype: HTMLSqmEditProfileElement; new (): HTMLSqmEditProfileElement; }; + interface HTMLSqmEmailCheckElement extends Components.SqmEmailCheck, HTMLStencilElement { + } + var HTMLSqmEmailCheckElement: { + prototype: HTMLSqmEmailCheckElement; + new (): HTMLSqmEmailCheckElement; + }; interface HTMLSqmEmptyElement extends Components.SqmEmpty, HTMLStencilElement { } var HTMLSqmEmptyElement: { @@ -5773,6 +5783,12 @@ declare global { prototype: HTMLSqmUserNameElement; new (): HTMLSqmUserNameElement; }; + interface HTMLSqmWidgetVerificationElement extends Components.SqmWidgetVerification, HTMLStencilElement { + } + var HTMLSqmWidgetVerificationElement: { + prototype: HTMLSqmWidgetVerificationElement; + new (): HTMLSqmWidgetVerificationElement; + }; interface HTMLElementTagNameMap { "raisins-plop-target": HTMLRaisinsPlopTargetElement; "sqm-asset-card": HTMLSqmAssetCardElement; @@ -5788,6 +5804,7 @@ declare global { "sqm-docusign-form": HTMLSqmDocusignFormElement; "sqm-dropdown-field": HTMLSqmDropdownFieldElement; "sqm-edit-profile": HTMLSqmEditProfileElement; + "sqm-email-check": HTMLSqmEmailCheckElement; "sqm-empty": HTMLSqmEmptyElement; "sqm-form-message": HTMLSqmFormMessageElement; "sqm-graphql-client-provider": HTMLSqmGraphqlClientProviderElement; @@ -5882,6 +5899,7 @@ declare global { "sqm-titled-section": HTMLSqmTitledSectionElement; "sqm-user-info-form": HTMLSqmUserInfoFormElement; "sqm-user-name": HTMLSqmUserNameElement; + "sqm-widget-verification": HTMLSqmWidgetVerificationElement; } } declare namespace LocalJSX { @@ -6551,6 +6569,8 @@ declare namespace LocalJSX { */ "updatetext"?: string; } + interface SqmEmailCheck { + } interface SqmEmpty { /** * @uiName Title @@ -10928,6 +10948,8 @@ declare namespace LocalJSX { */ "loadingText"?: string; } + interface SqmWidgetVerification { + } interface IntrinsicElements { "raisins-plop-target": RaisinsPlopTarget; "sqm-asset-card": SqmAssetCard; @@ -10943,6 +10965,7 @@ declare namespace LocalJSX { "sqm-docusign-form": SqmDocusignForm; "sqm-dropdown-field": SqmDropdownField; "sqm-edit-profile": SqmEditProfile; + "sqm-email-check": SqmEmailCheck; "sqm-empty": SqmEmpty; "sqm-form-message": SqmFormMessage; "sqm-graphql-client-provider": SqmGraphqlClientProvider; @@ -11037,6 +11060,7 @@ declare namespace LocalJSX { "sqm-titled-section": SqmTitledSection; "sqm-user-info-form": SqmUserInfoForm; "sqm-user-name": SqmUserName; + "sqm-widget-verification": SqmWidgetVerification; } } export { LocalJSX as JSX }; @@ -11057,6 +11081,7 @@ declare module "@stencil/core" { "sqm-docusign-form": LocalJSX.SqmDocusignForm & JSXBase.HTMLAttributes; "sqm-dropdown-field": LocalJSX.SqmDropdownField & JSXBase.HTMLAttributes; "sqm-edit-profile": LocalJSX.SqmEditProfile & JSXBase.HTMLAttributes; + "sqm-email-check": LocalJSX.SqmEmailCheck & JSXBase.HTMLAttributes; "sqm-empty": LocalJSX.SqmEmpty & JSXBase.HTMLAttributes; "sqm-form-message": LocalJSX.SqmFormMessage & JSXBase.HTMLAttributes; "sqm-graphql-client-provider": LocalJSX.SqmGraphqlClientProvider & JSXBase.HTMLAttributes; @@ -11151,6 +11176,7 @@ declare module "@stencil/core" { "sqm-titled-section": LocalJSX.SqmTitledSection & JSXBase.HTMLAttributes; "sqm-user-info-form": LocalJSX.SqmUserInfoForm & JSXBase.HTMLAttributes; "sqm-user-name": LocalJSX.SqmUserName & JSXBase.HTMLAttributes; + "sqm-widget-verification": LocalJSX.SqmWidgetVerification & JSXBase.HTMLAttributes; } } } diff --git a/packages/mint-components/src/components/sqm-widget-verification/keys.ts b/packages/mint-components/src/components/sqm-widget-verification/keys.ts new file mode 100644 index 000000000..4647e34e5 --- /dev/null +++ b/packages/mint-components/src/components/sqm-widget-verification/keys.ts @@ -0,0 +1 @@ +export const SHOW_CODE_NAMESPACE = "sq:code-verification"; diff --git a/packages/mint-components/src/components/sqm-widget-verification/readme.md b/packages/mint-components/src/components/sqm-widget-verification/readme.md new file mode 100644 index 000000000..230b41727 --- /dev/null +++ b/packages/mint-components/src/components/sqm-widget-verification/readme.md @@ -0,0 +1,10 @@ +# sqm-widget-verification + + + + + + +---------------------------------------------- + +*Built with [StencilJS](https://stenciljs.com/)* diff --git a/packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/sqm-email-check.tsx b/packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/sqm-email-check.tsx new file mode 100644 index 000000000..fac0777ea --- /dev/null +++ b/packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/sqm-email-check.tsx @@ -0,0 +1,65 @@ +import { useParent } from "@saasquatch/component-boilerplate"; +import { withHooks } from "@saasquatch/stencil-hooks"; +import { useState } from "@saasquatch/universal-hooks"; +import { Component, h } from "@stencil/core"; +import { SHOW_CODE_NAMESPACE } from "../keys"; + +/** + * @uiName Widget Verification Gate + */ +@Component({ + tag: "sqm-email-check", + shadow: true, +}) +export class WidgetEmailVerification { + constructor() { + withHooks(this); + } + disconnectedCallback() {} + + render() { + const [_, setShowCode] = useParent(SHOW_CODE_NAMESPACE); + const [email, setEmail] = useState(""); + + return ( +
+ setEmail(e.target.value)} + /> + +
+ ); + + // const Code = () => { + // return ( + //
+ // + // + // + // + // + //
+ // + //
+ // ); + // }; + + // const verificationStep = () => { + // switch (props.step) { + // case "email": + // return ; + // case "code": + // return ; + // } + // }; + + // return ( + //
+ //

Cash Payouts

+ // {verificationStep()} + //
+ // ); + } +} diff --git a/packages/mint-components/src/components/sqm-widget-verification/sqm-widget-verification.tsx b/packages/mint-components/src/components/sqm-widget-verification/sqm-widget-verification.tsx new file mode 100644 index 000000000..a373d0fb0 --- /dev/null +++ b/packages/mint-components/src/components/sqm-widget-verification/sqm-widget-verification.tsx @@ -0,0 +1,60 @@ +import { withHooks } from "@saasquatch/stencil-hooks"; +import { Component, h } from "@stencil/core"; +import { useWidgetVerification } from "./useWidgetVerification"; +import { useParentState } from "@saasquatch/component-boilerplate"; +import { SHOW_CODE_NAMESPACE } from "./keys"; +import { WidgetEmailVerification } from "./sqm-email-check/sqm-email-check"; + +/** + * @uiName Widget Verification Gate + * @slots [{ "name": "verified", "title": "Verified Content" }] + */ +@Component({ + tag: "sqm-widget-verification", + shadow: true, +}) +export class WidgetVerification { + constructor() { + withHooks(this); + } + disconnectedCallback() {} + + render() { + const [showCode, setShowCode] = useParentState({ + namespace: SHOW_CODE_NAMESPACE, + initialValue: false, + }); + + const props = useWidgetVerification(); + + const Code = () => { + return ( +
+ + + + + +
+ +
+ ); + }; + + const verificationStep = () => { + switch (showCode) { + case false: + return ; + case true: + return ; + } + }; + + return ( +
+

Cash Payouts

+ {verificationStep()} +
+ ); + } +} diff --git a/packages/mint-components/src/components/sqm-widget-verification/useWidgetVerification.ts b/packages/mint-components/src/components/sqm-widget-verification/useWidgetVerification.ts new file mode 100644 index 000000000..6cb314553 --- /dev/null +++ b/packages/mint-components/src/components/sqm-widget-verification/useWidgetVerification.ts @@ -0,0 +1,64 @@ +import { + setVerificationContext, + useVerificationContext, +} from "@saasquatch/component-boilerplate"; +import { useEffect, useState } from "@saasquatch/universal-hooks"; + +export function useWidgetVerification() { + const [step, setStep] = useState<"email" | "code">("email"); + const [email, setEmail] = useState(null); + const [codeRef, setCodeRef] = useState(null); + + const onSubmitEmail = () => { + setStep("code"); + }; + + useEffect(() => { + if (!codeRef) return; + + const codeElements = Array.from( + codeRef.querySelectorAll(`input[name="code"]`) + ) as HTMLInputElement[]; + + console.log({ codeElements }); + codeElements.forEach((element, idx) => { + element.addEventListener("keydown", (e: any) => { + if (e.key === "Backspace" && e.target.value === "") { + codeElements[Math.max(0, idx - 1)].focus(); + } + }); + element.addEventListener("input", (e: any) => { + const input = e.target.value; + if (!input) return; + if (idx === codeElements.length - 1) { + e.target.value = input.slice(-1); + return; + } + + if (input.length > 1) { + const rest = input.slice(1); + e.target.value = input.slice(0, 1); + codeElements[idx + 1].value = rest; + codeElements[idx + 1].dispatchEvent(new Event("input")); + } + codeElements[idx + 1].focus(); + }); + }); + }, [codeRef]); + + const onCheckCode = () => { + setVerificationContext({ + token: + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IklSTVhzWXk2WVlxcTQ2OTQzN21HOEVSUXQ4UW9LRkJhRzEifQ.eyJ1c2VyIjp7ImlkIjoiOThkODNlZGIwMmQ3ZTdjOTViY2Q2MjY3ZDZlN2RkMWU0NDJiNGMyMWJkZDQ4ZjY4NTgyMjIwYTVlNzgxMDdkYyIsImFjY291bnRJZCI6Ijk4ZDgzZWRiMDJkN2U3Yzk1YmNkNjI2N2Q2ZTdkZDFlNDQyYjRjMjFiZGQ0OGY2ODU4MjIyMGE1ZTc4MTA3ZGMiLCJlbWFpbCI6ImltcGFjdHFhbWFudWFsK3VzMUBnbWFpbC5jb20ifX0._CwBBMh6mX0WpoV2D3H_LfkP-i-D_bkgv7Q0ZCUhRTI", + }); + }; + + return { + step, + email, + setEmail, + setCodeRef, + onCheckCode, + onSubmitEmail, + }; +} diff --git a/packages/mint-components/src/index.html b/packages/mint-components/src/index.html index 168b34e51..23d269214 100644 --- a/packages/mint-components/src/index.html +++ b/packages/mint-components/src/index.html @@ -13,6 +13,17 @@ - + + + + + + From b71f12571cf35f6cbd1e630d743ef5edaa945697 Mon Sep 17 00:00:00 2001 From: Locrian24 Date: Wed, 20 Nov 2024 11:31:49 -0800 Subject: [PATCH 004/122] more fleshed out hooks for verification flow --- .../bedrock-components/src/components.d.ts | 2 + .../sqb-auth-template-switch/readme.md | 7 ++ .../src/contexts/VerificationContext.ts | 4 + packages/mint-components/src/components.d.ts | 13 ++ .../sqm-widget-verification/keys.ts | 1 + .../sqm-code-check/sqm-code-check.tsx | 39 ++++++ .../sqm-code-check/useCodeCheck.ts | 117 ++++++++++++++++++ .../sqm-email-check/sqm-email-check.tsx | 48 +------ .../sqm-email-check/useEmailCheck.ts | 76 ++++++++++++ .../sqm-widget-verification.tsx | 24 +--- .../useWidgetVerification.ts | 63 +--------- packages/mint-components/src/index.html | 6 +- 12 files changed, 275 insertions(+), 125 deletions(-) create mode 100644 packages/mint-components/src/components/sqm-widget-verification/sqm-code-check/sqm-code-check.tsx create mode 100644 packages/mint-components/src/components/sqm-widget-verification/sqm-code-check/useCodeCheck.ts create mode 100644 packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/useEmailCheck.ts diff --git a/packages/bedrock-components/src/components.d.ts b/packages/bedrock-components/src/components.d.ts index 147267bd6..4d0d57820 100644 --- a/packages/bedrock-components/src/components.d.ts +++ b/packages/bedrock-components/src/components.d.ts @@ -9,6 +9,7 @@ import { FunctionalComponent } from "@stencil/core"; import { DemoData } from "./global/demo"; export namespace Components { interface SqbAuthTemplateSwitch { + "verification": boolean; } interface SqbConditionalSection { /** @@ -127,6 +128,7 @@ declare global { } declare namespace LocalJSX { interface SqbAuthTemplateSwitch { + "verification"?: boolean; } interface SqbConditionalSection { /** diff --git a/packages/bedrock-components/src/components/sqb-auth-template-switch/readme.md b/packages/bedrock-components/src/components/sqb-auth-template-switch/readme.md index 94211fa6e..b55fa8482 100644 --- a/packages/bedrock-components/src/components/sqb-auth-template-switch/readme.md +++ b/packages/bedrock-components/src/components/sqb-auth-template-switch/readme.md @@ -5,6 +5,13 @@ +## Properties + +| Property | Attribute | Description | Type | Default | +| -------------- | -------------- | ----------- | --------- | ------- | +| `verification` | `verification` | | `boolean` | `false` | + + ## Dependencies ### Used by diff --git a/packages/component-environment/src/contexts/VerificationContext.ts b/packages/component-environment/src/contexts/VerificationContext.ts index 9d8f2b340..9acf3acac 100644 --- a/packages/component-environment/src/contexts/VerificationContext.ts +++ b/packages/component-environment/src/contexts/VerificationContext.ts @@ -7,6 +7,9 @@ import { VerificationContext, } from "../types"; import { getUserIdentity } from "./UserIdentityContext"; +import { debug as _debug } from "../debug"; + +const debug = (...args: any[]) => _debug(VERIFICATION_CONTEXT_NAME, ...args); export function lazilyStartVerificationContext() { let globalProvider = window.squatchVerification; @@ -49,6 +52,7 @@ export function setVerificationContext(context: VerificationContext) { const globalProvider = lazilyStartVerificationContext(); if (!equal(globalProvider.context, context)) { + debug(`Setting verification context to [${JSON.stringify(context)}]`); globalProvider.context = context; } } diff --git a/packages/mint-components/src/components.d.ts b/packages/mint-components/src/components.d.ts index 434347c70..59d475460 100644 --- a/packages/mint-components/src/components.d.ts +++ b/packages/mint-components/src/components.d.ts @@ -416,6 +416,8 @@ export namespace Components { */ "color": string; } + interface SqmCodeCheck { + } interface SqmContextRouter { "contextName": string; } @@ -5177,6 +5179,12 @@ declare global { prototype: HTMLSqmCloseButtonElement; new (): HTMLSqmCloseButtonElement; }; + interface HTMLSqmCodeCheckElement extends Components.SqmCodeCheck, HTMLStencilElement { + } + var HTMLSqmCodeCheckElement: { + prototype: HTMLSqmCodeCheckElement; + new (): HTMLSqmCodeCheckElement; + }; interface HTMLSqmContextRouterElement extends Components.SqmContextRouter, HTMLStencilElement { } var HTMLSqmContextRouterElement: { @@ -5798,6 +5806,7 @@ declare global { "sqm-card-feed": HTMLSqmCardFeedElement; "sqm-checkbox-field": HTMLSqmCheckboxFieldElement; "sqm-close-button": HTMLSqmCloseButtonElement; + "sqm-code-check": HTMLSqmCodeCheckElement; "sqm-context-router": HTMLSqmContextRouterElement; "sqm-coupon-code": HTMLSqmCouponCodeElement; "sqm-divided-layout": HTMLSqmDividedLayoutElement; @@ -6270,6 +6279,8 @@ declare namespace LocalJSX { */ "color"?: string; } + interface SqmCodeCheck { + } interface SqmContextRouter { "contextName"?: string; } @@ -10959,6 +10970,7 @@ declare namespace LocalJSX { "sqm-card-feed": SqmCardFeed; "sqm-checkbox-field": SqmCheckboxField; "sqm-close-button": SqmCloseButton; + "sqm-code-check": SqmCodeCheck; "sqm-context-router": SqmContextRouter; "sqm-coupon-code": SqmCouponCode; "sqm-divided-layout": SqmDividedLayout; @@ -11075,6 +11087,7 @@ declare module "@stencil/core" { "sqm-card-feed": LocalJSX.SqmCardFeed & JSXBase.HTMLAttributes; "sqm-checkbox-field": LocalJSX.SqmCheckboxField & JSXBase.HTMLAttributes; "sqm-close-button": LocalJSX.SqmCloseButton & JSXBase.HTMLAttributes; + "sqm-code-check": LocalJSX.SqmCodeCheck & JSXBase.HTMLAttributes; "sqm-context-router": LocalJSX.SqmContextRouter & JSXBase.HTMLAttributes; "sqm-coupon-code": LocalJSX.SqmCouponCode & JSXBase.HTMLAttributes; "sqm-divided-layout": LocalJSX.SqmDividedLayout & JSXBase.HTMLAttributes; diff --git a/packages/mint-components/src/components/sqm-widget-verification/keys.ts b/packages/mint-components/src/components/sqm-widget-verification/keys.ts index 4647e34e5..d43ebf388 100644 --- a/packages/mint-components/src/components/sqm-widget-verification/keys.ts +++ b/packages/mint-components/src/components/sqm-widget-verification/keys.ts @@ -1 +1,2 @@ export const SHOW_CODE_NAMESPACE = "sq:code-verification"; +export const VERIFICATION_EMAIL_NAMESPACE = "sq:verification-email"; diff --git a/packages/mint-components/src/components/sqm-widget-verification/sqm-code-check/sqm-code-check.tsx b/packages/mint-components/src/components/sqm-widget-verification/sqm-code-check/sqm-code-check.tsx new file mode 100644 index 000000000..09fa6d77c --- /dev/null +++ b/packages/mint-components/src/components/sqm-widget-verification/sqm-code-check/sqm-code-check.tsx @@ -0,0 +1,39 @@ +import { Component, h } from "@stencil/core"; +import { useCodeCheck } from "./useCodeCheck"; +import { withHooks } from "@saasquatch/stencil-hooks"; + +@Component({ + tag: "sqm-code-check", + shadow: true, +}) +export class CodeCheck { + constructor() { + withHooks(this); + } + disconnectedCallback() {} + render() { + const props = useCodeCheck(); + + return ( +
+ + + + + +
+ + {props.validationError && ( + INVALID CODE AHHHHHHHHh + )} +
+
+ Didn't get an email? + +
+
+ ); + } +} diff --git a/packages/mint-components/src/components/sqm-widget-verification/sqm-code-check/useCodeCheck.ts b/packages/mint-components/src/components/sqm-widget-verification/sqm-code-check/useCodeCheck.ts new file mode 100644 index 000000000..c8c15e59e --- /dev/null +++ b/packages/mint-components/src/components/sqm-widget-verification/sqm-code-check/useCodeCheck.ts @@ -0,0 +1,117 @@ +import { + setVerificationContext, + useMutation, + useParent, + useParentValue, +} from "@saasquatch/component-boilerplate"; +import { useEffect, useState } from "@saasquatch/stencil-hooks"; +import { SHOW_CODE_NAMESPACE, VERIFICATION_EMAIL_NAMESPACE } from "../keys"; +import { + useVerificationEmailMutation, + VerificationEmailMutation, +} from "../sqm-email-check/useEmailCheck"; +import { VERIFICATION_CONTEXT_NAME } from "../../../../../component-environment/dist"; + +export function useCodeCheck() { + const [showCode, setShowCode] = useParent(SHOW_CODE_NAMESPACE); + const email = useParentValue( + VERIFICATION_EMAIL_NAMESPACE + ); + + const [codeRef, setCodeRef] = useState(null); + const [validationError, setValidationError] = useState(false); + const [request, { loading: resendLoading, data, errors: resendErrors }] = + useVerificationEmailMutation(); + + useEffect(() => { + if (!codeRef) return; + + const codeElements = Array.from( + codeRef.querySelectorAll(`input[name="code"]`) + ) as HTMLInputElement[]; + + console.log({ codeElements }); + codeElements.forEach((element, idx) => { + element.addEventListener("focus", (e) => { + console.log("focussed"); + (e.target as HTMLInputElement).select(); + }); + element.addEventListener("keydown", (e: any) => { + if (e.key === "Backspace" && e.target.value === "") { + codeElements[Math.max(0, idx - 1)].focus(); + } + }); + element.addEventListener("input", (e: any) => { + const input = e.target.value; + if (!input) return; + if (idx === codeElements.length - 1) { + e.target.value = input.slice(-1); + return; + } + + if (input.length > 1) { + const rest = input.slice(1); + e.target.value = input.slice(0, 1); + codeElements[idx + 1].value = rest; + codeElements[idx + 1].dispatchEvent(new Event("input")); + } + codeElements[idx + 1].focus(); + }); + }); + }, [codeRef]); + + const reset = () => { + setShowCode(false); + setValidationError(false); + }; + + const resendEmail = async () => { + console.log({ email }); + if (!email) { + console.error("No email to send a repeat email to"); + return; + } + await request(email); + }; + + console.log({ data }); + + const onCheckCode = () => { + const codeElements = Array.from( + codeRef.querySelectorAll(`input[name="code"]`) + ) as HTMLInputElement[]; + + if (codeElements.find((el) => !el.value)) { + setValidationError(true); + return; + } + + let code = ""; + codeElements.forEach((element) => { + code = `${code}${element.value}`; + }); + + console.log({ code }); + + // Async check here + if (code === "12345") { + // Hardcoded jwt for my testing. Needs to match user identity id and accountId + setVerificationContext({ + token: + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7ImlkIjoidGVzdHVzZXIiLCJhY2NvdW50SWQiOiJ0ZXN0dXNlciIsImVtYWlsIjoidGVzdHVzZXJAZXhhbXBsZS5jb20ifX0.3d3_4i9IeCeFDXMi-oXeSyyH2Yk_9xyVEtVJ0iJc_SA", + }); + reset(); + } else { + setValidationError(true); + } + }; + + return { + setCodeRef, + onCheckCode, + resendEmail, + validationError, + resendLoading, + resendErrors, + }; +} diff --git a/packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/sqm-email-check.tsx b/packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/sqm-email-check.tsx index fac0777ea..0456f7a69 100644 --- a/packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/sqm-email-check.tsx +++ b/packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/sqm-email-check.tsx @@ -1,8 +1,6 @@ -import { useParent } from "@saasquatch/component-boilerplate"; import { withHooks } from "@saasquatch/stencil-hooks"; -import { useState } from "@saasquatch/universal-hooks"; import { Component, h } from "@stencil/core"; -import { SHOW_CODE_NAMESPACE } from "../keys"; +import { useEmailCheck } from "./useEmailCheck"; /** * @uiName Widget Verification Gate @@ -18,48 +16,14 @@ export class WidgetEmailVerification { disconnectedCallback() {} render() { - const [_, setShowCode] = useParent(SHOW_CODE_NAMESPACE); - const [email, setEmail] = useState(""); - + const props = useEmailCheck(); return (
- setEmail(e.target.value)} - /> - +
+ + +
); - - // const Code = () => { - // return ( - //
- // - // - // - // - // - //
- // - //
- // ); - // }; - - // const verificationStep = () => { - // switch (props.step) { - // case "email": - // return ; - // case "code": - // return ; - // } - // }; - - // return ( - //
- //

Cash Payouts

- // {verificationStep()} - //
- // ); } } diff --git a/packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/useEmailCheck.ts b/packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/useEmailCheck.ts new file mode 100644 index 000000000..912f9f833 --- /dev/null +++ b/packages/mint-components/src/components/sqm-widget-verification/sqm-email-check/useEmailCheck.ts @@ -0,0 +1,76 @@ +import { + useMutation, + useParent, + useUserIdentity, +} from "@saasquatch/component-boilerplate"; +import { useState } from "@saasquatch/universal-hooks"; +import { gql } from "graphql-request"; +import { SHOW_CODE_NAMESPACE, VERIFICATION_EMAIL_NAMESPACE } from "../keys"; + +export const VerificationEmailMutation = gql` + mutation sendVerificationEmail($key: String!, $toAddress: String!) { + sendPreviewEmail(emailKey: $key, toAddress: $toAddress) + } +`; + +// TODO: Move to component-boilerplate +export function useVerificationEmailMutation() { + const [request, { loading, data, errors }] = useMutation( + VerificationEmailMutation + ); + + const sendVerificationEmailMutation = async (toAddress: string) => { + return true; + + // TODO: Needs new mutation + // try { + // const result = await request({ + // toAddress, + // key: "verification-code-email", + // }); + // if (result instanceof Error || !result) throw new Error(); + + // return result; + // } catch (e) { + // return undefined; + // } + }; + + return [ + sendVerificationEmailMutation, + { + loading, + data, + errors, + }, + ] as const; +} + +export function useEmailCheck() { + const [_, setShowCode] = useParent(SHOW_CODE_NAMESPACE); + const [__, setEmail] = useParent(VERIFICATION_EMAIL_NAMESPACE); + + const [error, setError] = useState(false); + const [sendVerificationEmailMutation, { loading, data, errors }] = + useVerificationEmailMutation(); + + const submitEmail = async (e: any) => { + e.preventDefault(); + const formData = new FormData(e.target as HTMLFormElement); + const toAddress = formData.get("email").toString(); + console.log({ toAddress }); + + const result = await sendVerificationEmailMutation(toAddress); + if (!result) setError(true); + else { + setEmail(toAddress); + setShowCode(true); + } + }; + + return { + submitEmail, + loading, + error: error ? "Something happened" : errors?.message, + }; +} diff --git a/packages/mint-components/src/components/sqm-widget-verification/sqm-widget-verification.tsx b/packages/mint-components/src/components/sqm-widget-verification/sqm-widget-verification.tsx index a373d0fb0..6823ae0ef 100644 --- a/packages/mint-components/src/components/sqm-widget-verification/sqm-widget-verification.tsx +++ b/packages/mint-components/src/components/sqm-widget-verification/sqm-widget-verification.tsx @@ -2,7 +2,7 @@ import { withHooks } from "@saasquatch/stencil-hooks"; import { Component, h } from "@stencil/core"; import { useWidgetVerification } from "./useWidgetVerification"; import { useParentState } from "@saasquatch/component-boilerplate"; -import { SHOW_CODE_NAMESPACE } from "./keys"; +import { SHOW_CODE_NAMESPACE, VERIFICATION_EMAIL_NAMESPACE } from "./keys"; import { WidgetEmailVerification } from "./sqm-email-check/sqm-email-check"; /** @@ -24,29 +24,17 @@ export class WidgetVerification { namespace: SHOW_CODE_NAMESPACE, initialValue: false, }); - - const props = useWidgetVerification(); - - const Code = () => { - return ( -
- - - - - -
- -
- ); - }; + const [email, setEmail] = useParentState({ + namespace: VERIFICATION_EMAIL_NAMESPACE, + initialValue: false, + }); const verificationStep = () => { switch (showCode) { case false: return ; case true: - return ; + return ; } }; diff --git a/packages/mint-components/src/components/sqm-widget-verification/useWidgetVerification.ts b/packages/mint-components/src/components/sqm-widget-verification/useWidgetVerification.ts index 6cb314553..7acef8390 100644 --- a/packages/mint-components/src/components/sqm-widget-verification/useWidgetVerification.ts +++ b/packages/mint-components/src/components/sqm-widget-verification/useWidgetVerification.ts @@ -1,64 +1,3 @@ -import { - setVerificationContext, - useVerificationContext, -} from "@saasquatch/component-boilerplate"; -import { useEffect, useState } from "@saasquatch/universal-hooks"; - export function useWidgetVerification() { - const [step, setStep] = useState<"email" | "code">("email"); - const [email, setEmail] = useState(null); - const [codeRef, setCodeRef] = useState(null); - - const onSubmitEmail = () => { - setStep("code"); - }; - - useEffect(() => { - if (!codeRef) return; - - const codeElements = Array.from( - codeRef.querySelectorAll(`input[name="code"]`) - ) as HTMLInputElement[]; - - console.log({ codeElements }); - codeElements.forEach((element, idx) => { - element.addEventListener("keydown", (e: any) => { - if (e.key === "Backspace" && e.target.value === "") { - codeElements[Math.max(0, idx - 1)].focus(); - } - }); - element.addEventListener("input", (e: any) => { - const input = e.target.value; - if (!input) return; - if (idx === codeElements.length - 1) { - e.target.value = input.slice(-1); - return; - } - - if (input.length > 1) { - const rest = input.slice(1); - e.target.value = input.slice(0, 1); - codeElements[idx + 1].value = rest; - codeElements[idx + 1].dispatchEvent(new Event("input")); - } - codeElements[idx + 1].focus(); - }); - }); - }, [codeRef]); - - const onCheckCode = () => { - setVerificationContext({ - token: - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IklSTVhzWXk2WVlxcTQ2OTQzN21HOEVSUXQ4UW9LRkJhRzEifQ.eyJ1c2VyIjp7ImlkIjoiOThkODNlZGIwMmQ3ZTdjOTViY2Q2MjY3ZDZlN2RkMWU0NDJiNGMyMWJkZDQ4ZjY4NTgyMjIwYTVlNzgxMDdkYyIsImFjY291bnRJZCI6Ijk4ZDgzZWRiMDJkN2U3Yzk1YmNkNjI2N2Q2ZTdkZDFlNDQyYjRjMjFiZGQ0OGY2ODU4MjIyMGE1ZTc4MTA3ZGMiLCJlbWFpbCI6ImltcGFjdHFhbWFudWFsK3VzMUBnbWFpbC5jb20ifX0._CwBBMh6mX0WpoV2D3H_LfkP-i-D_bkgv7Q0ZCUhRTI", - }); - }; - - return { - step, - email, - setEmail, - setCodeRef, - onCheckCode, - onSubmitEmail, - }; + return {}; } diff --git a/packages/mint-components/src/index.html b/packages/mint-components/src/index.html index 23d269214..3d04e04f4 100644 --- a/packages/mint-components/src/index.html +++ b/packages/mint-components/src/index.html @@ -9,13 +9,13 @@ Mint Components Stencilbook - + - +