Skip to content

Commit

Permalink
[FEQ]- P2PV2 - counterparty conditions for create ad (binary-com#14405)
Browse files Browse the repository at this point in the history
* feat: counterparty conditions

* fix: pending test cases

* fix: style fixes, pending tests

* fix: removed temp changes

* fix: styles fixes

* fix: text size fix for no seach results

* fix: failing test in search results fixed

* fix: pr review comments

* fix: update test click event
  • Loading branch information
nada-deriv committed Apr 3, 2024
1 parent dc72714 commit b9dfdd3
Show file tree
Hide file tree
Showing 54 changed files with 2,001 additions and 30 deletions.
@@ -0,0 +1,8 @@
.p2p-v2-ad-conditions-modal {
border-radius: 8px;
width: 44rem;
height: fit-content;
@include mobile {
max-width: calc(100vw - 3.2rem);
}
}
@@ -0,0 +1,38 @@
import React from 'react';
import { AD_CONDITION_CONTENT } from '@/constants';
import { Button, Modal, Text, useDevice } from '@deriv-com/ui';
import './AdConditionsModal.scss';

type TAdConditionsModalProps = {
isModalOpen: boolean;
onRequestClose: () => void;
type: string;
};

const AdConditionsModal = ({ isModalOpen, onRequestClose, type }: TAdConditionsModalProps) => {
const { isMobile } = useDevice();
return (
<Modal
ariaHideApp={false}
className='p2p-v2-ad-conditions-modal'
isOpen={isModalOpen}
onRequestClose={onRequestClose}
>
<Modal.Header className='px-[1.6rem]' hideBorder hideCloseIcon onRequestClose={onRequestClose}>
<Text weight='bold'>{AD_CONDITION_CONTENT[type].title}</Text>
</Modal.Header>
<Modal.Body className='p-[1.6rem] lg:p-[2.4rem]'>
<Text className='whitespace-pre-line' size='sm'>
{AD_CONDITION_CONTENT[type].description}
</Text>
</Modal.Body>
<Modal.Footer hideBorder>
<Button onClick={onRequestClose} size='lg' textSize={isMobile ? 'md' : 'sm'} variant='contained'>
OK
</Button>
</Modal.Footer>
</Modal>
);
};

export default AdConditionsModal;
@@ -0,0 +1 @@
export { default as AdConditionsModal } from './AdConditionsModal';
@@ -0,0 +1,29 @@
.p2p-v2-ad-create-edit-error-modal {
height: fit-content;
width: 44rem;
border-radius: 8px;
@include mobile {
max-width: calc(100vw - 3.2rem);
}

&__header {
@include mobile {
padding: 1.6rem;
}
}

&__footer {
@include mobile {
padding-right: 1.6rem;
padding-left: 1.6rem;
}
}

&__body {
padding: 2.4rem;

@include mobile {
padding: 0.8rem 2.4rem;
}
}
}
@@ -0,0 +1,61 @@
import React from 'react';
import { ERROR_CODES } from '@/constants';
import { Button, Modal, Text, useDevice } from '@deriv-com/ui';
import './AdCreateEditErrorModal.scss';

type TAdCreateEditErrorModalProps = {
errorCode?: ErrorCodes;
isModalOpen: boolean;
onRequestClose: () => void;
};

type ErrorCodes = typeof ERROR_CODES[keyof typeof ERROR_CODES];

type ErrorContent = {
[key in ErrorCodes]?: {
description: string;
title: string;
};
};

const errorContent: ErrorContent = {
[ERROR_CODES.ADVERT_SAME_LIMITS]: {
description:
'Please set a different minimum and/or maximum order limit. \n\nThe range of your ad should not overlap with any of your active ads.',
title: 'You already have an ad with this range',
},
[ERROR_CODES.DUPLICATE_ADVERT]: {
description:
'You already have an ad with the same exchange rate for this currency pair and order type. \n\nPlease set a different rate for your ad.',
title: 'You already have an ad with this rate',
},
};

const AdCreateEditErrorModal = ({ errorCode, isModalOpen, onRequestClose }: TAdCreateEditErrorModalProps) => {
const { isMobile } = useDevice();
const textSize = isMobile ? 'md' : 'sm';
return (
<Modal
ariaHideApp={false}
className='p2p-v2-ad-create-edit-error-modal'
isOpen={isModalOpen}
onRequestClose={onRequestClose}
>
<Modal.Header className='p2p-v2-ad-create-edit-error-modal__header' hideBorder hideCloseIcon>
<Text weight='bold'>{(errorCode && errorContent?.[errorCode]?.title) ?? 'Something’s not right'}</Text>
</Modal.Header>
<Modal.Body className='p2p-v2-ad-create-edit-error-modal__body'>
<Text size={textSize}>
{(errorCode && errorContent?.[errorCode]?.description) ?? 'Something’s not right'}
</Text>
</Modal.Body>
<Modal.Footer className='p2p-v2-ad-create-edit-error-modal__footer' hideBorder>
<Button onClick={onRequestClose} size='lg' textSize={textSize}>
{errorCode ? 'Update ad' : 'Ok'}
</Button>
</Modal.Footer>
</Modal>
);
};

export default AdCreateEditErrorModal;
@@ -0,0 +1,35 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import AdCreateEditErrorModal from '../AdCreateEditErrorModal';

const mockProps = {
errorCode: 'AdvertSameLimits',
isModalOpen: true,
onRequestClose: jest.fn(),
};

jest.mock('@deriv-com/ui', () => ({
...jest.requireActual('@deriv-com/ui'),
useDevice: () => ({ isMobile: false }),
}));
describe('AdCreateEditErrorModal', () => {
it('should render the component as expected', () => {
render(<AdCreateEditErrorModal {...mockProps} />);
expect(screen.getByText('You already have an ad with this range')).toBeInTheDocument();
});
it('should render the error message for duplicate adverts', () => {
render(<AdCreateEditErrorModal {...mockProps} errorCode='DuplicateAdvert' />);
expect(screen.getByText('You already have an ad with this rate')).toBeInTheDocument();
});
it('should render the general error message if no error code is provided', () => {
render(<AdCreateEditErrorModal {...mockProps} errorCode={undefined} />);
expect(screen.getAllByText('Something’s not right')).toHaveLength(2);
});
it('should call onRequestClose when the button is clicked', () => {
render(<AdCreateEditErrorModal {...mockProps} />);
const button = screen.getByRole('button', { name: 'Update ad' });
userEvent.click(button);
expect(mockProps.onRequestClose).toHaveBeenCalledTimes(1);
});
});
@@ -0,0 +1 @@
export { default as AdCreateEditErrorModal } from './AdCreateEditErrorModal';
@@ -0,0 +1,20 @@
.p2p-v2-ad-create-edit-success-modal {
height: fit-content;
width: 44rem;
border-radius: 8px;

@include mobile {
max-width: calc(100vw - 3.2rem);
}

&__body {
padding: 2.4rem;
display: flex;
flex-direction: column;
gap: 1rem;

@include mobile {
padding: 0 2.4rem;
}
}
}
@@ -0,0 +1,61 @@
import React, { useCallback, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { MY_ADS_URL } from '@/constants';
import { Button, Checkbox, Modal, Text, useDevice } from '@deriv-com/ui';
import './AdCreateEditSuccessModal.scss';

type TAdCreateEditSuccessModalProps = {
advertsArchivePeriod?: number;
isModalOpen: boolean;
onRequestClose: () => void;
};

const AdCreateEditSuccessModal = ({
advertsArchivePeriod,
isModalOpen,
onRequestClose,
}: TAdCreateEditSuccessModalProps) => {
const { isMobile } = useDevice();
const history = useHistory();
const [isChecked, setIsChecked] = useState(false);
const textSize = isMobile ? 'md' : 'sm';
const onToggleCheckbox = useCallback(() => {
setIsChecked(prevState => !prevState);
}, []);

const onClickOk = () => {
localStorage.setItem('should_not_show_auto_archive_message_again', JSON.stringify(isChecked));
history.push(MY_ADS_URL);
onRequestClose();
};
return (
<Modal
ariaHideApp={false}
className='p2p-v2-ad-create-edit-success-modal'
isOpen={isModalOpen}
onRequestClose={onRequestClose}
>
<Modal.Header hideBorder hideCloseIcon>
<Text weight='bold'>You’ve created an ad</Text>
</Modal.Header>
<Modal.Body className='p2p-v2-ad-create-edit-success-modal__body'>
<Text color='prominent' size={textSize}>
{`If the ad doesn't receive an order for ${advertsArchivePeriod} days, it will be deactivated.`}
</Text>
<Checkbox
checked={isChecked}
label='Don’t show this message again.'
name='ad-create-success-message'
onChange={onToggleCheckbox}
/>
</Modal.Body>
<Modal.Footer hideBorder>
<Button onClick={onClickOk} size='lg' textSize={textSize}>
Ok
</Button>
</Modal.Footer>
</Modal>
);
};

export default AdCreateEditSuccessModal;
@@ -0,0 +1,47 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import AdCreateEditSuccessModal from '../AdCreateEditSuccessModal';

const mockProps = {
advertsArchivePeriod: 7,
isModalOpen: true,
onRequestClose: jest.fn(),
};

jest.mock('@deriv-com/ui', () => ({
...jest.requireActual('@deriv-com/ui'),
useDevice: () => ({ isMobile: false }),
}));

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useHistory: () => ({
push: jest.fn(),
}),
}));

