Skip to content

Commit

Permalink
feat: date filter in past orders
Browse files Browse the repository at this point in the history
  • Loading branch information
nada-deriv committed Oct 4, 2023
1 parent 23e4c60 commit 60c4da1
Show file tree
Hide file tree
Showing 31 changed files with 1,292 additions and 37 deletions.
46 changes: 24 additions & 22 deletions packages/components/src/components/input-field/input-field.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ export type TButtonType = 'button' | 'submit' | 'reset';
// supports more than two different types of 'value' as a prop.
// Quick Solution - Pass two different props to input field.
type TInputField = {
ariaLabel: string;
ariaLabel?: string;
checked?: boolean;
className?: string;
classNameDynamicSuffix?: string;
classNameInlinePrefix?: string;
classNameInput?: string;
classNamePrefix?: string;
classNameWrapper?: string; // CSS class for the component wrapper
currency: string;
currency?: string;
current_focus?: string | null;
data_testid?: string;
data_tip?: string;
Expand All @@ -31,91 +31,93 @@ type TInputField = {
error_message_alignment?: string;
error_messages?: string[];
format?: (new_value?: string) => string;
fractional_digits: number;
fractional_digits?: number;
helper?: string;
icon?: React.ElementType;
id?: string;
increment_button_type?: TButtonType;
inline_prefix?: string;
inputmode?: TInputMode;
is_autocomplete_disabled: boolean;
is_autocomplete_disabled?: boolean;
is_disabled?: boolean;
is_error_tooltip_hidden: boolean;
is_float: boolean;
is_hj_whitelisted: boolean;
is_error_tooltip_hidden?: boolean;
is_float?: boolean;
is_hj_whitelisted?: boolean;
is_incrementable_on_long_press?: boolean;
is_incrementable: boolean;
is_negative_disabled: boolean;
is_incrementable?: boolean;
is_negative_disabled?: boolean;
is_read_only?: boolean;
is_signed?: boolean;
is_unit_at_right?: boolean;
label?: string;
max_length: number;
max_length?: number;
max_value?: number;
min_value?: number;
name: string;
onBlur?: React.FocusEventHandler<HTMLInputElement>;
onChange: (e: TChangeEvent) => void;
onChange?: (e: TChangeEvent) => void;
onClick?: React.MouseEventHandler<HTMLInputElement>;
onClickInputWrapper?: React.MouseEventHandler<HTMLDivElement>;
placeholder?: string;
prefix?: string;
required?: boolean;
setCurrentFocus: (name: string | null) => void;
type: string;
type?: string;
unit?: string;
value: number | string;
};

const InputField = ({
ariaLabel,
ariaLabel = '',
checked,
className,
classNameDynamicSuffix,
classNameInlinePrefix,
classNameInput,
classNamePrefix,
classNameWrapper,
currency,
currency = '',
current_focus,
data_tip,
data_value,
decimal_point_change,
error_messages,
error_message_alignment,
fractional_digits,
fractional_digits = 0,
helper,
icon,
id,
inline_prefix,
is_autocomplete_disabled,
is_autocomplete_disabled = false,
is_disabled,
is_error_tooltip_hidden = false,
is_float,
is_float = false,
is_hj_whitelisted = false,
is_incrementable,
is_incrementable = false,
is_incrementable_on_long_press,
is_negative_disabled,
is_negative_disabled = false,
is_read_only = false,
is_signed = false,
is_unit_at_right = false,
inputmode,
increment_button_type,
label,
max_length,
max_length = 0,
max_value,
min_value,
name,
format,
onBlur,
onChange,
onChange = () => {
// do nothing
},
onClick,
onClickInputWrapper,
placeholder,
prefix,
required,
setCurrentFocus,
type,
type = '',
unit,
value,
data_testid,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import CalendarIcon from '../calendar-icon';
import userEvent from '@testing-library/user-event';

describe('<CalendarIcon />', () => {
it('should render icon', () => {
render(<CalendarIcon onClick={jest.fn()} />);
expect(screen.getByTestId('dt_calendar_icon')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import React from 'react';
import { act, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { StoreProvider, mockStore } from '@deriv/stores';
import CompositeCalendar from '../composite-calendar';
import TwoMonthPicker from '../two-month-picker';
import { toMoment } from '@deriv/shared';

const mock_props = {
input_date_range: {
value: 'last_7_days',
label: 'Last 7 days',
duration: 7,
onClick: jest.fn(),
},
from: 1696319493,
onChange: jest.fn(),
to: 1696928512,
};

jest.mock('../composite-calendar-mobile', () => jest.fn(() => <div>CompositeCalendarMobile</div>));

// jest.mock('../calendar-side-list', () =>jest.fn(() => <div>CalendarSideList</div>));

jest.mock('../two-month-picker', () => jest.fn(() => <div>TwoMonthPicker</div>));

describe('<CompositeCalendar />', () => {
const wrapper = ({ children }: { children: JSX.Element }) => (
<StoreProvider store={mockStore({})}>{children}</StoreProvider>
);
it('should render the component', () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
expect(screen.getByTestId('dt_calendar_input_from')).toBeInTheDocument();
expect(screen.getByTestId('dt_calendar_input_to')).toBeInTheDocument();
});
it('should handle onclick for "from date" input', () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
const from_input = screen.getByTestId('dt_calendar_input_from');
userEvent.click(from_input);
expect(screen.getByText('Last 7 days')).toBeInTheDocument();
});
it('should handle onclick for "to date" input', () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
const to_input = screen.getByTestId('dt_calendar_input_to');
userEvent.click(to_input);
expect(screen.getByText('Last 7 days')).toBeInTheDocument();
});
it('should handle setToDate function click', async () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
const to_input = screen.getByTestId('dt_calendar_input_to');
userEvent.click(to_input);
act(() => {
(TwoMonthPicker as unknown as jest.Mock).mock.calls[0][0].onChange();
});
await waitFor(() => {
expect(mock_props.onChange).toHaveBeenCalled();
});
});
it('should handle setFromDate function click', async () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
const from_input = screen.getByTestId('dt_calendar_input_from');
userEvent.click(from_input);
act(() => {
(TwoMonthPicker as unknown as jest.Mock).mock.calls[0][0].onChange();
});
await waitFor(() => {
expect(mock_props.onChange).toHaveBeenCalled();
});
});
it('should handle onclick for "All time" option', () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
const from_input = screen.getByTestId('dt_calendar_input_from');
userEvent.click(from_input);
userEvent.click(screen.getByText('All time'));
expect(mock_props.onChange).toHaveBeenCalled();
});
it('should handle onclick for "Today" option', () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
const from_input = screen.getByTestId('dt_calendar_input_from');
userEvent.click(from_input);
userEvent.click(screen.getByText('Today'));
expect(mock_props.onChange).toHaveBeenCalled();
});
it('should handle onclick for "Last 7 days" option', () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
const from_input = screen.getByTestId('dt_calendar_input_from');
userEvent.click(from_input);
userEvent.click(screen.getByText('Last 7 days'));
expect(mock_props.onChange).toHaveBeenCalled();
});
it('should handle onclick for "Last 30 days" option', () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
const from_input = screen.getByTestId('dt_calendar_input_from');
userEvent.click(from_input);
userEvent.click(screen.getByText('Last 30 days'));
expect(mock_props.onChange).toHaveBeenCalled();
});
it('should handle onclick for "Last quarter" option', () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
const from_input = screen.getByTestId('dt_calendar_input_from');
userEvent.click(from_input);
userEvent.click(screen.getByText('Last quarter'));
expect(mock_props.onChange).toHaveBeenCalled();
});
it('should disable date before from date in "to input" section ', () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
const to_input = screen.getByTestId('dt_calendar_input_to');
userEvent.click(to_input);
expect(
(TwoMonthPicker as unknown as jest.Mock).mock.calls[0][0].isPeriodDisabled(toMoment('2023-10-02'))
).toBeTruthy();
});
it('should disable date after to date in "from input" section ', () => {
render(<CompositeCalendar {...mock_props} />, { wrapper });
const from_input = screen.getByTestId('dt_calendar_input_from');
userEvent.click(from_input);
expect(
(TwoMonthPicker as unknown as jest.Mock).mock.calls[0][0].isPeriodDisabled(toMoment('2023-10-02'))
).toBeFalsy();
expect(
(TwoMonthPicker as unknown as jest.Mock).mock.calls[0][0].isPeriodDisabled(toMoment('2023-10-12'))
).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import TwoMonthPicker from '../two-month-picker';

const mock_props = {
onChange: jest.fn(),
isPeriodDisabled: jest.fn(),
value: 1696319493, // 2023-10-04
};

describe('TwoMonthPicker', () => {
it('should render the component', () => {
render(<TwoMonthPicker {...mock_props} />);
expect(screen.getByText('Sep')).toBeInTheDocument();
});
});
12 changes: 12 additions & 0 deletions packages/p2p/src/components/composite-calendar/calendar-icon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';
import { Icon } from '@deriv/components';

type TCalendarIcon = {
onClick: () => void;
};

const CalendarIcon = ({ onClick }: TCalendarIcon) => (
<Icon onClick={onClick} icon='IcCalendarDatefrom' className='inline-icon' data_testid='dt_calendar_icon' />
);

export default CalendarIcon;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import CalendarRadioButton from '../calendar-radio-button';

const mock_props = {
id: '1',
value: 'all_time',
label: 'All time',
onChange: jest.fn(),
};

describe('CalendarRadioButton', () => {
it('should render the radio button', () => {
render(<CalendarRadioButton {...mock_props} />);
expect(screen.getByText('All time')).toBeInTheDocument();
});
it('should handle on click of radio button', () => {
render(<CalendarRadioButton {...mock_props} />);
userEvent.click(screen.getByText('All time'));
expect(mock_props.onChange).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.calendar-radio-button {
display: flex;
align-items: center;
padding: 0.7rem 0.8rem;
border: 1px solid;
border-color: var(--border-normal);
border-radius: 4px;
margin: 0.8rem 0.8rem 2.4rem;

&__input {
display: none;
}
&__circle {
border: 2px solid var(--text-less-prominent);
border-radius: 50%;
box-shadow: 0 0 1px 0 var(--shadow-menu);
width: 1.6rem;
height: 1.6rem;
transition: all 0.3s ease-in-out;
margin-right: 0.8rem;
align-self: center;

&--selected {
border-width: 4px;
border-color: var(--brand-red-coral);
}
}
&--selected {
border-color: var(--brand-secondary);
font-weight: bold;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import classNames from 'classnames';
import { Text } from '@deriv/components';

type TCalendarRadioButtonProps = {
id: string;
className?: string;
selected_value?: string;
value: string;
label: string;
onChange: (value: { label?: string; value?: string }) => void;
};

const CalendarRadioButton = ({ id, className, selected_value, value, label, onChange }: TCalendarRadioButtonProps) => {
return (
<label
htmlFor={id}
className={classNames('calendar-radio-button', className, {
'calendar-radio-button--selected': selected_value === value,
})}
onClick={() => onChange({ label, value })}
>
<input className='calendar-radio-button__input' id={id} type='radio' value={value} />
<span
className={classNames('calendar-radio-button__circle', {
'calendar-radio-button__circle--selected': selected_value === value,
})}
/>
<Text
as='p'
color='prominent'
size='xs'
line_height='unset'
weight={selected_value === value ? 'bold' : 'normal'}
>
{label}
</Text>
</label>
);
};

export default CalendarRadioButton;
Loading

0 comments on commit 60c4da1

Please sign in to comment.