diff --git a/src/components/PaymentMethodForm/PaymentMethodForm.tsx b/src/components/PaymentMethodForm/PaymentMethodForm.tsx index 264943a3..fc5a1919 100644 --- a/src/components/PaymentMethodForm/PaymentMethodForm.tsx +++ b/src/components/PaymentMethodForm/PaymentMethodForm.tsx @@ -1,8 +1,8 @@ -import { useEffect, useMemo } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { useForm } from 'react-hook-form'; import { TAdvertiserPaymentMethod, TFormState, TSelectedPaymentMethod } from 'types'; import { PageReturn, PaymentMethodField, PaymentMethodsFormFooter } from '@/components'; -import { api, useModalManager } from '@/hooks'; +import { api } from '@/hooks'; import { Button, Modal, useDevice } from '@deriv-com/ui'; import { PaymentMethodFormAutocomplete } from './PaymentMethodFormAutocomplete'; import { PaymentMethodFormModalRenderer } from './PaymentMethodFormModalRenderer'; @@ -35,7 +35,7 @@ const PaymentMethodForm = ({ handleSubmit, reset, } = useForm({ mode: 'all' }); - const { hideModal, isModalOpenFor, showModal } = useModalManager(); + const [isError, setIsError] = useState(false); const { actionType, selectedPaymentMethod, title = '' } = rest.formState; const { data: availablePaymentMethods } = api.paymentMethods.useGet(); const { create, error: createError, isSuccess: isCreateSuccessful } = api.advertiserPaymentMethods.useCreate(); @@ -65,7 +65,7 @@ const PaymentMethodForm = ({ }, [availablePaymentMethods]); const handleGoBack = () => { if (isDirty) { - showModal('PaymentMethodFormErrorModal', { shouldStackModals: true }); + setIsError(true); } else { onResetFormState(); onRequestClose?.(); @@ -74,96 +74,110 @@ const PaymentMethodForm = ({ if (displayModal) { return ( - - { - event.preventDefault(); // Prevents create edit ad form submission - event.stopPropagation(); - handleSubmit(data => { - const hasData = Object.keys(data).length > 0; - if (actionType === 'ADD' && hasData) { - create({ - ...data, - method: String((selectedPaymentMethod as TAdvertiserPaymentMethod)?.method), - }); - } else if (actionType === 'EDIT' && hasData) { - update(String(selectedPaymentMethod?.id), { - ...data, - }); - } - })(event); - }} + <> + - - - - - - - { + event.preventDefault(); // Prevents create edit ad form submission + event.stopPropagation(); + handleSubmit(data => { + const hasData = Object.keys(data).length > 0; + if (actionType === 'ADD' && hasData) { + create({ + ...data, + method: String((selectedPaymentMethod as TAdvertiserPaymentMethod)?.method), + }); + } else if (actionType === 'EDIT' && hasData) { + update(String(selectedPaymentMethod?.id), { + ...data, + }); + } + })(event); + }} + > + + + + + + + + + {Object.keys(selectedPaymentMethod?.fields || {})?.map(field => { + const paymentMethodField = + (selectedPaymentMethod?.fields as TAdvertiserPaymentMethod['fields'])?.[ + field + ] ?? {}; + return ( + + ); + })} + + + + {selectedPaymentMethod ? ( + - - {Object.keys(selectedPaymentMethod?.fields || {})?.map(field => { - const paymentMethodField = - (selectedPaymentMethod?.fields as TAdvertiserPaymentMethod['fields'])?.[field] ?? - {}; - return ( - - ); - })} - - - - {selectedPaymentMethod ? ( - - ) : ( - - Cancel - - )} - - - + ) : ( + + Cancel + + )} + + + + {isError && ( + + )} + > ); } @@ -229,15 +243,14 @@ const PaymentMethodForm = ({ /> )} - {isModalOpenFor('PaymentMethodFormErrorModal') && ( + {isError && ( )} diff --git a/src/components/PaymentMethodForm/PaymentMethodFormModalRenderer/PaymentMethodFormModalRenderer.tsx b/src/components/PaymentMethodForm/PaymentMethodFormModalRenderer/PaymentMethodFormModalRenderer.tsx index 6f8a35ae..aa8491dd 100644 --- a/src/components/PaymentMethodForm/PaymentMethodFormModalRenderer/PaymentMethodFormModalRenderer.tsx +++ b/src/components/PaymentMethodForm/PaymentMethodFormModalRenderer/PaymentMethodFormModalRenderer.tsx @@ -1,14 +1,15 @@ +import { useEffect } from 'react'; import { TFormState, TSocketError } from 'types'; import { PaymentMethodErrorModal, PaymentMethodModal } from '@/components/Modals'; +import { useModalManager } from '@/hooks'; type TPaymentMethodFormModalRendererProps = { actionType: TFormState['actionType']; createError: TSocketError<'p2p_advertiser_payment_methods'> | null; isCreateSuccessful: boolean; - isModalOpen: boolean; isUpdateSuccessful: boolean; - onRequestClose: () => void; onResetFormState: () => void; + setIsError: (isError: boolean) => void; updateError: TSocketError<'p2p_advertiser_payment_methods'> | null; }; @@ -16,55 +17,65 @@ const PaymentMethodFormModalRenderer = ({ actionType, createError, isCreateSuccessful, - isModalOpen, isUpdateSuccessful, - onRequestClose, onResetFormState, + setIsError, updateError, }: TPaymentMethodFormModalRendererProps) => { - if (actionType === 'ADD' && (!isCreateSuccessful || !createError) && isModalOpen) { - return ( - - ); - } + const { hideModal, isModalOpenFor, showModal } = useModalManager(); - if (actionType === 'EDIT' && (!isUpdateSuccessful || !updateError) && isModalOpen) { - return ( - - ); - } + useEffect(() => { + if ( + (actionType === 'ADD' && (!isCreateSuccessful || !createError)) || + (actionType === 'EDIT' && (!isUpdateSuccessful || !updateError)) + ) { + showModal('PaymentMethodModal'); + } - // TODO: Remember to translate these strings - if (createError || updateError) { - return ( - { - onResetFormState(); - }} - title='Something’s not right' - /> - ); - } + // TODO: Remember to translate these strings + if (createError || updateError) { + showModal('PaymentMethodErrorModal'); + } + }, [actionType, createError, isCreateSuccessful, isUpdateSuccessful, updateError]); - return null; + return ( + <> + {!!isModalOpenFor('PaymentMethodErrorModal') && ( + { + onResetFormState(); + setIsError(false); + hideModal({ shouldHideAllModals: true }); + }} + title='Something’s not right' + /> + )} + {!!isModalOpenFor('PaymentMethodModal') && ( + { + onResetFormState(); + setIsError(false); + hideModal({ shouldHideAllModals: true }); + }} + onReject={() => { + hideModal(); + setIsError(false); + }} + primaryButtonLabel={actionType === 'ADD' ? 'Go back' : "Don't cancel"} + secondaryButtonLabel='Cancel' + title={actionType === 'ADD' ? 'Cancel adding this payment method?' : 'Cancel your edits?'} + /> + )} + > + ); }; export default PaymentMethodFormModalRenderer; diff --git a/src/hooks/custom-hooks/useModalManager.ts b/src/hooks/custom-hooks/useModalManager.ts index df706463..77ce7633 100644 --- a/src/hooks/custom-hooks/useModalManager.ts +++ b/src/hooks/custom-hooks/useModalManager.ts @@ -11,6 +11,10 @@ type TShowModalOptions = { shouldStackModals?: boolean; }; +type THideModalOptions = { + shouldHideAllModals?: boolean; +}; + const MODAL_QUERY_SEPARATOR = ','; /** @@ -61,30 +65,41 @@ export default function useModalManager(config?: TUseModalManagerConfig) { syncModalParams(); }, []); + useEffect(() => { + if (!queryString?.modal) actions.reset(); + }, [queryString?.modal]); + // ...or when the user clicks the back button useEventListener('popstate', () => { syncModalParams(); }); - const hideModal = () => { + const hideModal = (options?: THideModalOptions) => { const modalHash = queryString.modal; if (modalHash) { const modalIds = modalHash.split(MODAL_QUERY_SEPARATOR); - const currentModalId = modalIds.pop(); - const previousModalId = modalIds.slice(-1)[0]; - if (previousModalId) { - actions.set(currentModalId, false); - actions.set(previousModalId, true); - } else { - actions.set(currentModalId, false); - } - if (modalIds.length === 0) { - deleteQueryString('modal'); - } else { - setQueryString({ - modal: modalIds.join(MODAL_QUERY_SEPARATOR), + if (options?.shouldHideAllModals) { + isModalOpenScopes.forEach((_, key) => { + actions.set(key, false); + deleteQueryString('modal'); }); + } else { + const currentModalId = modalIds.pop(); + const previousModalId = modalIds.slice(-1)[0]; + if (previousModalId) { + actions.set(currentModalId, false); + actions.set(previousModalId, true); + } else { + actions.set(currentModalId, false); + } + if (modalIds.length === 0) { + deleteQueryString('modal'); + } else { + setQueryString({ + modal: modalIds.join(MODAL_QUERY_SEPARATOR), + }); + } } } }; diff --git a/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.tsx b/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.tsx index b28c966b..dd9739a2 100644 --- a/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.tsx +++ b/src/pages/my-profile/screens/MyProfileAdDetails/MyProfileAdDetails.tsx @@ -37,7 +37,6 @@ const MyProfileAdDetailsTextArea = ({ }; const MyProfileAdDetails = () => { - //TODO: change isloading to ispending after fixed from api-hooks const { data: advertiserInfo, isLoading } = api.advertiser.useGetInfo(); const { mutate: updateAdvertiser } = api.advertiser.useUpdate(); const [contactInfo, setContactInfo] = useState('');