Skip to content

Commit

Permalink
Nada/feq 1392/advert list (deriv-com#13326)
Browse files Browse the repository at this point in the history
* feat: advert list

* fix: eslint errors

* fix: fix styling issues

* fix: test fix

* fix: remove unused variables

* fix: sonar issues

* fix: replace regex

* fix: prettier

* fix: coveralls

* fix: test fixes, removed unused variables, functions

* fix: pr comments

* fix: pr comments fix

* fix: pr comments fixed
  • Loading branch information
nada-deriv authored Feb 7, 2024
1 parent 54d4fe9 commit 1779ab7
Show file tree
Hide file tree
Showing 54 changed files with 1,793 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const useAdvertUpdate = () => {
} = useMutation('p2p_advert_update', {
onSuccess: () => {
invalidate('p2p_advert_list');
invalidate('p2p_advertiser_adverts');
},
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const useAdvertiserAdverts = (
options: {
...config,
getNextPageParam: (lastPage, pages) => {
if (!lastPage?.p2p_advertiser_adverts?.list) return;
if (!lastPage?.p2p_advertiser_adverts?.list?.length) return;

return pages.length;
},
Expand Down Expand Up @@ -53,6 +53,8 @@ const useAdvertiserAdverts = (
},
/** The advert creation time in epoch. */
created_time: advert?.created_time ? new Date(advert.created_time) : undefined,
/** Indicates if this is block trade advert or not. */
block_trade: Boolean(advert?.block_trade),
}));
}, [flatten_data]);

Expand Down
5 changes: 3 additions & 2 deletions packages/api/src/hooks/useExchangeRateSubscription.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { useCallback } from 'react';
import useSubscription from '../useSubscription';

type TPayload = Required<
NonNullable<Parameters<ReturnType<typeof useSubscription<'exchange_rates'>>['subscribe']>>[0]['payload']
type TPayload = WithRequiredProperty<
NonNullable<Parameters<ReturnType<typeof useSubscription<'exchange_rates'>>['subscribe']>>[0]['payload'],
'target_currency'
>;

/** A custom hook that gets exchange rates from base currency to target currency */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.p2p-v2-popover-dropdown {
display: flex;
flex-direction: column;
position: relative;

&__icon {
margin-left: 1rem;
}

&__list {
display: flex;
flex-direction: column;
border-radius: 0.4rem;
width: 19.5rem;
box-shadow: 0px 32px 64px 0px #0e0e0e24;
z-index: 999;
top: 2.8rem;
position: absolute;
background: #fff;
right: 0;

.derivs-button__color--primary:hover:not(:disabled) {
background-color: var(--general-hover);
}

&-item {
padding: 1rem 1.6rem;
background-color: inherit;
height: inherit;
}
}
}
50 changes: 50 additions & 0 deletions packages/p2p-v2/src/components/PopoverDropdown/PopoverDropdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, { useRef, useState } from 'react';
import { Button, Text } from '@deriv-com/ui';
import { useOnClickOutside } from 'usehooks-ts';
import { LabelPairedEllipsisVerticalMdRegularIcon } from '@deriv/quill-icons';
import './PopoverDropdown.scss';

type TItem = {
label: string;
value: string;
};

type TPopoverDropdownProps = {
dataTestId?: string;
dropdownList: TItem[];
onClick: (value: string) => void;
};

const PopoverDropdown = ({ dataTestId, dropdownList, onClick }: TPopoverDropdownProps) => {
const [visible, setVisible] = useState(false);
const ref = useRef(null);
useOnClickOutside(ref, () => setVisible(false));

return (
<div className='p2p-v2-popover-dropdown' ref={ref}>
<LabelPairedEllipsisVerticalMdRegularIcon
className='p2p-v2-popover-dropdown__icon'
data-testid={dataTestId}
onClick={() => setVisible(prevState => !prevState)}
/>
{visible && (
<div className='p2p-v2-popover-dropdown__list'>
{dropdownList.map(item => (
<Button
className='p2p-v2-popover-dropdown__list-item'
key={item.value}
onClick={() => {
onClick(item.value);
setVisible(false);
}}
>
<Text key={item.value}>{item.label}</Text>
</Button>
))}
</div>
)}
</div>
);
};

