Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eager-ants-laugh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@venusprotocol/evm": minor
---

add Markets tab to Dashboard page
46 changes: 46 additions & 0 deletions apps/evm/src/components/AdCarousel/Banner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { cn } from '@venusprotocol/ui';
import type { To } from 'react-router';

import { ButtonWrapper } from 'components';
import { Link } from 'containers/Link';

export interface BannerProps {
title: string;
description: string;
buttonLabel: string;
children?: React.ReactNode;
to?: To;
href?: string;
className?: string;
}

export const Banner: React.FC<BannerProps> = ({
className,
title,
description,
buttonLabel,
to,
href,
children,
}) => (
<div
className={cn(
'relative rounded-2xl overflow-hidden p-4 h-63 @min-[357px]:p-6 @min-[357px]:h-100 @min-[576px]:h-45 @min-[576px]:items-center @min-[1120px]:h-50',
className,
)}
>
<div className="absolute size-full inset-0">{children}</div>

<div className="relative max-w-64 @min-[357px]:max-w-86 @min-[357px]:pr-7 @min-[576px]:max-w-none">
<p className="text-p2s mb-2">{title}</p>

<p className="mb-3 text-light-grey @min-[357px]:mb-6 ">{description}</p>

<ButtonWrapper size="xs" asChild>
<Link to={to} href={href} noStyle>
{buttonLabel}
</Link>
</ButtonWrapper>
</div>
</div>
);
26 changes: 26 additions & 0 deletions apps/evm/src/components/AdCarousel/BoostBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { VENUS_DOC_URL } from 'constants/production';
import { useTranslation } from 'libs/translations';
import { Banner } from '../Banner';
import rocketIllustrationSrc from './rocket.png';

const LEARN_MORE_URL = `${VENUS_DOC_URL}/guides/leveraged-positions`;

