From fde14e71addfd6448135e066c63388fed168be08 Mon Sep 17 00:00:00 2001 From: fabriziofff Date: Wed, 11 Nov 2020 18:32:50 +0100 Subject: [PATCH] feat(Bonus Pagamenti Digitali): [#175488300,#175662744] Iban insertion and workflow (rework due to change request) (#2360) * [#175269179] draft essential details * [#175269179] bpd transaction warning * [#175269179] cancellation badge * [#175269179] fix typescript * [#175269179] fix locales * [#175266668] cancel subscription screen * [#175266668] fix ts * [#175266668] handle unsubscription success / failure * [#175266668] clean & comments * [#175266668] change button style as design * [#175488300] first draft rework IbanKoNotOwned * [#175488300] change behaviour of IbanKONotOwned * [#175488300] . * Update ts/features/bonus/bpd/components/transactionItem/BpdTransactionItem.tsx Co-authored-by: Matteo Boschi * Update ts/features/bonus/bpd/screens/details/transaction/detail/BpdTransactionDetailComponent.tsx Co-authored-by: Matteo Boschi * Update ts/features/bonus/bpd/screens/details/transaction/detail/BpdTransactionDetailComponent.tsx Co-authored-by: Matteo Boschi * [#175269179] refactoring * [#175488300] Iban Prefill * [#175488300] restore main iban * Update ts/features/bonus/bonusVacanze/components/buttons/ButtonConfigurations.ts * Update ts/features/bonus/bpd/screens/details/BpdDetailsScreen.tsx * Update ts/features/bonus/bpd/store/reducers/details/activation/index.ts * [#175488300] refactoring * Update ts/features/bonus/bpd/store/reducers/details/activation/index.ts Co-authored-by: Matteo Boschi --- locales/en/index.yml | 7 +- locales/it/index.yml | 7 +- .../bonus/bpd/screens/iban/MainIbanScreen.tsx | 8 +-- .../iban/insertion/IbanInsertionComponent.tsx | 3 +- .../iban/insertion/IbanInsertionScreen.tsx | 6 +- .../screens/iban/ko/IbanKOCannotVerify.tsx | 1 + .../bpd/screens/iban/ko/IbanKONotOwned.tsx | 71 +++++++++++++++---- .../bonus/bpd/screens/iban/ko/IbanKoBody.tsx | 15 ++-- .../reducers/details/activation/index.ts | 17 +++++ .../details/activation/payoffInstrument.ts | 5 +- 10 files changed, 106 insertions(+), 34 deletions(-) diff --git a/locales/en/index.yml b/locales/en/index.yml index 9c7ff30181e..0e6c6f6ab61 100644 --- a/locales/en/index.yml +++ b/locales/en/index.yml @@ -1644,6 +1644,7 @@ bonus: iban: iban: "IBAN" edit: "Change IBAN" + verify: "Check IBAN" insertion: title: "IBAN for accreditation" body1: "Indicate here the IBAN of your current account, on which you want to receive credit once the ranking has been consolidated." @@ -1657,9 +1658,9 @@ bonus: text1: "If you are sure the IBAN" text2: "identify the account on which you want to receive credit, you can proceed." koNotOwned: - title: "The current account is not in your name" - text1: "The IBAN you entered" - text2: "identify a current account that is not registered in your tax code: are you sure you want to use this IBAN?" + title: "Check the IBAN entered" + text1: "IBAN" + text2: "is not registered to" loading: "We are verifying your IBAN\n\nPlease wait." details: diff --git a/locales/it/index.yml b/locales/it/index.yml index 7e8b12e0de2..ef8f2b07c4a 100644 --- a/locales/it/index.yml +++ b/locales/it/index.yml @@ -1676,6 +1676,7 @@ bonus: iban: iban: "IBAN" edit: "Modifica IBAN" + verify: "Controlla IBAN" insertion: title: "IBAN per l’accredito" body1: "Indica qui l’IBAN del tuo conto corrente, su cui vuoi ricevere l’accredito una volta consolidata la classifica." @@ -1689,9 +1690,9 @@ bonus: text1: "Se sei sicuro che l’IBAN" text2: "identifichi il conto su cui vuoi ricevere gli accrediti, puoi proseguire." koNotOwned: - title: "Il conto corrente non risulta intestato a te" - text1: "L’IBAN che hai inserito" - text2: "identifica un conto corrente che non risulta intestato al tuo codice fiscale: sei sicuro di voler usare questo IBAN?" + title: "Controlla l'IBAN inserito" + text1: "L’IBAN" + text2: "non risulta intestato a" loading: "Stiamo verificando il tuo IBAN\n\nTi preghiamo di attendere." details: diff --git a/ts/features/bonus/bpd/screens/iban/MainIbanScreen.tsx b/ts/features/bonus/bpd/screens/iban/MainIbanScreen.tsx index f70c24f66eb..0e0f17ced1e 100644 --- a/ts/features/bonus/bpd/screens/iban/MainIbanScreen.tsx +++ b/ts/features/bonus/bpd/screens/iban/MainIbanScreen.tsx @@ -10,11 +10,10 @@ import { bpdIbanInsertionResetScreen } from "../../store/actions/iban"; import { bpdUpsertIbanSelector } from "../../store/reducers/details/activation/payoffInstrument"; -import IbanKoCannotVerify from "./ko/IbanKOCannotVerify"; -import IbanKoNotOwned from "./ko/IbanKONotOwned"; -import IbanKOWrong from "./ko/IbanKOWrong"; import IbanLoadingUpsert from "./IbanLoadingUpsert"; import IbanInsertionScreen from "./insertion/IbanInsertionScreen"; +import IbanKoNotOwned from "./ko/IbanKONotOwned"; +import IbanKOWrong from "./ko/IbanKOWrong"; export type Props = ReturnType & ReturnType; @@ -25,13 +24,12 @@ const chooseRenderScreen = (props: Props) => { return ; } else if (isReady(ibanStatus)) { switch (ibanStatus.value) { - case IbanStatus.CANT_VERIFY: - return ; case IbanStatus.NOT_OWNED: return ; case IbanStatus.NOT_VALID: return ; case IbanStatus.OK: + case IbanStatus.CANT_VERIFY: props.reset(); props.completed(); } diff --git a/ts/features/bonus/bpd/screens/iban/insertion/IbanInsertionComponent.tsx b/ts/features/bonus/bpd/screens/iban/insertion/IbanInsertionComponent.tsx index 60152751e28..e540efb788f 100644 --- a/ts/features/bonus/bpd/screens/iban/insertion/IbanInsertionComponent.tsx +++ b/ts/features/bonus/bpd/screens/iban/insertion/IbanInsertionComponent.tsx @@ -15,6 +15,7 @@ type Props = { onBack: () => void; onIbanConfirm: (iban: Iban) => void; onContinue: () => void; + startIban?: string; }; // https://en.wikipedia.org/wiki/International_Bank_Account_Number @@ -31,7 +32,7 @@ const loadLocales = () => ({ }); export const IbanInsertionComponent: React.FunctionComponent = props => { - const [iban, setIban] = useState(""); + const [iban, setIban] = useState(props.startIban ?? ""); const isInvalidIban = iban.length > 0 && Iban.decode(iban).isLeft(); const userCanContinue = !isInvalidIban && iban.length > 0; const { diff --git a/ts/features/bonus/bpd/screens/iban/insertion/IbanInsertionScreen.tsx b/ts/features/bonus/bpd/screens/iban/insertion/IbanInsertionScreen.tsx index 3a8986943cc..7dce8e44ec0 100644 --- a/ts/features/bonus/bpd/screens/iban/insertion/IbanInsertionScreen.tsx +++ b/ts/features/bonus/bpd/screens/iban/insertion/IbanInsertionScreen.tsx @@ -8,6 +8,7 @@ import { bpdIbanInsertionContinue, bpdUpsertIban } from "../../../store/actions/iban"; +import { bpdIbanPrefillSelector } from "../../../store/reducers/details/activation"; import { IbanInsertionComponent } from "./IbanInsertionComponent"; export type Props = ReturnType & @@ -22,6 +23,7 @@ const IbanInsertionScreen: React.FunctionComponent = props => ( onBack={props.cancel} onContinue={props.continue} onIbanConfirm={props.submitIban} + startIban={props.prefillIban} /> ); @@ -31,7 +33,9 @@ const mapDispatchToProps = (dispatch: Dispatch) => ({ submitIban: (iban: Iban) => dispatch(bpdUpsertIban.request(iban)) }); -const mapStateToProps = (_: GlobalState) => ({}); +const mapStateToProps = (state: GlobalState) => ({ + prefillIban: bpdIbanPrefillSelector(state) +}); export default connect( mapStateToProps, diff --git a/ts/features/bonus/bpd/screens/iban/ko/IbanKOCannotVerify.tsx b/ts/features/bonus/bpd/screens/iban/ko/IbanKOCannotVerify.tsx index fb667b9188d..6caf81d6f05 100644 --- a/ts/features/bonus/bpd/screens/iban/ko/IbanKOCannotVerify.tsx +++ b/ts/features/bonus/bpd/screens/iban/ko/IbanKOCannotVerify.tsx @@ -32,6 +32,7 @@ const loadLocales = () => ({ * This screen warns the user that the provided iban cannot be verified. * This is just a warning, the user can continue and the iban has been registered on the bpd remote system. * @constructor + * @deprecated not used anymore, still here just in case of change of mind */ const IbanKoCannotVerify: React.FunctionComponent = props => { const { headerTitle, continueStr, edit, title, text1, text2 } = loadLocales(); diff --git a/ts/features/bonus/bpd/screens/iban/ko/IbanKONotOwned.tsx b/ts/features/bonus/bpd/screens/iban/ko/IbanKONotOwned.tsx index 88708b8562a..ef58385cf04 100644 --- a/ts/features/bonus/bpd/screens/iban/ko/IbanKONotOwned.tsx +++ b/ts/features/bonus/bpd/screens/iban/ko/IbanKONotOwned.tsx @@ -1,17 +1,23 @@ +import * as pot from "italia-ts-commons/lib/pot"; +import { View } from "native-base"; import * as React from "react"; -import { SafeAreaView } from "react-native"; +import { SafeAreaView, StyleSheet } from "react-native"; import { connect } from "react-redux"; import { Dispatch } from "redux"; import image from "../../../../../../../img/pictograms/doubt.png"; +import { Body } from "../../../../../../components/core/typography/Body"; +import { H4 } from "../../../../../../components/core/typography/H4"; +import { Monospace } from "../../../../../../components/core/typography/Monospace"; import { IOStyles } from "../../../../../../components/core/variables/IOStyles"; import { renderInfoRasterImage } from "../../../../../../components/infoScreen/imageRendering"; import { InfoScreenComponent } from "../../../../../../components/infoScreen/InfoScreenComponent"; import BaseScreenComponent from "../../../../../../components/screens/BaseScreenComponent"; import I18n from "../../../../../../i18n"; +import { profileSelector } from "../../../../../../store/reducers/profile"; import { GlobalState } from "../../../../../../store/reducers/types"; import { FooterTwoButtons } from "../../../../bonusVacanze/components/markdown/FooterTwoButtons"; import { - bpdIbanInsertionContinue, + bpdIbanInsertionCancel, bpdIbanInsertionResetScreen } from "../../../store/actions/iban"; import IbanKoBody from "./IbanKoBody"; @@ -21,34 +27,71 @@ export type Props = ReturnType & const loadLocales = () => ({ headerTitle: I18n.t("bonus.bpd.title"), - edit: I18n.t("bonus.bpd.iban.edit"), - continueStr: I18n.t("global.buttons.continue"), + cancel: I18n.t("global.buttons.cancel"), + verify: I18n.t("bonus.bpd.iban.verify"), title: I18n.t("bonus.bpd.iban.koNotOwned.title"), text1: I18n.t("bonus.bpd.iban.koNotOwned.text1"), text2: I18n.t("bonus.bpd.iban.koNotOwned.text2") }); +const styles = StyleSheet.create({ + profile: { + flex: 1, + alignContent: "flex-end" + }, + text: { + textAlign: "center" + } +}); + +/** + * Render the profile information (name, surname, fiscal code) + * @param props + * @constructor + */ +const ProfileInformation = (props: Props) => { + // undefined profile should never happens + const profile = pot.getOrElse(props.profile, undefined); + + return ( + +

+ {profile?.name} {profile?.family_name}, +

+ + {I18n.t("profile.fiscalCode.fiscalCode")}{" "} + {profile?.fiscal_code} + +
+ ); +}; + /** * This screen warns the user that the provided iban does not belong to him. * This is just a warning, the user can continue and iban has been registered on the bpd remote system. * @constructor */ const IbanKoNotOwned: React.FunctionComponent = props => { - const { headerTitle, continueStr, edit, title, text1, text2 } = loadLocales(); + const { headerTitle, verify, cancel, title, text1, text2 } = loadLocales(); return ( } + body={ + + + + + } /> @@ -57,9 +100,11 @@ const IbanKoNotOwned: React.FunctionComponent = props => { const mapDispatchToProps = (dispatch: Dispatch) => ({ modifyIban: () => dispatch(bpdIbanInsertionResetScreen()), - completeInsertion: () => dispatch(bpdIbanInsertionContinue()) + cancel: () => dispatch(bpdIbanInsertionCancel()) }); -const mapStateToProps = (_: GlobalState) => ({}); +const mapStateToProps = (state: GlobalState) => ({ + profile: profileSelector(state) +}); export default connect(mapStateToProps, mapDispatchToProps)(IbanKoNotOwned); diff --git a/ts/features/bonus/bpd/screens/iban/ko/IbanKoBody.tsx b/ts/features/bonus/bpd/screens/iban/ko/IbanKoBody.tsx index f9dc524a73c..5fca19e3572 100644 --- a/ts/features/bonus/bpd/screens/iban/ko/IbanKoBody.tsx +++ b/ts/features/bonus/bpd/screens/iban/ko/IbanKoBody.tsx @@ -1,4 +1,3 @@ -import { fromNullable } from "fp-ts/lib/Option"; import { View } from "native-base"; import * as React from "react"; import { StyleSheet } from "react-native"; @@ -12,6 +11,7 @@ import { bpdUpsertIbanSelector } from "../../../store/reducers/details/activatio type OwnProps = { text1: string; text2: string; + isFlex?: boolean; }; export type Props = OwnProps & ReturnType; @@ -28,17 +28,18 @@ const styles = StyleSheet.create({ * @constructor */ const IbanKoBody: React.FunctionComponent = props => { - const iban: string = fromNullable(props.candidateIban.value).fold( - "", - iban => iban as string - ); + const iban: string = props.candidateIban.value ?? ""; + const style = props.isFlex ?? true ? IOStyles.flex : {}; + return ( - +

{props.text1}

- {iban} + + {iban} +

{props.text2} diff --git a/ts/features/bonus/bpd/store/reducers/details/activation/index.ts b/ts/features/bonus/bpd/store/reducers/details/activation/index.ts index 3c1b8f7f39d..07943b37515 100644 --- a/ts/features/bonus/bpd/store/reducers/details/activation/index.ts +++ b/ts/features/bonus/bpd/store/reducers/details/activation/index.ts @@ -1,9 +1,11 @@ +import { fromNullable } from "fp-ts/lib/Option"; import { combineReducers } from "redux"; import { createSelector } from "reselect"; import { getType } from "typesafe-actions"; import { Action } from "../../../../../../../store/actions/types"; import { GlobalState } from "../../../../../../../store/reducers/types"; import { + getValue, remoteError, remoteLoading, remoteReady, @@ -17,6 +19,7 @@ import { bpdUnsubscribeCompleted } from "../../../actions/onboarding"; import paymentInstrumentReducer, { + bpdUpsertIbanSelector, PayoffInstrumentType } from "./payoffInstrument"; @@ -117,4 +120,18 @@ export const bpdUnsubscriptionSelector = createSelector( unsubscription => unsubscription ); +/** + * Return the prefill text based on the iban upsert or iban inserted by user + * if the user tried to add a new iban (upsertIban.value !== undefined) return that iban + * else try to return the actual iban getValue(iban) + * + */ +export const bpdIbanPrefillSelector = createSelector( + [bpdIbanSelector, bpdUpsertIbanSelector], + (iban, upsertIban): string => + fromNullable(upsertIban.value as string).getOrElse( + fromNullable(getValue(iban)).getOrElse("") + ) +); + export default bpdActivationReducer; diff --git a/ts/features/bonus/bpd/store/reducers/details/activation/payoffInstrument.ts b/ts/features/bonus/bpd/store/reducers/details/activation/payoffInstrument.ts index e342b62231b..9c7655cfd09 100644 --- a/ts/features/bonus/bpd/store/reducers/details/activation/payoffInstrument.ts +++ b/ts/features/bonus/bpd/store/reducers/details/activation/payoffInstrument.ts @@ -15,11 +15,12 @@ import { IbanStatus } from "../../../../saga/networking/patchCitizenIban"; import { bpdLoadActivationStatus } from "../../../actions/details"; import { bpdIbanInsertionResetScreen, + bpdIbanInsertionStart, bpdUpsertIban } from "../../../actions/iban"; import { bpdDeleteUserFromProgram } from "../../../actions/onboarding"; -type UpsertIBAN = { +export type UpsertIBAN = { // the results of the upsert operation outcome: RemoteValue; // the value the user is trying to enter @@ -98,6 +99,8 @@ const paymentInstrumentUpsertReducer = ( ...state, outcome: remoteUndefined }; + case getType(bpdIbanInsertionStart): + return INITIAL_UPSERT; } return state; };