export default PopoverDropdown;
1 change: 1 addition & 0 deletions packages/p2p-v2/src/components/PopoverDropdown/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as PopoverDropdown } from './PopoverDropdown';
27 changes: 20 additions & 7 deletions packages/p2p-v2/src/components/Table/Table.scss
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
.p2p-v2-table {
overflow-y: auto;
display: flex;
flex-direction: column;
width: 100%;
position: absolute;
&__content {
overflow-y: auto;
display: flex;
flex-direction: column;
width: 100%;

@include mobile {
height: 100%;
@include mobile {
height: 100%;
}

&-row {
&:not(:last-child) {
border-bottom: 1px solid var(--general-section-1);
}
}
}

scrollbar-width: thin; /* For Firefox */
Expand Down Expand Up @@ -35,4 +42,10 @@
background-color: var(--state-active);
}
}

&__header {
display: grid;
border-bottom: 2px solid var(--general-section-1);
padding: 1.6rem;
}
}
51 changes: 37 additions & 14 deletions packages/p2p-v2/src/components/Table/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { memo, useRef } from 'react';
import React, { memo, useLayoutEffect, useRef, useState } from 'react';
import clsx from 'clsx';
import { useFetchMore } from '@/hooks';
import { ColumnDef, getCoreRowModel, getGroupedRowModel, GroupingState, useReactTable } from '@tanstack/react-table';
import { Text } from '@deriv-com/ui';
import { useFetchMore, useDevice } from '@/hooks';
import './Table.scss';