export const BoostBanner: React.FC = () => {
const { t } = useTranslation();

return (
<Banner
title={t('adCarousel.boostBanner.title')}
description={t('adCarousel.boostBanner.description')}
buttonLabel={t('adCarousel.boostBanner.buttonLabel')}
className="bg-[linear-gradient(142deg,#00193A_20%,#0E3FB7_75%,#001E68_95%)]"
href={LEARN_MORE_URL}
>
<img
className="absolute size-112 max-w-none -bottom-45 -right-35 @min-[357px]:size-125 @min-[357px]:-bottom-33 @min-[357px]:right-auto @min-[357px]:-left-10 @min-[409px]:left-5 @min-[409px]:-bottom-44 @min-[576px]:h-119 @min-[576px]:-bottom-57 @min-[576px]:left-auto @min-[576px]:-right-12 @min-[896px]:size-160 @min-[896px]:rotate-12 @min-[896px]:-bottom-79 @min-[896px]:left-44 @min-[1120px]:size-194 @min-[1120px]:rotate-16 @min-[1120px]:-bottom-94 @min-[1120px]:left-80"
src={rocketIllustrationSrc}
alt={t('adCarousel.boostBanner.rocketIllustration.altText')}
/>
</Banner>
);
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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
@@ -0,0 +1,32 @@
import { VENUS_COMMUNITY_URL } from 'constants/production';
import { useTranslation } from 'libs/translations';
import { Banner } from '../Banner';
import backgroundIllustrationJpg from './background.jpg';
import coinsIllustrationSrc from './coins.png';

const LEARN_MORE_URL = `${VENUS_COMMUNITY_URL}/t/isolated-pools-sunset/5603`;

export const IsolatedPoolsSunsetBanner: React.FC = () => {
const { t } = useTranslation();

return (
<Banner
title={t('adCarousel.isolatedPoolsSunsetBanner.title')}
description={t('adCarousel.isolatedPoolsSunsetBanner.description')}
buttonLabel={t('adCarousel.isolatedPoolsSunsetBanner.buttonLabel')}
href={LEARN_MORE_URL}
>
<img
className="absolute max-w-none size-130 top-0 left-[50%] translate-x-[-50%] @min-[357px]:size-180 @min-[357px]:-top-20 @min-[576px]:top-[50%] @min-[576px]:translate-y-[-30%] @min-[576px]:size-[200%]"
src={backgroundIllustrationJpg}
alt={t('adCarousel.isolatedPoolsSunsetBanner.backgroundIllustration.altText')}
/>

<img
className="absolute max-w-none size-62 -bottom-18 -right-10 @min-[357px]:size-97 @min-[357px]:-bottom-20 @min-[357px]:-right-16 @min-[576px]:size-80 @min-[576px]:-bottom-20 @min-[576px]:right-auto @min-[576px]:left-75 @min-[686px]:size-88 @min-[686px]:left-auto @min-[686px]:right-5 @min-[896px]:size-116 @min-[896px]:-bottom-33"
src={coinsIllustrationSrc}
alt={t('adCarousel.isolatedPoolsSunsetBanner.coinsIllustration.altText')}
/>
</Banner>
);
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 32 additions & 0 deletions apps/evm/src/components/AdCarousel/ProbableBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useTranslation } from 'libs/translations';
import { Banner } from '../Banner';
import backgroundIllustrationJpg from './background.jpg';
import coinIllustrationSrc from './coin.png';

const LEARN_MORE_URL = 'https://probable.markets';

export const ProbableBanner: React.FC = () => {
const { t } = useTranslation();

return (
<Banner
title={t('adCarousel.probableBanner.title')}
description={t('adCarousel.probableBanner.description')}
buttonLabel={t('adCarousel.probableBanner.buttonLabel')}
className="bg-black"
href={LEARN_MORE_URL}
>
<img
className="absolute max-w-none left-[50%] top-[50%] translate-x-[-50%] translate-y-[-50%] size-full object-cover"
src={backgroundIllustrationJpg}
alt={t('adCarousel.probableBanner.backgroundIllustration.altText')}
/>

<img
className="absolute max-w-none w-55 bottom-0 -right-6 @min-[357px]:w-80 @min-[357px]:-right-11 @min-[576px]:w-57 @min-[576px]:right-2 @min-[896px]:right-30 @min-[1120px]:w-66 @min-[1120px]:right-10"
src={coinIllustrationSrc}
alt={t('adCarousel.probableBanner.coinIllustration.altText')}
/>
</Banner>
);
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions apps/evm/src/components/AdCarousel/VenusFluxBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { VENUS_FLUX_URL } from 'constants/production';
import { useTranslation } from 'libs/translations';
import { Banner } from '../Banner';
import backgroundIllustrationJpg from './background.jpg';
import venusFluxIconSrc from './venusFluxIcon.png';

export const VenusFluxBanner: React.FC = () => {
const { t } = useTranslation();

return (
<Banner
title={t('adCarousel.venusFluxBanner.title')}
description={t('adCarousel.venusFluxBanner.description')}
buttonLabel={t('adCarousel.venusFluxBanner.buttonLabel')}
className="bg-black"
href={VENUS_FLUX_URL}
>
<img
className="absolute max-w-none left-[50%] -top-17 translate-x-[-50%] size-160 object-contain @min-[576px]:w-[110%] @min-[576px]:h-auto @min-[576px]:top-[160%] @min-[576px]:translate-y-[-50%]"
src={backgroundIllustrationJpg}
alt={t('adCarousel.venusFluxBanner.backgroundIllustration.altText')}
/>

<img
className="absolute max-w-none size-31 bottom-6 right-8 @min-[357px]:size-42 @min-[409px]:bottom-12 @min-[576px]:bottom-7 @min-[576px]:size-32 @min-[576px]:right-12 @min-[1120px]:size-39 @min-[1120px]:bottom-6"
src={venusFluxIconSrc}
alt={t('adCarousel.venusFluxBanner.venusFluxIcon.altText')}
/>
</Banner>
);
};
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
@@ -0,0 +1,3 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`AdCarousel > displays correctly 1`] = `"Boost is available now!One-click leverage to boost your yield up to 5xLearn moreShare $1M in Venus Flux IncentivesLet your liquidity Flux, watch your yield grow.Start nowBelieve in something?Give your conviction a boost on probably.marketsStart nowIsolated pools are being sunsetClaim your rewards and close your positionsLearn more"`;
17 changes: 17 additions & 0 deletions apps/evm/src/components/AdCarousel/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { Mock } from 'vitest';

import { useIsFeatureEnabled } from 'hooks/useIsFeatureEnabled';
import { renderComponent } from 'testUtils/render';
import { AdCarousel } from '..';

describe('AdCarousel', () => {
beforeEach(() => {
(useIsFeatureEnabled as Mock).mockImplementation(() => true);
});

it('displays correctly', () => {
const { container } = renderComponent(<AdCarousel />);

expect(container.textContent).toMatchSnapshot();
});
});
35 changes: 35 additions & 0 deletions apps/evm/src/components/AdCarousel/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Carousel, CarouselItem } from 'components';
import { useIsFeatureEnabled } from 'hooks/useIsFeatureEnabled';
import { BoostBanner } from './BoostBanner';
import { IsolatedPoolsSunsetBanner } from './IsolatedPoolsSunsetBanner';
import { ProbableBanner } from './ProbableBanner';
import { VenusFluxBanner } from './VenusFluxBanner';

