Use source loader for email sprite icons
[ProtonMail-WebClient.git] / packages / wallet / store / slices / paymentMethodByProvider.ts
blobcd1a8fbd0b2ed56afbde0f11846e199022952a92
1 import { createSlice } from '@reduxjs/toolkit';
3 import type { ModelState } from '@proton/account';
4 import { getInitialModelState } from '@proton/account';
5 import type { WasmFiatCurrencySymbol, WasmGatewayProvider, WasmPaymentMethod } from '@proton/andromeda';
6 import { createAsyncModelThunk, handleAsyncModel } from '@proton/redux-utilities';
7 import { MINUTE } from '@proton/shared/lib/constants';
9 import type { WalletThunkArguments } from '../thunk';
11 const name = 'payment_method_by_provider' as const;
13 export type PaymentMethodsByProvider = Partial<Record<WasmGatewayProvider, WasmPaymentMethod[]>>;
14 type PaymentMethodsByProviderByFiat = Partial<Record<WasmFiatCurrencySymbol, PaymentMethodsByProvider>>;
16 export interface PaymentMethodsByProviderState {
17     [name]: ModelState<PaymentMethodsByProviderByFiat>;
20 type SliceState = PaymentMethodsByProviderState[typeof name];
21 type Model = NonNullable<SliceState['value']>;
23 export const selectPaymentMethodsByProvider = (state: PaymentMethodsByProviderState) => state[name];
25 const modelThunk = createAsyncModelThunk<
26     Model,
27     PaymentMethodsByProviderState,
28     WalletThunkArguments,
29     WasmFiatCurrencySymbol
30 >(`${name}/fetch`, {
31     miss: async ({ extraArgument, options, getState }) => {
32         const stateValue = getState()[name].value;
33         if (!options?.thunkArg) {
34             return stateValue ?? {};
35         }
37         const fiat = options?.thunkArg;
39         return extraArgument.walletApi
40             .clients()
41             .payment_gateway.getPaymentMethods(fiat)
42             .then((paymentMethods) => {
43                 const paymentMethodsByProvider = paymentMethods.data.reduce((acc, current) => {
44                     const provider = current[0];
45                     const countries = current[1];
47                     return { ...acc, [provider]: countries.data };
48                 }, {} as PaymentMethodsByProvider);
50                 return {
51                     ...stateValue,
52                     [fiat]: paymentMethodsByProvider,
53                 };
54             });
55     },
56     expiry: 10 * MINUTE,
57     previous: ({ getState, options }) => {
58         const state = getState()[name];
59         if (!options?.thunkArg || !state.value) {
60             return undefined;
61         }
63         const fiat = options?.thunkArg;
65         if (state.value[fiat]) {
66             return state;
67         }
69         return undefined;
70     },
71 });
73 const initialState = getInitialModelState<Model>();
74 const slice = createSlice({
75     name,
76     initialState,
77     reducers: {},
78     extraReducers: (builder) => {
79         handleAsyncModel(builder, modelThunk);
80     },
81 });
83 export const paymentMethodsByProviderReducer = { [name]: slice.reducer };
84 export const paymentMethodsByProviderThunk = modelThunk.thunk;