type TProps<T> = {
Expand All @@ -10,8 +11,7 @@ type TProps<T> = {
groupBy?: GroupingState;
isFetching: boolean;
loadMoreFunction: () => void;
rowClassname: string;
rowGroupRender?: (data: T) => JSX.Element;
renderHeader?: (data: string) => JSX.Element;
rowRender: (data: T) => JSX.Element;
tableClassname: string;
};
Expand All @@ -21,10 +21,11 @@ const Table = <T,>({
data,
isFetching,
loadMoreFunction,
rowClassname,
renderHeader = () => <div />,
rowRender,
tableClassname,
}: TProps<T>) => {
const { isDesktop } = useDevice();
const table = useReactTable({
columns,
data,
Expand All @@ -33,23 +34,45 @@ const Table = <T,>({
});

const tableContainerRef = useRef<HTMLDivElement>(null);
const headerRef = useRef<HTMLDivElement>(null);
const [height, setHeight] = useState(0);

useLayoutEffect(() => {
if (headerRef?.current) {
const topPosition = headerRef.current.getBoundingClientRect().bottom;
setHeight(window.innerHeight - topPosition);
}
}, [headerRef?.current]);

const { fetchMoreOnBottomReached } = useFetchMore({
loadMore: loadMoreFunction,
ref: tableContainerRef,
isFetching,
});

return (
<div
className={clsx('p2p-v2-table', tableClassname)}
onScroll={e => fetchMoreOnBottomReached(e.target as HTMLDivElement)}
ref={tableContainerRef}
>
{table.getRowModel().rows.map(row => (
<div className={rowClassname} key={row.id}>
{rowRender(row.original)}
<div className='w-full'>
{isDesktop && columns.length > 0 && (
<div className='p2p-v2-table__header' ref={headerRef}>
{table.getFlatHeaders().map(header => (
<Text className='p2p-v2-table__header-items' key={header.id} size='sm' weight='bold'>
{renderHeader(header.column.columnDef.header as string)}
</Text>
))}
</div>
))}
)}
<div
className={clsx('p2p-v2-table__content', tableClassname)}
onScroll={e => fetchMoreOnBottomReached(e.target as HTMLDivElement)}
ref={tableContainerRef}
style={{ height: isDesktop && columns.length > 0 ? `calc(${height}px - 3.6rem)` : '100%' }}
>
{table.getRowModel().rows.map(row => (
<div className='p2p-v2-table__content-row' key={row.id}>
{rowRender(row.original)}
</div>
))}
</div>
</div>
);
};
Expand Down
1 change: 1 addition & 0 deletions packages/p2p-v2/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export * from './PaymentMethodField';
export * from './PaymentMethodForm';
export * from './PaymentMethodsFormFooter';
export * from './PaymentMethodsHeader';
export * from './PopoverDropdown';
export * from './RadioGroup';
export * from './Search';
export * from './StarRating';
Expand Down
22 changes: 22 additions & 0 deletions packages/p2p-v2/src/constants/ad-constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export const COUNTERPARTIES_DROPDOWN_LIST = [
{ value: 'all', text: 'All' },
{ value: 'blocked', text: 'Blocked' },
];

export const RATE_TYPE = {
FLOAT: 'float',
FIXED: 'fixed',
};

export const AD_ACTION = {
EDIT: 'edit',
CREATE: 'create',
ACTIVATE: 'activate',
DEACTIVATE: 'deactivate',
DELETE: 'delete',
};

export const ADVERT_TYPE = {
SELL: 'Sell',
BUY: 'Buy',
};
4 changes: 0 additions & 4 deletions packages/p2p-v2/src/constants/counterparties-dropdown.ts

This file was deleted.

2 changes: 1 addition & 1 deletion packages/p2p-v2/src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export * from './counterparties-dropdown';
export * from './ad-constants';
export * from './payment-methods';
export * from './validation';
1 change: 1 addition & 0 deletions packages/p2p-v2/src/pages/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './my-ads';
export * from './my-profile';
38 changes: 38 additions & 0 deletions packages/p2p-v2/src/pages/my-ads/components/AdStatus/AdStatus.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@mixin ad-status-base($background-color) {
&:before {
content: '';
height: 100%;
width: 100%;
opacity: 0.16;
display: block;
position: absolute;
left: 0;
top: 0;
border-radius: 1.6rem;
background-color: $background-color;
}
align-items: center;
display: flex;
justify-content: center;
padding: 0.1rem 1.2rem;
position: relative;
}

.p2p-v2-ad-status {
&--active {
@include ad-status-base(var(--status-success));

width: fit-content;

@include mobile {
margin-bottom: 0.8rem;
padding: 0.2rem 1rem;
}
}

&--inactive {
@include ad-status-base(var(--status-danger));

width: fit-content;
}
}
29 changes: 29 additions & 0 deletions packages/p2p-v2/src/pages/my-ads/components/AdStatus/AdStatus.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import clsx from 'clsx';
import { Text } from '@deriv-com/ui';
import { useDevice } from '@/hooks';
import './AdStatus.scss';

type TAdStatusProps = {
isActive?: boolean;
};

const AdStatus = ({ isActive = false }: TAdStatusProps) => {
const { isMobile } = useDevice();
return (
<Text
align='center'
className={clsx({
'p2p-v2-ad-status--active': isActive,
'p2p-v2-ad-status--inactive': !isActive,
})}
color={isActive ? 'success' : 'error'}
size={isMobile ? 'md' : 'sm'}
weight='bold'
>
{isActive ? 'Active' : 'Inactive'}
</Text>
);
};

export default AdStatus;
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import AdStatus from '../AdStatus';

describe('AdStatus', () => {
it('should render the component as expected with Inactive as default', () => {
render(<AdStatus />);
expect(screen.getByText('Inactive')).toBeInTheDocument();
});
it('should render active when isActive is true', () => {
render(<AdStatus isActive={true} />);
expect(screen.getByText('Active')).toBeInTheDocument();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as AdStatus } from './AdStatus';
Loading

0 comments on commit 1779ab7

Please sign in to comment.