Skip to content

Commit

Permalink
refactor: refactor usePreviousPaymentMethods (#4701)
Browse files Browse the repository at this point in the history
  • Loading branch information
rosvik committed Sep 3, 2024
1 parent 9f1f8d5 commit 9fee0ee
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
UserProfileWithCountAndOffer,
} from '../Root_PurchaseOverviewScreen/use-offer-state';
import {SelectPaymentMethodSheet} from './components/SelectPaymentMethodSheet';
import {usePreviousPaymentMethod} from '../saved-payment-utils';
import {usePreviousPaymentMethods} from '../saved-payment-utils';
import {PaymentMethod, SavedPaymentOption} from '../types';
import {RootStackScreenProps} from '@atb/stacks-hierarchy/navigation-types';
import {GenericSectionItem, Section} from '@atb/components/sections';
Expand Down Expand Up @@ -93,7 +93,8 @@ export const Root_PurchaseConfirmationScreen: React.FC<Props> = ({
const [previousMethod, setPreviousMethod] = useState<
PaymentMethod | undefined
>(undefined);
const previousPaymentMethod = usePreviousPaymentMethod();
const {previousPaymentMethod, recurringPayments} =
usePreviousPaymentMethods();
const isShowValidTimeInfoEnabled = useShowValidTimeInfoEnabled();
const analytics = useAnalytics();

Expand Down Expand Up @@ -223,6 +224,7 @@ export const Root_PurchaseConfirmationScreen: React.FC<Props> = ({
openBottomSheet(() => {
return (
<SelectPaymentMethodSheet
recurringPayments={recurringPayments}
onSelect={(option: PaymentMethod) => {
goToPayment(option);
closeBottomSheet();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import React, {useEffect, useState} from 'react';
import {ActivityIndicator, ScrollView, View} from 'react-native';
import {StyleSheet, useTheme} from '@atb/theme';
import {ScrollView, View} from 'react-native';
import {StyleSheet} from '@atb/theme';
import {Button} from '@atb/components/button';
import {PurchaseConfirmationTexts, useTranslation} from '@atb/translations';
import {ArrowRight} from '@atb/assets/svg/mono-icons/navigation';
import {ThemeText} from '@atb/components/text';
import SelectPaymentMethodTexts from '@atb/translations/screens/subscreens/SelectPaymentMethodTexts';
import {listRecurringPayments, PaymentType} from '@atb/ticketing';
import {PaymentType, RecurringPayment} from '@atb/ticketing';
import {PaymentMethod, SavedPaymentOption} from '../../types';
import {useAuthState} from '@atb/auth';
import {BottomSheetContainer} from '@atb/components/bottom-sheet';
Expand All @@ -20,6 +20,7 @@ import {PressableOpacity} from '@atb/components/pressable-opacity';
type Props = {
onSelect: (value: PaymentMethod) => void;
previousPaymentMethod?: SavedPaymentOption;
recurringPayments?: RecurringPayment[];
};

function getSelectedPaymentMethod(
Expand Down Expand Up @@ -65,19 +66,13 @@ function isRecurring(option: PaymentMethod): option is {
);
}

const remotePaymentOptions: SavedPaymentOption[] = [];

export const SelectPaymentMethodSheet: React.FC<Props> = ({
onSelect,
previousPaymentMethod,
recurringPayments,
}) => {
const {t} = useTranslation();

const [loadingRecurringOptions, setLoadingRecurringOptions] =
useState<boolean>(true);

const {authenticationType} = useAuthState();
const {theme} = useTheme();
const {paymentTypes} = useFirestoreConfiguration();

const defaultPaymentOptions: SavedPaymentOption[] = paymentTypes.map(
Expand All @@ -92,30 +87,28 @@ export const SelectPaymentMethodSheet: React.FC<Props> = ({
const [selectedOption, setSelectedOption] = useState<
PaymentMethod | undefined
>(getSelectedPaymentMethod(paymentTypes, previousPaymentMethod));
const [remoteOptions, setRemoteOptions] = useState(remotePaymentOptions);
const styles = useStyles();

async function getRecurringPaymentOptions(): Promise<
Array<SavedPaymentOption>
> {
function getRecurringPaymentOptions(): SavedPaymentOption[] {
if (authenticationType !== 'phone') return [];
const recurringOptions: Array<SavedPaymentOption> = (
await listRecurringPayments()
).map((option) => {
return {
savedType: 'recurring',
paymentType: option.payment_type,
recurringCard: {
id: option.id,
masked_pan: option.masked_pan,
expires_at: option.expires_at,
payment_type: option.payment_type,
},
};
});
return [...recurringOptions.reverse()];
const recurringOptions: Array<SavedPaymentOption> | undefined =
recurringPayments?.map((option) => {
return {
savedType: 'recurring',
paymentType: option.payment_type,
recurringCard: {
id: option.id,
masked_pan: option.masked_pan,
expires_at: option.expires_at,
payment_type: option.payment_type,
},
};
});
return recurringOptions ? [...recurringOptions.reverse()] : [];
}

const remoteOptions = getRecurringPaymentOptions();

const isSelectedOption = (item: SavedPaymentOption) => {
// False if types doesn't match
if (!(selectedOption?.paymentType === item.paymentType)) return false;
Expand All @@ -132,16 +125,6 @@ export const SelectPaymentMethodSheet: React.FC<Props> = ({
return !itemIsRecurring && !selectedIsRecurring;
};

useEffect(() => {
async function run() {
const remoteOptions = await getRecurringPaymentOptions();
setRemoteOptions(remoteOptions);
setLoadingRecurringOptions(false);
}
run();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [previousPaymentMethod]);

return (
<BottomSheetContainer
title={t(SelectPaymentMethodTexts.header.text)}
Expand All @@ -164,17 +147,6 @@ export const SelectPaymentMethodSheet: React.FC<Props> = ({
);
})}

{loadingRecurringOptions && (
<>
<ActivityIndicator
color={theme.text.colors.primary}
style={styles.spinner}
animating={true}
size="large"
/>
</>
)}

{remoteOptions.length > 0 && (
<View style={styles.listHeading}>
<ThemeText>
Expand Down
53 changes: 26 additions & 27 deletions src/stacks-hierarchy/saved-payment-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,41 @@ import {storage} from '@atb/storage';
import Bugsnag from '@bugsnag/react-native';
import {useAuthState} from '@atb/auth';
import {useListRecurringPaymentsQuery} from '@atb/ticketing/use-list-recurring-payments-query';
import {RecurringPayment} from '@atb/ticketing';

export function usePreviousPaymentMethod(): SavedPaymentOption | undefined {
const [paymentMethod, setPaymentMethod] = useState<
SavedPaymentOption | undefined
>(undefined);
export function usePreviousPaymentMethods(): {
recurringPayments: RecurringPayment[] | undefined;
previousPaymentMethod: SavedPaymentOption | undefined;
} {
const {userId} = useAuthState();

const {data: recurringPayments} = useListRecurringPaymentsQuery();
const [previousPaymentMethod, setPreviousPaymentMethod] =
useState<SavedPaymentOption>();

useEffect(() => {
async function run(uid: string) {
const savedMethod = await getPreviousPaymentMethodByUser(uid);
if (
recurringPayments &&
savedMethod &&
savedMethod.savedType === 'recurring'
) {
const method = recurringPayments.find(
(recurringPayment) =>
recurringPayment.id === savedMethod.recurringCard.id,
);
if (method) setPaymentMethod(savedMethod);
} else {
setPaymentMethod(savedMethod);
}
}

if (!userId) {
setPaymentMethod(undefined);
return;
setPreviousPaymentMethod(undefined);
} else {
run(userId);
getPreviousPaymentMethodByUser(userId).then((storedMethod) => {
// Since the stored payment could have been deleted, we need to check if
// it is still in the list of recurring payments.
if (!storedMethod) return;
const shouldUseStored =
'recurringCard' in storedMethod
? !!recurringPayments?.find(
(recurringPayment) =>
recurringPayment.id === storedMethod.recurringCard.id,
)
: true;
setPreviousPaymentMethod(shouldUseStored ? storedMethod : undefined);
});
}
}, [recurringPayments, userId]);
}, [userId, recurringPayments]);

return paymentMethod;
return {
recurringPayments,
previousPaymentMethod,
};
}

type StoredPaymentMethods = {
Expand Down

0 comments on commit 9fee0ee

Please sign in to comment.