Skip to content

Commit

Permalink
chore(IT Wallet): [SIW-951] Add user payment methods in new wallet se…
Browse files Browse the repository at this point in the history
…ction (#5639)

> [!WARNING]
> This PR depends on #5626 and
pagopa/io-dev-api-server#358


## Short description
This PR adds the user's payment methods in the new wallet section

## List of changes proposed in this pull request
- Added store and saga for the payments' `wallet` feature
- Added card mapping for payment methods
- Fixed a glitch in the ID Pay cards in wallet

## How to test
With the `io-dev-api-server`, make sure to checkout this branch:
pagopa/io-dev-api-server#358
From the **Profile** section, enable the **New wallet section** FF.
You should be able to see payment cards in the wallet.

## Preview
<img
src="https://github.com/pagopa/io-app/assets/6160324/361f1808-48f9-425d-84d3-ef0ac7b6d62a"
width="200" />

---------

Co-authored-by: Jacopo Pompilii <[email protected]>
Co-authored-by: Martino Cesari Tomba <[email protected]>
  • Loading branch information
3 people authored Apr 4, 2024
1 parent b816497 commit 86087cc
Show file tree
Hide file tree
Showing 32 changed files with 2,240 additions and 1,931 deletions.
4 changes: 2 additions & 2 deletions img/features/cgn/cgn_card.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions locales/en/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -836,8 +836,8 @@ email:
title: We have sent you an email
subtitle: To confirm your address, follow the instructions we have sent to
link: Isn't that right?
buttonlabelsent: Email sent!
countdowntext: Request new email in
buttonlabelsent: Email sent!
countdowntext: Request new email in
buttonlabelsentagain: Send email again
toast: Done! Check your mailbox.
newvalidemail:
Expand Down Expand Up @@ -2935,7 +2935,7 @@ features:
bonus: Iniziative welfare
cgn: Carta Giovani Nazionale
itw: IT Wallet
payment: Metodo di pagamento
payment: Payment methods
webView:
error:
missingParams: Not all information necessary to access this page are available
Expand Down
10 changes: 5 additions & 5 deletions locales/it/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -804,16 +804,16 @@ email:
label: Indirizzo email personale
alert:
title: "{{email}} è già in uso, inseriscine un’altra."
description1: Email già in uso
description1: Email già in uso
description2: Inserisci un indirizzo diverso da quello attuale
description3: Stai già usando questa email
invalidemail: Inserisci un indirizzo email valido
invalidemail: Inserisci un indirizzo email valido
modaltitle: Questa email è già in uso
modaldescription: Può succedere se condividi lo stesso indirizzo con un familiare
modalbutton: Usa un’altra email
edit:
title: Modifica la tua email
subtitle: Ora stai usando
subtitle: Ora stai usando
validated: L'email che avevi inserito e validato in precedenza è
label: Nuovo indirizzo email personale
cta: Modifica email
Expand All @@ -836,7 +836,7 @@ email:
title: Ti abbiamo inviato un’email
subtitle: Per confermare il tuo indirizzo, segui le istruzioni che abbiamo inviato a
link: Non è corretto?
countdowntext: Richiedi una nuova email tra
countdowntext: Richiedi una nuova email tra
buttonlabelsent: Email inviata!
buttonlabelsentagain: Invia di nuovo l’email
toast: Fatto! Controlla la tua casella di posta.
Expand Down Expand Up @@ -2935,7 +2935,7 @@ features:
bonus: Iniziative welfare
cgn: Carta Giovani Nazionale
itw: IT Wallet
payment: Metodo di pagamento
payment: Metodi di pagamento
webView:
error:
missingParams: Non sono presenti le informazioni necessarie per accedere a questa pagina
Expand Down
11 changes: 10 additions & 1 deletion ts/features/idpay/wallet/components/IdPayCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,16 @@ export const IdPayCard = (props: IdPayCardProps) => (
<View style={styles.content}>
<View>
<View style={styles.header}>
<H6 color="blueItalia-850">{props.name}</H6>
<H6
color="blueItalia-850"
ellipsizeMode="tail"
numberOfLines={1}
style={{
width: "80%"
}}
>
{props.name}
</H6>
<Avatar size="small" logoUri={props.avatarSource} />
</View>
<VSpacer size={16} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,20 @@ exports[`IdPayCard should match the snapshot 1`] = `
color="blueItalia-850"
defaultColor="black"
defaultWeight="SemiBold"
ellipsizeMode="tail"
font="TitilliumWeb"
fontStyle={
Object {
"fontSize": 18,
"lineHeight": 25,
}
}
numberOfLines={1}
style={
Array [
Object {
"width": "80%",
},
Object {
"fontSize": 18,
"lineHeight": 25,
Expand Down
2 changes: 2 additions & 0 deletions ts/features/newWallet/screens/WalletHomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { WalletEmptyScreenContent } from "../components/WalletEmptyScreenContent
import { WalletPaymentsRedirectBanner } from "../components/WalletPaymentsRedirectBanner";
import { selectWalletCards } from "../store/selectors";
import { cgnDetails } from "../../bonus/cgn/store/actions/details";
import { getPaymentsWalletUserMethods } from "../../payments/wallet/store/actions";

const WalletHomeScreen = () => {
const dispatch = useIODispatch();
Expand All @@ -22,6 +23,7 @@ const WalletHomeScreen = () => {

React.useEffect(() => {
// TODO SIW-960 Move cards request to app startup
dispatch(getPaymentsWalletUserMethods.request());
dispatch(idPayWalletGet.request());
dispatch(cgnDetails.request());
}, [dispatch]);
Expand Down
19 changes: 7 additions & 12 deletions ts/features/newWallet/store/selectors/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
import { pipe } from "fp-ts/lib/function";
import _ from "lodash";
import { createSelector } from "reselect";
import { GlobalState } from "../../../../store/reducers/types";
import { WalletCard, WalletCardCategory } from "../../types";

const selectWalletFeature = (state: GlobalState) => state.features.wallet;

export const isWalletPaymentsRedirectBannerVisibleSelector = (
state: GlobalState
) =>
pipe(
state,
selectWalletFeature,
wallet => wallet.preferences.shouldShowPaymentsRedirectBanner
);
export const isWalletPaymentsRedirectBannerVisibleSelector = createSelector(
selectWalletFeature,
wallet => wallet.preferences.shouldShowPaymentsRedirectBanner
);

export const selectWalletCards = (state: GlobalState) =>
pipe(state, selectWalletFeature, wallet => Object.values(wallet.cards));
export const selectWalletCards = createSelector(selectWalletFeature, wallet =>
Object.values(wallet.cards)
);

export const getWalletCardsByCategorySelector = createSelector(
selectWalletCards,
Expand Down
2 changes: 1 addition & 1 deletion ts/features/newWallet/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
import {
PaymentWalletCard,
PaymentWalletCardProps
} from "../../payments/common/components/PaymentWalletCard";
} from "../../payments/wallet/components/PaymentWalletCard";
import { WalletCardBaseComponent } from "../components/WalletCardBaseComponent";
import {
CgnWalletCard,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
getPaymentLogo
} from "../../common/utils";
import { WalletPaymentStepEnum } from "../types";
import { UIWalletInfoDetails } from "../../details/types/UIWalletInfoDetails";
import { UIWalletInfoDetails } from "../../common/types/UIWalletInfoDetails";
import { walletPaymentSetCurrentStep } from "../store/actions/orchestration";
import { walletPaymentPspListSelector } from "../store/selectors";
import { WalletPaymentTotalAmount } from "./WalletPaymentTotalAmount";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { useIONavigation } from "../../../../navigation/params/AppParamsList";
import { useIODispatch, useIOSelector } from "../../../../store/hooks";
import { ComponentProps } from "../../../../types/react";
import { findFirstCaseInsensitive } from "../../../../utils/object";
import { UIWalletInfoDetails } from "../../details/types/UIWalletInfoDetails";
import { UIWalletInfoDetails } from "../../common/types/UIWalletInfoDetails";
import { WalletPaymentMissingMethodsError } from "../components/WalletPaymentMissingMethodsError";
import { useOnTransactionActivationEffect } from "../hooks/useOnTransactionActivationEffect";
import { PaymentsCheckoutRoutes } from "../navigation/routes";
Expand Down
8 changes: 4 additions & 4 deletions ts/features/payments/checkout/store/__tests__/store.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,19 @@ const INITIAL_STATE: PaymentsCheckoutState = {
describe("Test Payment reducer", () => {
it("should have initial state at startup", () => {
const globalState = appReducer(undefined, applicationChangeState("active"));
expect(globalState.features.payments.payment).toStrictEqual(INITIAL_STATE);
expect(globalState.features.payments.checkout).toStrictEqual(INITIAL_STATE);
});

it("should correctly update payment step, also when trying to overflow the steps, it should set the steps to WALLET_PAYMENT_STEP_MAX, and in case zero is passed it should set the step to 1", () => {
const globalState = appReducer(undefined, applicationChangeState("active"));
expect(globalState.features.payments.payment).toStrictEqual(INITIAL_STATE);
expect(globalState.features.payments.checkout).toStrictEqual(INITIAL_STATE);

const store = createStore(appReducer, globalState as any);

store.dispatch(walletPaymentSetCurrentStep(2));
expect(store.getState().features.payments.payment.currentStep).toBe(2);
expect(store.getState().features.payments.checkout.currentStep).toBe(2);

store.dispatch(walletPaymentSetCurrentStep(0));
expect(store.getState().features.payments.payment.currentStep).toBe(1);
expect(store.getState().features.payments.checkout.currentStep).toBe(1);
});
});
28 changes: 14 additions & 14 deletions ts/features/payments/checkout/store/selectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,31 @@ import { pipe } from "fp-ts/lib/function";
import { createSelector } from "reselect";
import { GlobalState } from "../../../../../store/reducers/types";

const selectWalletPayment = (state: GlobalState) =>
state.features.payments.payment;
const selectPaymentsCheckoutState = (state: GlobalState) =>
state.features.payments.checkout;

export const selectWalletPaymentCurrentStep = (state: GlobalState) =>
selectWalletPayment(state).currentStep;
selectPaymentsCheckoutState(state).currentStep;

export const selectWalletPaymentSessionTokenPot = (state: GlobalState) =>
selectWalletPayment(state).sessionToken;
selectPaymentsCheckoutState(state).sessionToken;

export const selectWalletPaymentSessionToken = (state: GlobalState) =>
pot.toUndefined(selectWalletPaymentSessionTokenPot(state));

export const walletPaymentRptIdSelector = (state: GlobalState) =>
selectWalletPayment(state).rptId;
selectPaymentsCheckoutState(state).rptId;

export const walletPaymentDetailsSelector = (state: GlobalState) =>
selectWalletPayment(state).paymentDetails;
selectPaymentsCheckoutState(state).paymentDetails;

export const walletPaymentAmountSelector = createSelector(
walletPaymentDetailsSelector,
state => pot.map(state, payment => payment.amount)
);

export const walletPaymentAllMethodsSelector = createSelector(
selectWalletPayment,
selectPaymentsCheckoutState,
state => pot.map(state.allPaymentMethods, _ => _.paymentMethods ?? [])
);

Expand All @@ -43,7 +43,7 @@ export const walletPaymentGenericMethodByIdSelector = createSelector(
);

export const walletPaymentUserWalletsSelector = createSelector(
selectWalletPayment,
selectPaymentsCheckoutState,
state => pot.map(state.userWallets, _ => _.wallets ?? [])
);

Expand All @@ -58,19 +58,19 @@ export const walletPaymentSavedMethodByIdSelector = createSelector(
);

export const walletPaymentPickedPaymentMethodSelector = (state: GlobalState) =>
selectWalletPayment(state).chosenPaymentMethod;
selectPaymentsCheckoutState(state).chosenPaymentMethod;

export const walletPaymentPspListSelector = (state: GlobalState) =>
selectWalletPayment(state).pspList;
selectPaymentsCheckoutState(state).pspList;

export const walletPaymentPickedPspSelector = (state: GlobalState) =>
selectWalletPayment(state).chosenPsp;
selectPaymentsCheckoutState(state).chosenPsp;

export const walletPaymentTransactionSelector = (state: GlobalState) =>
selectWalletPayment(state).transaction;
selectPaymentsCheckoutState(state).transaction;

export const walletPaymentAuthorizationUrlSelector = (state: GlobalState) =>
selectWalletPayment(state).authorizationUrl;
selectPaymentsCheckoutState(state).authorizationUrl;

export const walletPaymentStartRouteSelector = (state: GlobalState) =>
selectWalletPayment(state).startRoute;
selectPaymentsCheckoutState(state).startRoute;
4 changes: 1 addition & 3 deletions ts/features/payments/common/components/PaymentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,15 +191,13 @@ const SkeletonPlaceholder = (props: Pick<BoxProps, "width" | "height">) => (
/>
);

const borderColor = "#0000001F";

const styleSheet = StyleSheet.create({
card: {
aspectRatio: 16 / 10,
backgroundColor: IOColors["grey-100"],
borderRadius: 16,
borderWidth: 1,
borderColor
borderColor: IOColors["grey-200"]
},
wrapper: {
padding: 16,
Expand Down
Loading

0 comments on commit 86087cc

Please sign in to comment.