diff --git a/clients/banking/package.json b/clients/banking/package.json index eb2438232..92924bf62 100644 --- a/clients/banking/package.json +++ b/clients/banking/package.json @@ -24,8 +24,8 @@ "@sentry/react": "7.81.1", "@swan-io/boxed": "1.2.0", "@swan-io/chicane": "1.4.1", - "@swan-io/lake": "4.0.2", - "@swan-io/shared-business": "4.0.2", + "@swan-io/lake": "4.0.3", + "@swan-io/shared-business": "4.0.3", "@urql/exchange-graphcache": "6.3.3", "core-js": "3.33.3", "dayjs": "1.11.10", diff --git a/clients/banking/src/components/AccountArea.tsx b/clients/banking/src/components/AccountArea.tsx index bdbae145a..9c288a66e 100644 --- a/clients/banking/src/components/AccountArea.tsx +++ b/clients/banking/src/components/AccountArea.tsx @@ -237,6 +237,7 @@ export const AccountArea = ({ accountMembershipId }: Props) => { hasTransactions, identificationStatus, accountHolderType: account?.holder.info.__typename, + verificationStatus: account?.holder.verificationStatus, isIndividual, requireFirstTransfer, isLegalRepresentative: accountMembership?.legalRepresentative ?? false, @@ -244,6 +245,7 @@ export const AccountArea = ({ accountMembershipId }: Props) => { }) .returnType() // if payment level limitations have been lifted, no need for activation + .with({ verificationStatus: "Refused", isLegalRepresentative: true }, () => "refused") .with( { account: { paymentLevel: "Unlimited", paymentAccountType: "PaymentService" } }, () => "none", @@ -402,54 +404,57 @@ export const AccountArea = ({ accountMembershipId }: Props) => { paymentMenuIsVisible, cardMenuIsVisible, memberMenuIsVisible, - }) => [ - { - matchRoutes: ["AccountTransactionsArea"], - iconActive: "apps-list-filled", - icon: "apps-list-regular", - name: t("navigation.history"), - to: Router.AccountTransactionsListRoot({ accountMembershipId }), - hidden: !historyMenuIsVisible, - }, - { - matchRoutes: ["AccountDetailsArea"], - iconActive: "building-bank-filled", - icon: "building-bank-regular", - name: t("navigation.account"), - to: Router.AccountDetailsIban({ accountMembershipId }), - hidden: !detailsMenuIsVisible, - }, - { - matchRoutes: ["AccountPaymentsArea"], - iconActive: "arrow-swap-filled", - icon: "arrow-swap-regular", - name: t("navigation.transfer"), - to: Router.AccountPaymentsRoot({ accountMembershipId }), - hidden: !paymentMenuIsVisible, - }, - { - matchRoutes: ["AccountCardsArea"], - iconActive: "payment-filled", - icon: "payment-regular", - name: t("navigation.cards"), - to: Router.AccountCardsList({ accountMembershipId }), - hidden: !cardMenuIsVisible, - }, - { - matchRoutes: ["AccountMembersArea"], - iconActive: "people-filled", - icon: "people-regular", - name: t("navigation.members"), - to: Router.AccountMembersList({ accountMembershipId }), - hidden: !memberMenuIsVisible, - hasNotifications: Option.fromNullable(accountMembership.account) - .map( - ({ accountMembershipsWithBindingUserError }) => - accountMembershipsWithBindingUserError.totalCount > 0, - ) - .getWithDefault(false), - }, - ], + }) => + holder?.verificationStatus === "Refused" + ? [] + : [ + { + matchRoutes: ["AccountTransactionsArea"], + iconActive: "apps-list-filled", + icon: "apps-list-regular", + name: t("navigation.history"), + to: Router.AccountTransactionsListRoot({ accountMembershipId }), + hidden: !historyMenuIsVisible, + }, + { + matchRoutes: ["AccountDetailsArea"], + iconActive: "building-bank-filled", + icon: "building-bank-regular", + name: t("navigation.account"), + to: Router.AccountDetailsIban({ accountMembershipId }), + hidden: !detailsMenuIsVisible, + }, + { + matchRoutes: ["AccountPaymentsArea"], + iconActive: "arrow-swap-filled", + icon: "arrow-swap-regular", + name: t("navigation.transfer"), + to: Router.AccountPaymentsRoot({ accountMembershipId }), + hidden: !paymentMenuIsVisible, + }, + { + matchRoutes: ["AccountCardsArea"], + iconActive: "payment-filled", + icon: "payment-regular", + name: t("navigation.cards"), + to: Router.AccountCardsList({ accountMembershipId }), + hidden: !cardMenuIsVisible, + }, + { + matchRoutes: ["AccountMembersArea"], + iconActive: "people-filled", + icon: "people-regular", + name: t("navigation.members"), + to: Router.AccountMembersList({ accountMembershipId }), + hidden: !memberMenuIsVisible, + hasNotifications: Option.fromNullable(accountMembership.account) + .map( + ({ accountMembershipsWithBindingUserError }) => + accountMembershipsWithBindingUserError.totalCount > 0, + ) + .getWithDefault(false), + }, + ], ) .getWithDefault([]); @@ -673,14 +678,14 @@ export const AccountArea = ({ accountMembershipId }: Props) => { const indexUrl: string = historyMenuIsVisible ? Router.AccountTransactionsListRoot({ accountMembershipId }) : detailsMenuIsVisible - ? Router.AccountDetailsIban({ accountMembershipId }) - : paymentMenuIsVisible - ? Router.AccountPaymentsRoot({ accountMembershipId }) - : cardMenuIsVisible - ? Router.AccountCardsList({ accountMembershipId }) - : memberMenuIsVisible - ? Router.AccountMembersList({ accountMembershipId }) - : ""; + ? Router.AccountDetailsIban({ accountMembershipId }) + : paymentMenuIsVisible + ? Router.AccountPaymentsRoot({ accountMembershipId }) + : cardMenuIsVisible + ? Router.AccountCardsList({ accountMembershipId }) + : memberMenuIsVisible + ? Router.AccountMembersList({ accountMembershipId }) + : ""; if (accountMembership.user?.id !== user?.id) { return ; @@ -690,6 +695,19 @@ export const AccountArea = ({ accountMembershipId }: Props) => { accountMembership.statusInfo.status !== "BindingUserError" && accountMembership.canManageAccountMembership; + if (holder?.verificationStatus === "Refused") { + return ( + + ); + } return ( }> {match(route) diff --git a/clients/banking/src/components/AccountPicker.tsx b/clients/banking/src/components/AccountPicker.tsx index 404c06636..5a3d57f71 100644 --- a/clients/banking/src/components/AccountPicker.tsx +++ b/clients/banking/src/components/AccountPicker.tsx @@ -242,7 +242,7 @@ export const AccountPicker = ({ accountMembershipId, onPressItem }: Props) => { }); }; -export type AccountActivationTag = "actionRequired" | "pending" | "none"; +export type AccountActivationTag = "actionRequired" | "pending" | "none" | "refused"; type AccountPickerButtonProps = { desktop: boolean; @@ -315,29 +315,40 @@ export const AccountPickerButton = forwardRef( {activationTag !== "none" && ( - [ - styles.activationLink, - hovered && styles.activationLinkHovered, - ]} - > - {match(activationTag) - .with("actionRequired", () => ( - - {t("accountActivation.menuTag.actionRequired")} + {match(activationTag) + .with("refused", () => ( + + + {t("accountActivation.menuTag.refused")} - )) - .with("pending", () => ( - - {t("accountActivation.menuTag.pending")} - - )) - .exhaustive()} + + )) + .otherwise(activationTag => ( + [ + styles.activationLink, + hovered && styles.activationLinkHovered, + ]} + > + {match(activationTag) + .with("actionRequired", () => ( + + {t("accountActivation.menuTag.actionRequired")} + + )) + .with("pending", () => ( + + {t("accountActivation.menuTag.pending")} + + )) + + .exhaustive()} - - + + + ))} {activationLinkActive && ( diff --git a/clients/banking/src/locales/de.json b/clients/banking/src/locales/de.json index 3c19377be..f23a4b032 100644 --- a/clients/banking/src/locales/de.json +++ b/clients/banking/src/locales/de.json @@ -26,8 +26,11 @@ "accountActivation.identity.title": "Identitätsprüfung", "accountActivation.menuTag.actionRequired": "Aktion erforderlich", "accountActivation.menuTag.pending": "Verifizierung steht noch aus", + "accountActivation.menuTag.refused": "Abgelehnt", "accountActivation.pendingDocuments.text": "Bitte haben Sie etwas Geduld, während wir die Dokumente überprüfen. Dies dauert normalerweise maximal 72 Stunden.", "accountActivation.pendingDocuments.title": "Wir prüfen Ihre Unterlagen.", + "accountActivation.refused.description": "Unsere Zahlungspartner überprüfen alle potenziellen Kontoinhaber gemäß strenger Vorschriften.\nLeider entsprach die Überprüfung für {name} nicht ihren Kriterien.\n\nBei Fragen senden Sie bitte eine E-Mail an {email}.", + "accountActivation.refused.title": "Leider können wir Ihr Konto nicht eröffnen", "accountActivation.tag.done": "Erledigt", "accountActivation.tag.todo": "Aufgaben", "accountActivation.title": "Kontoaktivierung", diff --git a/clients/banking/src/locales/en.json b/clients/banking/src/locales/en.json index 830eee152..cb0ce181d 100644 --- a/clients/banking/src/locales/en.json +++ b/clients/banking/src/locales/en.json @@ -26,8 +26,11 @@ "accountActivation.identity.title": "Identity verification", "accountActivation.menuTag.actionRequired": "Action required", "accountActivation.menuTag.pending": "Pending verification", + "accountActivation.menuTag.refused": "Refused", "accountActivation.pendingDocuments.text": "Please bear with us while we review your documents. This can take up to 72 hours.", "accountActivation.pendingDocuments.title": "We're reviewing your supporting documents.", + "accountActivation.refused.description": "Our payment partners review all potential account holders according to strict regulations.\nUnfortunately, the review for {name} did not meet their criteria.\n\nPlease send an email to {email} if you have any questions.", + "accountActivation.refused.title": "Regrettably, we can’t open your account", "accountActivation.tag.done": "Done", "accountActivation.tag.todo": "To do", "accountActivation.title": "Account activation", diff --git a/clients/banking/src/locales/es.json b/clients/banking/src/locales/es.json index 742597519..364da7219 100644 --- a/clients/banking/src/locales/es.json +++ b/clients/banking/src/locales/es.json @@ -26,8 +26,11 @@ "accountActivation.identity.title": "Verificación de identidad", "accountActivation.menuTag.actionRequired": "Acción necesaria", "accountActivation.menuTag.pending": "Pendiente de verificación", + "accountActivation.menuTag.refused": "Rechazado", "accountActivation.pendingDocuments.text": "Ten paciencia mientras revisamos tus documentos. Puede tardar hasta 72 horas.", "accountActivation.pendingDocuments.title": "Estamos revisando tus documentos justificativos.", + "accountActivation.refused.description": "Nuestros socios de pago revisan a todos los posibles titulares de cuentas según regulaciones estrictas.\nDesafortunadamente, la revisión para {name} no cumplió con sus criterios.\n\nSi tienes alguna pregunta, envía un correo electrónico a {email}.", + "accountActivation.refused.title": "Lamentablemente, no podemos abrir tu cuenta", "accountActivation.tag.done": "Hecho", "accountActivation.tag.todo": "Pendiente", "accountActivation.title": "Activación de cuenta", diff --git a/clients/banking/src/locales/fr.json b/clients/banking/src/locales/fr.json index b860e1b4f..0f4481c5c 100644 --- a/clients/banking/src/locales/fr.json +++ b/clients/banking/src/locales/fr.json @@ -26,8 +26,11 @@ "accountActivation.identity.title": "Vérification d'identité", "accountActivation.menuTag.actionRequired": "Action requise", "accountActivation.menuTag.pending": "En attente de vérification", + "accountActivation.menuTag.refused": "Refusé", "accountActivation.pendingDocuments.text": "Veuillez patienter pendant que nous examinons vos documents. Cette opération peut prendre jusqu'à 72 heures.", "accountActivation.pendingDocuments.title": "Nous examinons vos documents justificatifs.", + "accountActivation.refused.description": "Nos partenaires de paiement examinent tous les demandeurs de compte potentiel selon des réglementations strictes.\nMalheureusement, l'examen de {name} n'a pas répondu à leurs critères.\n\nVeuillez envoyer un courriel à {email} si vous avez des questions.", + "accountActivation.refused.title": "Malheureusement, nous ne pouvons pas ouvrir votre compte", "accountActivation.tag.done": "Terminé", "accountActivation.tag.todo": "À faire", "accountActivation.title": "Activation du compte", diff --git a/clients/banking/src/locales/it.json b/clients/banking/src/locales/it.json index 7ee6d0fa7..d0d829314 100644 --- a/clients/banking/src/locales/it.json +++ b/clients/banking/src/locales/it.json @@ -26,8 +26,11 @@ "accountActivation.identity.title": "Verifica dell'identità", "accountActivation.menuTag.actionRequired": "Azione richiesta", "accountActivation.menuTag.pending": "Verifica in attesa", + "accountActivation.menuTag.refused": "Rifiutato", "accountActivation.pendingDocuments.text": "La preghiamo di attendere mentre esaminiamo i suoi documenti. Questa operazione può richiedere fino a 72 ore.", "accountActivation.pendingDocuments.title": "Abbiamo ricevuto i suoi documenti.", + "accountActivation.refused.description": "I nostri partner di pagamento esaminano tutti i potenziali titolari di conto in conformità con rigorose normative.\nSfortunatamente, la revisione per {name} non ha soddisfatto i loro criteri.\n\nSe hai domande, invia un'email a {email}.", + "accountActivation.refused.title": "Purtroppo non possiamo aprire il tuo conto", "accountActivation.tag.done": "Fatto", "accountActivation.tag.todo": "Da fare", "accountActivation.title": "Attivazione conto", diff --git a/clients/banking/src/locales/nl.json b/clients/banking/src/locales/nl.json index eb044830b..3aa41232e 100644 --- a/clients/banking/src/locales/nl.json +++ b/clients/banking/src/locales/nl.json @@ -26,8 +26,11 @@ "accountActivation.identity.title": "Identiteitsverificatie", "accountActivation.menuTag.actionRequired": "Actie vereist", "accountActivation.menuTag.pending": "In afwachting van verificatie", + "accountActivation.menuTag.refused": "Geweigerd", "accountActivation.pendingDocuments.text": "Nog even geduld! We gaan je documenten beoordelen. Dit duurt maximaal 72 uur.", "accountActivation.pendingDocuments.title": "We hebben je documenten ontvangen.", + "accountActivation.refused.description": "Onze betalingspartners beoordelen alle potentiële rekeninghouders volgens strikte regelgeving.\nHelaas voldoet de beoordeling voor {name} niet aan hun criteria.\n\nAls je vragen hebt, stuur dan een e-mail naar {email}.", + "accountActivation.refused.title": "Helaas kunnen we je account niet openen", "accountActivation.tag.done": "Klaar", "accountActivation.tag.todo": "Taken", "accountActivation.title": "Accountactivatie", diff --git a/clients/banking/src/locales/pt.json b/clients/banking/src/locales/pt.json index bfeec0744..603d7155c 100644 --- a/clients/banking/src/locales/pt.json +++ b/clients/banking/src/locales/pt.json @@ -26,8 +26,11 @@ "accountActivation.identity.title": "Verificação de identidade", "accountActivation.menuTag.actionRequired": "Ação necessária", "accountActivation.menuTag.pending": "Verificação pendente", + "accountActivation.menuTag.refused": "Recusado", "accountActivation.pendingDocuments.text": "Por favor, aguarde enquanto revemos os seus documentos. Este processo pode demorar até 72 horas.", "accountActivation.pendingDocuments.title": "Estamos verificando os seus documentos de apoio.", + "accountActivation.refused.description": "Nossos parceiros de pagamento analisam todos os potenciais titulares de conta de acordo com regulamentações rigorosas.\nInfelizmente, a análise para {name} não atendeu aos critérios deles.\n\nPor favor, envie um e-mail para {email} se tiver alguma dúvida.", + "accountActivation.refused.title": "Lamentavelmente, não podemos abrir a sua conta", "accountActivation.tag.done": "Feito", "accountActivation.tag.todo": "Por fazer", "accountActivation.title": "Ativação de conta", diff --git a/clients/banking/src/pages/AccountActivationPage.tsx b/clients/banking/src/pages/AccountActivationPage.tsx index 576051dfe..2b8d3ffb2 100644 --- a/clients/banking/src/pages/AccountActivationPage.tsx +++ b/clients/banking/src/pages/AccountActivationPage.tsx @@ -8,6 +8,7 @@ import { LakeAlert } from "@swan-io/lake/src/components/LakeAlert"; import { LakeButton } from "@swan-io/lake/src/components/LakeButton"; import { LakeHeading } from "@swan-io/lake/src/components/LakeHeading"; import { LakeText } from "@swan-io/lake/src/components/LakeText"; +import { Link } from "@swan-io/lake/src/components/Link"; import { ReadOnlyFieldList } from "@swan-io/lake/src/components/ReadOnlyFieldList"; import { Separator } from "@swan-io/lake/src/components/Separator"; import { Space } from "@swan-io/lake/src/components/Space"; @@ -20,6 +21,7 @@ import { useBoolean } from "@swan-io/lake/src/hooks/useBoolean"; import { useResponsive } from "@swan-io/lake/src/hooks/useResponsive"; import { isNotNullish, isNotNullishOrEmpty, isNullish } from "@swan-io/lake/src/utils/nullish"; import { useQueryWithErrorBoundary } from "@swan-io/lake/src/utils/urql"; +import { isMobile } from "@swan-io/lake/src/utils/userAgent"; import { AdditionalInfo, SupportChat } from "@swan-io/shared-business/src/components/SupportChat"; import dayjs from "dayjs"; import { ReactNode, useCallback, useMemo, useRef } from "react"; @@ -34,7 +36,7 @@ import { import { AccountActivationPageDocument } from "../graphql/partner"; import { openPopup } from "../states/popup"; import { env } from "../utils/env"; -import { t } from "../utils/i18n"; +import { formatNestedMessage, t } from "../utils/i18n"; import { Router } from "../utils/routes"; const styles = StyleSheet.create({ @@ -122,6 +124,9 @@ const styles = StyleSheet.create({ illustrationPanel: { ...commonStyles.fill, }, + errorContainer: { + ...commonStyles.fill, + }, }); type StepScrollViewProps = { @@ -441,6 +446,32 @@ export const AccountActivationPage = ({ return ; } + if (holder?.verificationStatus === "Refused") { + return ( + + + + + + {t("accountActivation.refused.title")} + + + + + + {formatNestedMessage("accountActivation.refused.description", { + name: holder.info.name, + email: ( + + support@swan.io + + ), + })} + + + ); + } + const content = match(step) .with( "IdentityVerificationPending", diff --git a/clients/onboarding/package.json b/clients/onboarding/package.json index 3dc762910..fd2c28370 100644 --- a/clients/onboarding/package.json +++ b/clients/onboarding/package.json @@ -24,8 +24,8 @@ "@sentry/react": "7.81.1", "@swan-io/boxed": "1.2.0", "@swan-io/chicane": "1.4.1", - "@swan-io/lake": "4.0.2", - "@swan-io/shared-business": "4.0.2", + "@swan-io/lake": "4.0.3", + "@swan-io/shared-business": "4.0.3", "@urql/exchange-graphcache": "6.3.3", "core-js": "3.33.3", "dayjs": "1.11.10", diff --git a/yarn.lock b/yarn.lock index 2675fe403..c0ac8f92a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2520,10 +2520,10 @@ history "^5.3.0" use-sync-external-store "^1.2.0" -"@swan-io/lake@4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@swan-io/lake/-/lake-4.0.2.tgz#87aa5b87203981060bcb03068295c72b0b0f939c" - integrity sha512-HZqt2nOiUiViT1RxA6fBt/TKU2k4MHKx6rVsKbRqIJjcfPMRAwDRvEEXsWrJs4CewqFaQDD2f54p+32cKKzqrA== +"@swan-io/lake@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@swan-io/lake/-/lake-4.0.3.tgz#78fcd4bcb56558b880d66d8504bd6ffdcf10b1d6" + integrity sha512-F66kjyGXWCoFQG3vc61lNjLoEDLQc/Am3UE2Jc9hloaO2c0h0Ah2vpStXZQEEhb05DtfDhF2SjR9BeQsMyTI6Q== dependencies: "@popperjs/core" "^2.11.8" "@react-three/drei" "^9.88.17" @@ -2546,10 +2546,10 @@ urql "^4.0.6" uuid "^9.0.1" -"@swan-io/shared-business@4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@swan-io/shared-business/-/shared-business-4.0.2.tgz#1178eed44607c61519169b45b0023c3ffbdf636a" - integrity sha512-vjhXArTIltyvM91Ogai5k0MCvMsfQLbJFrCx2vkHTTyd+fqFBi0AMW1k4xAm26+Z+AnAtxsgD7XjetAuEMZU2g== +"@swan-io/shared-business@4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@swan-io/shared-business/-/shared-business-4.0.3.tgz#3cdee50135756f735e64e5e7c9db76eadee3181d" + integrity sha512-q6k4ECFf7ZMS3vhPcdD9VitoDK1khy5OsAWBthe5YCS1ITIT4m+b44g54+1j6W10YqAEDVnE2ipYGogTKibmlA== dependencies: "@formatjs/intl" "^2.9.9" "@googlemaps/js-api-loader" "1.16.2"