describe('AdCreateEditSuccessModal', () => {
it('should render with passed props', () => {
render(<AdCreateEditSuccessModal {...mockProps} />);
expect(screen.getByText(/You’ve created an ad/i)).toBeInTheDocument();
expect(
screen.getByText(/If the ad doesn't receive an order for 7 days, it will be deactivated./i)
).toBeInTheDocument();
});
it('should handle checkbox change', () => {
render(<AdCreateEditSuccessModal {...mockProps} />);
const checkbox = screen.getByRole('checkbox');
expect(checkbox).toBeInTheDocument();
expect(checkbox).not.toBeChecked();
userEvent.click(checkbox);
expect(checkbox).toBeChecked();
});
it('should handle ok button click', () => {
render(<AdCreateEditSuccessModal {...mockProps} />);
const okButton = screen.getByRole('button', { name: 'Ok' });
expect(okButton).toBeInTheDocument();
userEvent.click(okButton);
expect(mockProps.onRequestClose).toBeCalledTimes(1);
});
});
@@ -0,0 +1 @@
export { default as AdCreateEditSuccessModal } from './AdCreateEditSuccessModal';
@@ -0,0 +1,21 @@
import React from 'react';
import { Text, useDevice } from '@deriv-com/ui';

type TNoSearchResultsProps = {
value: string;
};
const NoSearchResults = ({ value }: TNoSearchResultsProps) => {
const { isMobile } = useDevice();
return (
<div className='flex flex-col items-center justify-center mt-64 break-all'>
<Text align='center' size={isMobile ? 'lg' : 'md'} weight='bold'>
{`No results for “${value}”.`}
</Text>
<Text align='center' size={isMobile ? 'md' : 'sm'}>
Check your spelling or use a different term.
</Text>
</div>
);
};

export default NoSearchResults;
@@ -0,0 +1,16 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import NoSearchResults from '../NoSearchResults';

jest.mock('@deriv-com/ui', () => ({
...jest.requireActual('@deriv-com/ui'),
useDevice: () => ({ isMobile: false }),
}));

describe('NoSearchResults', () => {
it('should render', () => {
render(<NoSearchResults value='test' />);
expect(screen.getByText('No results for “test”.')).toBeInTheDocument();
expect(screen.getByText('Check your spelling or use a different term.')).toBeInTheDocument();
});
});
@@ -0,0 +1 @@
export { default as NoSearchResults } from './NoSearchResults';
@@ -0,0 +1,31 @@
.p2p-v2-preferred-countries-dropdown {
& .p2p-v2-search {
& .deriv-input {
&__container {
& .deriv-input__left-content {
margin-left: -1rem;
}
& .deriv-input__field {
margin-left: 1.8rem;
}
}
}
}
&__content {
height: 37rem;
overflow-y: auto;

@include mobile {
height: unset;
max-height: calc(100vh - 28rem);
}

&--no-footer {
height: 44rem;
@include mobile {
height: 100vh;
max-height: unset;
}
}
}
}

0 comments on commit b9dfdd3

Please sign in to comment.