diff --git a/packages/server/src/api/controllers/PaymentServices/PaymentServicesController.ts b/packages/server/src/api/controllers/PaymentServices/PaymentServicesController.ts index 10abdfc63..dc3126db8 100644 --- a/packages/server/src/api/controllers/PaymentServices/PaymentServicesController.ts +++ b/packages/server/src/api/controllers/PaymentServices/PaymentServicesController.ts @@ -26,15 +26,10 @@ export class PaymentServicesController extends BaseController { '/:paymentMethodId', [ param('paymentMethodId').exists(), + body('name').optional().isString(), - body('options.bankAccountId').optional().isNumeric(), - body('options.clearingAccountId').optional().isNumeric(), - body('options.showVisa').optional().isBoolean(), - body('options.showMasterCard').optional().isBoolean(), - body('options.showDiscover').optional().isBoolean(), - body('options.showAmer').optional().isBoolean(), - body('options.showJcb').optional().isBoolean(), - body('options.showDiners').optional().isBoolean(), + body('options.bank_account_id').optional().isNumeric(), + body('options.clearing_account_id').optional().isNumeric(), ], this.validationResult, asyncMiddleware(this.updatePaymentMethod.bind(this)) diff --git a/packages/webapp/src/containers/Preferences/PaymentMethods/PreferencesPaymentMethodsBoot.tsx b/packages/webapp/src/containers/Preferences/PaymentMethods/PreferencesPaymentMethodsBoot.tsx index 378c602e1..ca6364a31 100644 --- a/packages/webapp/src/containers/Preferences/PaymentMethods/PreferencesPaymentMethodsBoot.tsx +++ b/packages/webapp/src/containers/Preferences/PaymentMethods/PreferencesPaymentMethodsBoot.tsx @@ -1,4 +1,5 @@ import { createContext, ReactNode, useContext } from 'react'; +import { Spinner } from '@blueprintjs/core'; import { GetPaymentServicesStateResponse, useGetPaymentServicesState, @@ -23,6 +24,9 @@ const PaymentMethodsBoot = ({ children }: PaymentMethodsProviderProps) => { const value = { isPaymentMethodsStateLoading, paymentMethodsState }; + if (isPaymentMethodsStateLoading) { + return ; + } return ( {children} diff --git a/packages/webapp/src/containers/Preferences/PaymentMethods/PreferencesPaymentMethodsPage.tsx b/packages/webapp/src/containers/Preferences/PaymentMethods/PreferencesPaymentMethodsPage.tsx index 07b86277f..8ca2c3302 100644 --- a/packages/webapp/src/containers/Preferences/PaymentMethods/PreferencesPaymentMethodsPage.tsx +++ b/packages/webapp/src/containers/Preferences/PaymentMethods/PreferencesPaymentMethodsPage.tsx @@ -1,4 +1,5 @@ // @ts-nocheck +import React, { useEffect } from 'react'; import styled from 'styled-components'; import { Button, @@ -20,6 +21,7 @@ import { StripePreSetupDialog } from './dialogs/StripePreSetupDialog/StripePreSe import { DialogsName } from '@/constants/dialogs'; import { useAlertActions, + useChangePreferencesPageTitle, useDialogActions, useDrawerActions, } from '@/hooks/state'; @@ -29,6 +31,12 @@ import { DRAWERS } from '@/constants/drawers'; import { MoreIcon } from '@/icons/More'; export default function PreferencesPaymentMethodsPage() { + const changePageTitle = useChangePreferencesPageTitle(); + + useEffect(() => { + changePageTitle('Payment Methods'); + }, [changePageTitle]); + return ( diff --git a/packages/webapp/src/containers/Preferences/PaymentMethods/drawers/StripeIntegrationEditForm.tsx b/packages/webapp/src/containers/Preferences/PaymentMethods/drawers/StripeIntegrationEditForm.tsx index 4aecfa892..18297093b 100644 --- a/packages/webapp/src/containers/Preferences/PaymentMethods/drawers/StripeIntegrationEditForm.tsx +++ b/packages/webapp/src/containers/Preferences/PaymentMethods/drawers/StripeIntegrationEditForm.tsx @@ -11,20 +11,17 @@ import { useStripeIntegrationEditBoot } from './StripeIntegrationEditBoot'; import { transformToForm } from '@/utils'; interface StripeIntegrationFormValues { - paymentAccountId: string; + bankAccountId: string; clearingAccountId: string; } - const initialValues = { - paymentAccountId: '', + bankAccountId: '', clearingAccountId: '', }; - const validationSchema = Yup.object().shape({ - paymentAccountId: Yup.string().required('Payment Account is required'), + bankAccountId: Yup.string().required('Bank Account is required'), clearingAccountId: Yup.string().required('Clearing Account is required'), }); - interface StripeIntegrationEditFormProps { children: React.ReactNode; } @@ -44,13 +41,14 @@ export function StripeIntegrationEditForm({ ...initialValues, ...transformToForm(paymentMethod?.options, initialValues), }; - const onSubmit = ( values: StripeIntegrationFormValues, { setSubmitting }: FormikHelpers, ) => { + const _values = { options: { ...values } }; + setSubmitting(true); - updatePaymentMethod({ paymentMethodId, values }) + updatePaymentMethod({ paymentMethodId, values: _values }) .then(() => { AppToaster.show({ message: 'The Stripe settings have been updated.', diff --git a/packages/webapp/src/containers/Preferences/PaymentMethods/drawers/StripeIntegrationEditFormContent.tsx b/packages/webapp/src/containers/Preferences/PaymentMethods/drawers/StripeIntegrationEditFormContent.tsx index 9243062ca..16f7e141b 100644 --- a/packages/webapp/src/containers/Preferences/PaymentMethods/drawers/StripeIntegrationEditFormContent.tsx +++ b/packages/webapp/src/containers/Preferences/PaymentMethods/drawers/StripeIntegrationEditFormContent.tsx @@ -11,12 +11,13 @@ export function StripeIntegrationEditFormContent() { return ( ( - ['PaymentServicesState'], + [PaymentServicesStateQueryKey], () => apiRequest .get('/payment-services/state') @@ -99,19 +101,27 @@ export const useUpdatePaymentMethod = (): UseMutationResult< unknown > => { const apiRequest = useApiRequest(); + const queryClient = useQueryClient(); return useMutation< UpdatePaymentMethodResponse, Error, UpdatePaymentMethodValues, unknown - >((data: UpdatePaymentMethodValues) => - apiRequest - .post( - `/payment-services/${data.paymentMethodId}`, - transfromToSnakeCase(data.values), - ) - .then((response) => response.data), + >( + (data: UpdatePaymentMethodValues) => + apiRequest + .post( + `/payment-services/${data.paymentMethodId}`, + transfromToSnakeCase(data.values), + ) + .then((response) => response.data), + { + onSuccess: () => { + queryClient.invalidateQueries(PaymentServicesStateQueryKey); + queryClient.invalidateQueries(PaymentServicesQueryKey); + }, + }, ); }; @@ -127,11 +137,13 @@ export const useGetPaymentMethod = ( const apiRequest = useApiRequest(); return useQuery( - ['paymentMethod', paymentMethodId], - () => apiRequest.get(`/payment-services/${paymentMethodId}`), - { - select: (data) => - transformToCamelCase(data.data) as GetPaymentMethodResponse, - }, + [PaymentServicesQueryKey, paymentMethodId], + () => + apiRequest + .get(`/payment-services/${paymentMethodId}`) + .then( + (res) => + transformToCamelCase(res.data?.data) as GetPaymentMethodResponse, + ), ); }; diff --git a/packages/webapp/src/hooks/state/dashboard.tsx b/packages/webapp/src/hooks/state/dashboard.tsx index 8b5f118de..c2b246999 100644 --- a/packages/webapp/src/hooks/state/dashboard.tsx +++ b/packages/webapp/src/hooks/state/dashboard.tsx @@ -14,6 +14,7 @@ import { closeDrawer, openAlert, closeAlert, + changePreferencesPageTitle, } from '@/store/dashboard/dashboard.actions'; export const useDispatchAction = (action) => { @@ -95,3 +96,7 @@ export const useAlertActions = () => { closeAlert: useDispatchAction(closeAlert), }; }; + +export const useChangePreferencesPageTitle = () => { + return useDispatchAction(changePreferencesPageTitle); +}; diff --git a/packages/webapp/src/store/dashboard/dashboard.actions.tsx b/packages/webapp/src/store/dashboard/dashboard.actions.tsx index b956955dd..630b6ff7e 100644 --- a/packages/webapp/src/store/dashboard/dashboard.actions.tsx +++ b/packages/webapp/src/store/dashboard/dashboard.actions.tsx @@ -129,19 +129,26 @@ export function closeSidebarSubmenu() { export function addAutofill(autofillRef: number, payload: any) { return { type: t.ADD_AUTOFILL_REF, - payload: { ref: autofillRef, payload } - } + payload: { ref: autofillRef, payload }, + }; } export function removeAutofill(autofillRef: number) { return { type: t.REMOVE_AUTOFILL_REF, - payload: { ref: autofillRef} - } + payload: { ref: autofillRef }, + }; } export function resetAutofill() { return { type: t.RESET_AUTOFILL_REF, - } -} \ No newline at end of file + }; +} + +export function changePreferencesPageTitle(pageTitle: string) { + return { + type: 'CHANGE_PREFERENCES_PAGE_TITLE', + pageTitle, + }; +}