export const AdCarousel: React.FC = () => {
const isPrimeCalculatorFeatureEnabled = useIsFeatureEnabled({ name: 'primeCalculator' });

const slides: React.ReactNode[] = [];

if (isPrimeCalculatorFeatureEnabled) {
slides.push(
<BoostBanner />,
<VenusFluxBanner />,
<ProbableBanner />,
<IsolatedPoolsSunsetBanner />,
);
}

return (
<div className="relative @container/carousel">
<Carousel
autoPlay
className="rounded-2xl overflow-hidden"
trackerClassName="absolute bottom-4 left-4 @min-[357px]:left-6 @min-[357px]:bottom-6 @min-[409px]:bottom-12 @min-[576px]:left-auto @min-[576px]:right-8 @min-[576px]:bottom-7 @min-[1120px]:right-auto @min-[1120px]:left-6 @min-[1120px]:bottom-4"
>
{slides.map((slide, i) => (
<CarouselItem key={i}>{slide}</CarouselItem>
))}
</Carousel>
</div>
);
};
2 changes: 1 addition & 1 deletion apps/evm/src/components/Carousel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const Carousel = forwardRef<
key={i}
className={cn(
'size-1.5 rounded-full cursor-pointer',
i === activeSlideIndex ? 'bg-white' : 'bg-white/30',
i === activeSlideIndex ? 'bg-blue' : 'bg-white',
)}
/>
))}
Expand Down
19 changes: 19 additions & 0 deletions apps/evm/src/components/Icon/icons/crown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { SVGProps } from 'react';

const SvgCrown = (props: SVGProps<SVGSVGElement>) => (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M2.6991 3.86792L5.23576 6.09992L7.49576 3.31725C7.55905 3.23946 7.63907 3.17694 7.72986 3.13437C7.82065 3.09179 7.91989 3.07024 8.02016 3.07133C8.12044 3.07242 8.21918 3.09612 8.30903 3.14066C8.39888 3.1852 8.47752 3.24944 8.5391 3.32859L10.6958 6.09925L13.3144 3.83525C13.4173 3.74653 13.5447 3.69133 13.6798 3.67704C13.8149 3.66275 13.9511 3.69007 14.0702 3.75532C14.1893 3.82057 14.2857 3.92065 14.3464 4.04216C14.4071 4.16367 14.4292 4.30082 14.4098 4.43525L13.4098 11.3333H2.61443L1.5991 4.46659C1.57893 4.33141 1.60079 4.1933 1.66173 4.07096C1.72267 3.94863 1.81973 3.84798 1.93978 3.78264C2.05982 3.71731 2.19705 3.69045 2.33287 3.7057C2.46868 3.72096 2.59653 3.77759 2.6991 3.86792ZM2.66643 11.9999H13.3331V12.6666C13.3331 12.8434 13.2629 13.013 13.1378 13.138C13.0128 13.263 12.8432 13.3333 12.6664 13.3333H3.3331C3.15629 13.3333 2.98672 13.263 2.86169 13.138C2.73667 13.013 2.66643 12.8434 2.66643 12.6666V11.9999Z"
fill="currentColor"
/>
</svg>
);

export default SvgCrown;
37 changes: 37 additions & 0 deletions apps/evm/src/components/Icon/icons/graphOutline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import type { SVGProps } from 'react';

