diff --git a/packages/ui/src/containers/VerificationCode/use-sign-in-flow-code-verification.ts b/packages/ui/src/containers/VerificationCode/use-sign-in-flow-code-verification.ts index 1d3780384..8cc996c1d 100644 --- a/packages/ui/src/containers/VerificationCode/use-sign-in-flow-code-verification.ts +++ b/packages/ui/src/containers/VerificationCode/use-sign-in-flow-code-verification.ts @@ -14,6 +14,7 @@ import { useConfirmModal } from '@/hooks/use-confirm-modal'; import useRequiredProfileErrorHandler from '@/hooks/use-required-profile-error-handler'; import { useSieMethods } from '@/hooks/use-sie'; import type { VerificationCodeIdentifier } from '@/types'; +import { UserFlow } from '@/types'; import { formatPhoneNumberWithCountryCallingCode } from '@/utils/country-code'; import useGeneralVerificationCodeErrorHandler from './use-general-verification-code-error-handler'; @@ -33,7 +34,10 @@ const useSignInFlowCodeVerification = ( const { signInMode } = useSieMethods(); - const requiredProfileErrorHandlers = useRequiredProfileErrorHandler({ replace: true }); + const requiredProfileErrorHandlers = useRequiredProfileErrorHandler({ + replace: true, + flow: UserFlow.signIn, + }); const { run: registerWithIdentifierAsync } = useApi( registerWithVerifiedIdentifier, diff --git a/packages/ui/src/hooks/use-password-sign-in.ts b/packages/ui/src/hooks/use-password-sign-in.ts index 305a4af21..91eb3b0e5 100644 --- a/packages/ui/src/hooks/use-password-sign-in.ts +++ b/packages/ui/src/hooks/use-password-sign-in.ts @@ -4,6 +4,7 @@ import type { PasswordSignInPayload } from '@/apis/interaction'; import { signInWithPasswordIdentifier } from '@/apis/interaction'; import type { ErrorHandlers } from '@/hooks/use-api'; import useApi from '@/hooks/use-api'; +import { UserFlow } from '@/types'; import useRequiredProfileErrorHandler from './use-required-profile-error-handler'; @@ -14,7 +15,7 @@ const usePasswordSignIn = () => { setErrorMessage(''); }, []); - const requiredProfileErrorHandler = useRequiredProfileErrorHandler(); + const requiredProfileErrorHandler = useRequiredProfileErrorHandler({ flow: UserFlow.signIn }); const errorHandlers: ErrorHandlers = useMemo( () => ({ diff --git a/packages/ui/src/hooks/use-required-profile-error-handler.ts b/packages/ui/src/hooks/use-required-profile-error-handler.ts index 32bc33706..90f9788bc 100644 --- a/packages/ui/src/hooks/use-required-profile-error-handler.ts +++ b/packages/ui/src/hooks/use-required-profile-error-handler.ts @@ -13,9 +13,10 @@ import { PageContext } from './use-page-context'; type Options = { replace?: boolean; linkSocial?: string; + flow?: UserFlow; }; -const useRequiredProfileErrorHandler = ({ replace, linkSocial }: Options = {}) => { +const useRequiredProfileErrorHandler = ({ replace, linkSocial, flow }: Options = {}) => { const navigate = useNavigate(); const { setToast } = useContext(PageContext); @@ -37,7 +38,7 @@ const useRequiredProfileErrorHandler = ({ replace, linkSocial }: Options = {}) = { pathname: `/${UserFlow.continue}/${missingProfile}`, }, - { replace } + { replace, state: { flow } } ); break; case MissingProfile.email: @@ -47,7 +48,7 @@ const useRequiredProfileErrorHandler = ({ replace, linkSocial }: Options = {}) = pathname: `/${UserFlow.continue}/${missingProfile}`, search: linkSocialQueryString, }, - { replace, state: { registeredSocialIdentity } } + { replace, state: { registeredSocialIdentity, flow } } ); break; case MissingProfile.emailOrPhone: @@ -56,7 +57,7 @@ const useRequiredProfileErrorHandler = ({ replace, linkSocial }: Options = {}) = pathname: `/${UserFlow.continue}/email-or-phone/email`, search: linkSocialQueryString, }, - { replace } + { replace, state: { registeredSocialIdentity, flow } } ); break; @@ -67,7 +68,7 @@ const useRequiredProfileErrorHandler = ({ replace, linkSocial }: Options = {}) = } }, }), - [linkSocial, navigate, replace, setToast] + [flow, linkSocial, navigate, replace, setToast] ); return requiredProfileErrorHandler; diff --git a/packages/ui/src/hooks/use-social-sign-in-listener.ts b/packages/ui/src/hooks/use-social-sign-in-listener.ts index da7e4a731..6dac0f352 100644 --- a/packages/ui/src/hooks/use-social-sign-in-listener.ts +++ b/packages/ui/src/hooks/use-social-sign-in-listener.ts @@ -6,6 +6,7 @@ import { useNavigate } from 'react-router-dom'; import { validate } from 'superstruct'; import { signInWithSocial } from '@/apis/interaction'; +import { UserFlow } from '@/types'; import { socialAccountNotExistErrorDataGuard } from '@/types/guard'; import { parseQueryParameters } from '@/utils'; import { stateValidation } from '@/utils/social-connectors'; @@ -50,7 +51,7 @@ const useSocialSignInListener = (connectorId?: string) => { [connectorId, navigate, registerWithSocial] ); - const requiredProfileErrorHandlers = useRequiredProfileErrorHandler(); + const requiredProfileErrorHandlers = useRequiredProfileErrorHandler({ flow: UserFlow.signIn }); const signInWithSocialErrorHandlers: ErrorHandlers = useMemo( () => ({ diff --git a/packages/ui/src/pages/Continue/EmailOrPhone/index.tsx b/packages/ui/src/pages/Continue/EmailOrPhone/index.tsx index 545c70cb4..04071456a 100644 --- a/packages/ui/src/pages/Continue/EmailOrPhone/index.tsx +++ b/packages/ui/src/pages/Continue/EmailOrPhone/index.tsx @@ -1,10 +1,14 @@ import { SignInIdentifier } from '@logto/schemas'; -import { useParams } from 'react-router-dom'; +import { conditional } from '@silverhand/essentials'; +import { useParams, useLocation } from 'react-router-dom'; +import { validate } from 'superstruct'; import SecondaryPageWrapper from '@/components/SecondaryPageWrapper'; import { EmailContinue } from '@/containers/EmailForm'; import { PhoneContinue } from '@/containers/PhoneForm'; import ErrorPage from '@/pages/ErrorPage'; +import { UserFlow } from '@/types'; +import { continueFlowStateGuard } from '@/types/guard'; type Parameters = { method?: string; @@ -12,12 +16,19 @@ type Parameters = { const EmailOrPhone = () => { const { method = '' } = useParams(); + const { state } = useLocation(); + + const [_, data] = validate(state, continueFlowStateGuard); + const notification = conditional( + data?.flow === UserFlow.signIn && 'description.continue_with_more_information' + ); if (method === SignInIdentifier.Email) { return ( @@ -29,6 +40,7 @@ const EmailOrPhone = () => { diff --git a/packages/ui/src/pages/Continue/SetEmail/index.tsx b/packages/ui/src/pages/Continue/SetEmail/index.tsx index 3ee3eeaa2..2bd4c9b02 100644 --- a/packages/ui/src/pages/Continue/SetEmail/index.tsx +++ b/packages/ui/src/pages/Continue/SetEmail/index.tsx @@ -1,10 +1,17 @@ +import type { TFuncKey } from 'react-i18next'; + import SecondaryPageWrapper from '@/components/SecondaryPageWrapper'; import { EmailContinue } from '@/containers/EmailForm'; -const SetEmail = () => ( +type Props = { + notification?: TFuncKey; +}; + +const SetEmail = (props: Props) => ( diff --git a/packages/ui/src/pages/Continue/SetPassword/index.tsx b/packages/ui/src/pages/Continue/SetPassword/index.tsx index 04e3bd326..770a65b82 100644 --- a/packages/ui/src/pages/Continue/SetPassword/index.tsx +++ b/packages/ui/src/pages/Continue/SetPassword/index.tsx @@ -1,13 +1,19 @@ +import type { TFuncKey } from 'react-i18next'; + import SecondaryPageWrapper from '@/components/SecondaryPageWrapper'; import SetPasswordForm from '@/containers/SetPassword'; import useSetPassword from './use-set-password'; -const SetPassword = () => { +type Props = { + notification?: TFuncKey; +}; + +const SetPassword = (props: Props) => { const { setPassword } = useSetPassword(); return ( - + ); diff --git a/packages/ui/src/pages/Continue/SetPhone/index.tsx b/packages/ui/src/pages/Continue/SetPhone/index.tsx index 7e440e685..aa7ac7c58 100644 --- a/packages/ui/src/pages/Continue/SetPhone/index.tsx +++ b/packages/ui/src/pages/Continue/SetPhone/index.tsx @@ -1,11 +1,18 @@ +import type { TFuncKey } from 'react-i18next'; + import SecondaryPageWrapper from '@/components/SecondaryPageWrapper'; import { PhoneContinue } from '@/containers/PhoneForm'; -const SetPhone = () => { +type Props = { + notification?: TFuncKey; +}; + +const SetPhone = (props: Props) => { return ( diff --git a/packages/ui/src/pages/Continue/SetUsername/index.tsx b/packages/ui/src/pages/Continue/SetUsername/index.tsx index 4e7e3b493..f9a0c6ada 100644 --- a/packages/ui/src/pages/Continue/SetUsername/index.tsx +++ b/packages/ui/src/pages/Continue/SetUsername/index.tsx @@ -1,10 +1,17 @@ +import type { TFuncKey } from 'react-i18next'; + import SecondaryPageWrapper from '@/components/SecondaryPageWrapper'; import { SetUsername as SetUsernameForm } from '@/containers/UsernameForm'; -const SetUsername = () => ( +type Props = { + notification?: TFuncKey; +}; + +const SetUsername = (props: Props) => ( diff --git a/packages/ui/src/pages/Continue/index.tsx b/packages/ui/src/pages/Continue/index.tsx index 85991be9b..b84668e3f 100644 --- a/packages/ui/src/pages/Continue/index.tsx +++ b/packages/ui/src/pages/Continue/index.tsx @@ -1,7 +1,11 @@ import { SignInIdentifier } from '@logto/schemas'; -import { useParams } from 'react-router-dom'; +import { conditional } from '@silverhand/essentials'; +import { useLocation, useParams } from 'react-router-dom'; +import { validate } from 'superstruct'; import ErrorPage from '@/pages/ErrorPage'; +import { UserFlow } from '@/types'; +import { continueFlowStateGuard } from '@/types/guard'; import SetEmail from './SetEmail'; import SetPassword from './SetPassword'; @@ -14,21 +18,28 @@ type Parameters = { const Continue = () => { const { method = '' } = useParams(); + const { state } = useLocation(); + + const [_, data] = validate(state, continueFlowStateGuard); + + const notification = conditional( + data?.flow === UserFlow.signIn && 'description.continue_with_more_information' + ); if (method === 'password') { - return ; + return ; } if (method === SignInIdentifier.Username) { - return ; + return ; } if (method === SignInIdentifier.Email) { - return ; + return ; } if (method === SignInIdentifier.Phone) { - return ; + return ; } return ; diff --git a/packages/ui/src/types/guard.ts b/packages/ui/src/types/guard.ts index 77fb68e96..4247900cb 100644 --- a/packages/ui/src/types/guard.ts +++ b/packages/ui/src/types/guard.ts @@ -26,6 +26,12 @@ export const userFlowGuard = s.enums([ UserFlow.continue, ]); +export const continueFlowStateGuard = s.optional( + s.type({ + flow: userFlowGuard, + }) +); + export const continueMethodGuard = s.union([ s.literal('password'), s.literal('username'), @@ -57,7 +63,7 @@ export const missingProfileErrorDataGuard = s.object({ registeredSocialIdentity, }); -export const registeredSocialIdentityStateGuard = s.object({ +export const registeredSocialIdentityStateGuard = s.type({ registeredSocialIdentity, });