Skip to content

Commit

Permalink
[P2PS] farrah/P2PS-2244/feat: copy advert (binary-com#14283)
Browse files Browse the repository at this point in the history
* feat: copy ads

* fix: ad menu style

* fix: comments

* fix: ad rate

* fix: subtasks raised

* fix: layout issues

* fix: remove unnecessary change

* fix: subtasks

* fix: test

* fix: switch rates

* fix: switch rates flow

* fix: test

* fix: subtasks

* fix: switch on ad edit

* fix: scroll

* fix: word break
  • Loading branch information
farrah-deriv committed Apr 22, 2024
1 parent ed0a5a7 commit a46d04a
Show file tree
Hide file tree
Showing 39 changed files with 1,115 additions and 392 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
}

&__error-message {
padding-inline-start: 4rem;
padding-left: 1.1rem;
text-transform: none;
@include mobile {
padding-inline-start: 1rem;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function MockMyAdsDeleteModal({ title }: TMockMyAdsDeleteModalProps) {
);
}

export function MockEditAdCancelModal() {
export function MockAdCancelModal() {
const { hideModal, showModal, useRegisterModalProps } = useModalManagerContext();

const showBuySellModal = () =>
Expand Down Expand Up @@ -103,10 +103,14 @@ export function MockPage() {
});
};

const showEditAdCancelModal = () => {
const showAdCancelModal = () => {
showModal({
key: 'EditAdCancelModal',
props: {},
key: 'AdCancelModal',
props: {
confirm_label: "Don't cancel",
message: 'If you choose to cancel, the edited details will be lost.',
title: 'Cancel your edits?',
},
});
};

Expand All @@ -119,7 +123,7 @@ export function MockPage() {
{isCurrentModal('MyAdsDeleteModal') && <h1>Delete Ads</h1>}
<button onClick={showBuySellModal}>Show BuySellModal</button>
<button onClick={showMyAdsDeleteModal}>Show MyAdsDeleteModal</button>
<button onClick={showEditAdCancelModal}>Show EditAdCancelModal</button>
<button onClick={showAdCancelModal}>Show AdCancelModal</button>
<button onClick={() => hideModal()}>Hide Modal</button>
<button onClick={hideModals}>Hide All Modals</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useStores } from 'Stores/index';
import {
MockBuySellModal,
MockMyAdsDeleteModal,
MockEditAdCancelModal,
MockAdCancelModal,
MockPage,
} from '../__mocks__/mock-modal-manager-context-provider';

Expand All @@ -34,7 +34,7 @@ jest.mock('Constants/modals', () => ({
Modals: {
BuySellModal: (props: any) => <MockBuySellModal {...props} />,
MyAdsDeleteModal: (props: any) => <MockMyAdsDeleteModal {...props} />,
EditAdCancelModal: (props: any) => <MockEditAdCancelModal {...props} />,
AdCancelModal: (props: any) => <MockAdCancelModal {...props} />,
},
}));

Expand Down Expand Up @@ -323,10 +323,10 @@ describe('<ModalManagerContextProvider />', () => {
</React.Fragment>
);

const edit_ad_cancel_modal_btn = screen.getByRole('button', {
name: /Show EditAdCancelModal/,
const ad_cancel_modal_btn = screen.getByRole('button', {
name: /Show AdCancelModal/,
});
userEvent.click(edit_ad_cancel_modal_btn);
userEvent.click(ad_cancel_modal_btn);

const buy_sell_modal_btn = screen.getByRole('button', {
name: /Go to BuySellModal/,
Expand All @@ -346,10 +346,10 @@ describe('<ModalManagerContextProvider />', () => {
</React.Fragment>
);

const edit_ad_cancel_modal_btn = screen.getByRole('button', {
name: /Show EditAdCancelModal/,
const ad_cancel_modal_btn = screen.getByRole('button', {
name: /AdCancelModal/,
});
userEvent.click(edit_ad_cancel_modal_btn);
userEvent.click(ad_cancel_modal_btn);

const submit_btn = screen.getByRole('button', {
name: /Submit/,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import userEvent from '@testing-library/user-event';
import { render, screen } from '@testing-library/react';
import { useModalManagerContext } from 'Components/modal-manager/modal-manager-context';
import { useStores } from 'Stores';
import EditAdCancelModal from '../edit-ad-cancel-modal';
import AdCancelModal from '../ad-cancel-modal';

const mock_store: DeepPartial<ReturnType<typeof useStores>> = {
my_ads_store: {
Expand All @@ -28,7 +28,7 @@ const mocked_useModalManagerContext = useModalManagerContext as jest.MockedFunct

mocked_useModalManagerContext.mockImplementation(() => mock_modal_manager);

describe('<EditAdCancelModal/>', () => {
describe('<AdCancelModal/>', () => {
let modal_root_el: HTMLElement;
beforeAll(() => {
modal_root_el = document.createElement('div');
Expand All @@ -39,17 +39,33 @@ describe('<EditAdCancelModal/>', () => {
afterAll(() => {
document.body.removeChild(modal_root_el);
});
it('should render the EditAdCancelModal', () => {
render(<EditAdCancelModal />);
it('should render the AdCancelModal', () => {
render(
<AdCancelModal
confirm_label='Go back'
message="If you choose to cancel, the details you've entered will be lost."
title='Cancel ad creation?'
/>
);

expect(screen.getByText('Cancel your edits?')).toBeInTheDocument();
const confirm_button = screen.getByRole('button', { name: 'Go back' });
expect(confirm_button).toBeInTheDocument();
expect(screen.getByText('Cancel ad creation?')).toBeInTheDocument();
expect(
screen.getByText("If you choose to cancel, the details you've entered will be lost.")
).toBeInTheDocument();
});
it('should close modal on clicking cancel button', () => {
render(<EditAdCancelModal />);
render(
<AdCancelModal
confirm_label="Don't cancel"
message='If you choose to cancel, the edited details will be lost.'
title='Cancel your edits?'
/>
);

const cancel_button = screen.getByText('Cancel');
const cancel_button = screen.getByRole('button', { name: 'Cancel' });
userEvent.click(cancel_button);
expect(mock_modal_manager.hideModal).toBeCalledTimes(1);
expect(mock_store.my_ads_store.setShowEditAdForm).toBeCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
import React from 'react';
import { Button, Modal, Text } from '@deriv/components';
import { localize, Localize } from 'Components/i18next';
import { localize } from 'Components/i18next';
import { useModalManagerContext } from 'Components/modal-manager/modal-manager-context';
import { useStores } from 'Stores';

const EditAdCancelModal = () => {
const { my_ads_store } = useStores();
type TAdCancelModalProps = {
confirm_label: string;
message: string;
onConfirm?: () => void;
title: string;
};

const AdCancelModal = ({ confirm_label, message, onConfirm, title }: TAdCancelModalProps) => {
const { hideModal, is_modal_open } = useModalManagerContext();
const { setShowEditAdForm } = my_ads_store;

return (
<Modal has_close_icon={false} is_open={is_modal_open} small title={localize('Cancel your edits?')}>
<Modal has_close_icon={false} is_open={is_modal_open} small title={title}>
<Modal.Body>
<Text as='p' size='xs' color='prominent'>
<Localize i18n_default_text='If you choose to cancel, the edited details will be lost.' />
{message}
</Text>
</Modal.Body>
<Modal.Footer>
<Button
has_effect
text={localize('Cancel')}
onClick={() => {
hideModal();
setShowEditAdForm(false);
hideModal({ should_hide_all_modals: true });
onConfirm?.();
}}
secondary
large
/>
<Button has_effect text={localize("Don't cancel")} onClick={hideModal} primary large />
<Button has_effect text={confirm_label} onClick={hideModal} primary large />
</Modal.Footer>
</Modal>
);
};

export default EditAdCancelModal;
export default AdCancelModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import AdCancelModal from './ad-cancel-modal';

export default AdCancelModal;
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const AdCreateEditErrorModal = ({ ad_type = ads.CREATE }: TAdCreateEditErrorModa
<Button
has_effect
text={is_api_error ? localize('Update ad') : localize('Ok')}
onClick={hideModal}
onClick={is_api_error ? hideModal : () => hideModal({ should_hide_all_modals: true })}
primary
large
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from 'react';
import { Button, Checkbox, Modal, Text } from '@deriv/components';
import { localize, Localize } from 'Components/i18next';
import { useModalManagerContext } from 'Components/modal-manager/modal-manager-context';
import { api_error_codes } from 'Constants/api-error-codes';
import { useStores } from 'Stores';

type TAdCreatedModalProps = {
adverts_archive_period: number;
};

const AdCreatedModal = ({ adverts_archive_period }: TAdCreatedModalProps) => {
const { hideModal, is_modal_open } = useModalManagerContext();
const { general_store, my_ads_store } = useStores();
const should_not_show_auto_archive_message_again = React.useRef(false);

const onCheckboxChange = () =>
(should_not_show_auto_archive_message_again.current = !should_not_show_auto_archive_message_again.current);

const onClickOkCreatedAd = () => {
localStorage.setItem(
'should_not_show_auto_archive_message',
JSON.stringify(should_not_show_auto_archive_message_again.current)
);
my_ads_store.setIsAdCreatedModalVisible(false);
if (my_ads_store.advert_details?.visibility_status?.includes(api_error_codes.AD_EXCEEDS_BALANCE)) {
general_store.showModal({
key: 'AdVisibilityErrorModal',
props: { error_code: api_error_codes.AD_EXCEEDS_BALANCE },
});
} else if (my_ads_store.advert_details?.visibility_status?.includes(api_error_codes.AD_EXCEEDS_DAILY_LIMIT)) {
general_store.showModal({
key: 'AdVisibilityErrorModal',
props: { error_code: api_error_codes.AD_EXCEEDS_DAILY_LIMIT },
});
}

my_ads_store.setShowAdForm(false);
hideModal({ should_hide_all_modals: true });
};

return (
<Modal
className='my-ads__ad-created'
has_close_icon={false}
is_open={is_modal_open}
small
title={localize("You've created an ad")}
toggleModal={hideModal}
>
<Modal.Body>
<Text as='p' size='xs' color='prominent'>
<Localize
i18n_default_text="If the ad doesn't receive an order for {{adverts_archive_period}} days, it will be deactivated."
values={{ adverts_archive_period }}
/>
</Text>
<br />
<Checkbox
label={localize('Don’t show this message again.')}
onChange={onCheckboxChange}
value={should_not_show_auto_archive_message_again.current}
/>
</Modal.Body>
<Modal.Footer>
<Button has_effect text={localize('Ok')} onClick={onClickOkCreatedAd} primary large />
</Modal.Footer>
</Modal>
);
};

export default AdCreatedModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import AdCreatedModal from './ad-created-modal';

export default AdCreatedModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { mockStore, P2PSettingsProvider, StoreProvider } from '@deriv/stores';
import { adverts } from 'Pages/my-ads/__mocks__/mock-data';
import { useStores } from 'Stores/index';
import CopyAdvertModal from '../copy-advert-modal';

const wrapper = ({ children }) => (
<StoreProvider store={mockStore({})}>
<P2PSettingsProvider>{children}</P2PSettingsProvider>
</StoreProvider>
);

const mock_store: DeepPartial<ReturnType<typeof useStores>> = {
my_ads_store: {
payment_method_ids: [],
payment_method_names: [],
setShowEditAdForm: jest.fn(),
},
};

const el_modal = document.createElement('div');

jest.mock('Stores', () => ({
...jest.requireActual('Stores'),
useStores: jest.fn(() => mock_store),
}));

jest.mock('Components/modal-manager/modal-manager-context', () => ({
...jest.requireActual('Components/modal-manager/modal-manager-context'),
useModalManagerContext: jest.fn(() => ({
hideModal: jest.fn(),
is_modal_open: true,
})),
}));

describe('<CopyAdvertModal />', () => {
beforeAll(() => {
el_modal.setAttribute('id', 'modal_root');
document.body.appendChild(el_modal);
});

afterAll(() => {
document.body.removeChild(el_modal);
});

it('should render CopyAdvertModal', () => {
render(<CopyAdvertModal advert={adverts[0]} />, { wrapper });

expect(screen.getByText('Create a similar ad')).toBeInTheDocument();
expect(screen.getByRole('button', { name: 'Cancel' }));
expect(screen.getByRole('button', { name: 'Create ad' }));
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.copy-advert-modal {
@include desktop {
padding: 1rem 0 0;
}

@include mobile {
padding: 1rem;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';
import { Modal } from '@deriv/components';
import { Localize } from 'Components/i18next';
import { useModalManagerContext } from 'Components/modal-manager/modal-manager-context';
import CopyAdvertForm from 'Pages/my-ads/copy-advert-form';
import { useStores } from 'Stores';
import { TAdvert } from 'Types';

const CopyAdvertModal = ({ advert }: TAdvert) => {
const { is_modal_open } = useModalManagerContext();
const { my_ads_store } = useStores();

return (
<Modal
is_open={is_modal_open}
small
has_close_icon={false}
title={<Localize i18n_default_text='Create a similar ad' />}
>
<Modal.Body className='copy-advert-modal'>
<CopyAdvertForm advert={advert} onCancel={() => my_ads_store.setShowEditAdForm(false)} />
</Modal.Body>
</Modal>
);
};

export default CopyAdvertModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import CopyAdvertModal from './copy-advert-modal';
import './copy-advert-modal.scss';

export default CopyAdvertModal;

This file was deleted.

Loading

0 comments on commit a46d04a

Please sign in to comment.