const SvgGraphOutline = (props: SVGProps<SVGSVGElement>) => (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<mask id="path-1-inside-1_1334_21006" fill="white">
<rect x="12" width="8" height="20" rx="1.49998" />
</mask>
<rect
x="12"
width="8"
height="20"
rx="1.49998"
stroke="currentColor"
stroke-width="4"
mask="url(#path-1-inside-1_1334_21006)"
/>
<path
d="M7.5 8H12.5C12.7761 8 13 8.22387 13 8.5V19H7.5C7.22387 19 7 18.7761 7 18.5V8.5C7 8.22387 7.22387 8 7.5 8Z"
stroke="currentColor"
stroke-width="2"
/>
<path
d="M1.5 14H6.5C6.77613 14 7 14.2239 7 14.5V19H1.5C1.22387 19 1 18.7761 1 18.5V14.5C1 14.2239 1.22387 14 1.5 14Z"
stroke="currentColor"
stroke-width="2"
/>
</svg>
);

export default SvgGraphOutline;
2 changes: 2 additions & 0 deletions apps/evm/src/components/Icon/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export { default as infinity } from './infinity';
export { default as shield2 } from './shield2';
export { default as lightning2 } from './lightning2';
export { default as graph } from './graph';
export { default as graphOutline } from './graphOutline';
export { default as star } from './star';
export { default as download } from './download';
export { default as arrowUpFull2 } from './arrowUpFull2';
Expand All @@ -85,3 +86,4 @@ export { default as closedEye } from './closedEye';
export { default as pending } from './pending';
export { default as innerArrows } from './innerArrows';
export { default as outerArrows } from './outerArrows';
export { default as crown } from './crown';
8 changes: 5 additions & 3 deletions apps/evm/src/components/Table/Head.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ function Head<R>({
controls,
}: HeadProps<R>) {
const styles = useStyles();

return (
<MuiTableHead>
<MuiTableRow className={className}>
{columns.map(column => {
const active = orderBy?.key === column.key;
const sortable = controls && !!column.sortRows;

return (
<MuiTableCell
Expand All @@ -41,17 +43,17 @@ function Head<R>({
align={column.align}
>
<MuiTableSortLabel
css={styles.tableSortLabel({ orderable: !!column.sortRows })}
css={styles.tableSortLabel({ sortable })}
active={active}
direction={active ? orderDirection : 'asc'}
onClick={column.sortRows ? () => onRequestOrder(column) : undefined}
onClick={sortable ? () => onRequestOrder(column) : undefined}
hideSortIcon={false}
// @ts-expect-error Override IconComponent with null so it doesn't render
IconComponent={null}
>
<span>{column.label}</span>

{controls && !!column.sortRows && (
{sortable && (
<div css={styles.tableSortLabelIconsContainer}>
<Icon
name="sort"
Expand Down
19 changes: 11 additions & 8 deletions apps/evm/src/components/Table/TableCards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,28 +81,31 @@ export function TableCards<R>({

{isFetching && <Spinner css={styles.loader} />}

<div className="space-y-6">
<div className="space-y-3">
{data.map((row, rowIndex) => {
const rowKey = rowKeyExtractor(row);
const content = (
<div className="space-y-6">
<div className="space-y-4">
<div>{titleColumn.renderCell(row, rowIndex)}</div>

<Delimiter className="my-4" />

{otherColumns.map(column => (
<LabeledInlineContent key={`${rowKey}-${column.key}`} label={column.label}>
<div className="text-right">{column.renderCell(row, rowIndex)}</div>
</LabeledInlineContent>
))}
<div className="space-y-6">
{otherColumns.map(column => (
<LabeledInlineContent key={`${rowKey}-${column.key}`} label={column.label}>
<div className="text-right inline-flex">{column.renderCell(row, rowIndex)}</div>
</LabeledInlineContent>
))}
</div>
</div>
);

return (
<Card
key={rowKey}
className={cn(
!!(rowOnClick || getRowHref) && 'cursor-pointer hover:bg-cards',
!!(rowOnClick || getRowHref) &&
'cursor-pointer hover:bg-dark-blue-hover active:bg-dark-blue-active',
cardClassName,
)}
onClick={rowOnClick && ((e: React.MouseEvent<HTMLDivElement>) => rowOnClick(e, row))}
Expand Down
Loading
Loading