Skip to content

Commit

Permalink
Use the MarketsHighlight component to highlight 3 markets and make la…
Browse files Browse the repository at this point in the history
…nding more interesting (#172)

* add highlight to 3 random markets

* make it more responsive

* track carousel open market

* fix types
  • Loading branch information
Diogomartf authored Feb 21, 2025
1 parent 70b65d2 commit 641e3ae
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 36 deletions.
1 change: 1 addition & 0 deletions analytics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const FA_EVENTS = {
},
},
MARKETS: {
CAROUSEL: 'click/markets/carousel',
CATEGORY: (category: string) => `click/markets/category-${category}`,
DETAILS: {
EMBED: {
Expand Down
55 changes: 21 additions & 34 deletions app/(main)/MarketsHighlight.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
'use client';

import { useQueries } from '@tanstack/react-query';
import Link from 'next/link';
import { FixedProductMarketMaker, getMarket } from '@/queries/omen';
import { OutcomeBar, TokenLogo } from '@/app/components';
import { FixedProductMarketMaker } from '@/queries/omen';
import { MarketThumbnail, OutcomeBar, TokenLogo } from '@/app/components';
import { formatEtherWithFixedDecimals, remainingTime } from '@/utils';
import {
Carousel,
Expand All @@ -14,28 +13,15 @@ import {
CarouselSelector,
} from '../components/Carousel';
import Autoplay from 'embla-carousel-autoplay';
import { highlightedMarketsList } from '@/market-highlight.config';
import defaultHighlightImage from '@/public/assets/highlights/default.png';
import Image from 'next/image';
import { useState } from 'react';
import { FA_EVENTS } from '@/analytics';
import { trackEvent } from 'fathom-client';

export const MarketsHighlight = () => {
const { data: markets, isLoading } = useQueries({
queries: Object.keys(highlightedMarketsList).map(id => ({
queryKey: ['getMarket', id],
queryFn: async () => getMarket({ id }),
})),
combine: results => {
return {
data: results
.map(result => result.data?.fixedProductMarketMaker)
.filter((market): market is FixedProductMarketMaker => !!market),
isLoading: results.some(result => result.isPending),
};
},
});
interface MarketsHighlightProps {
markets: FixedProductMarketMaker[];
}

if (markets.length === 0 || isLoading) return null;
export const MarketsHighlight = ({ markets }: MarketsHighlightProps) => {
const randomMarkets = markets.sort(() => 0.5 - Math.random()).slice(0, 3);

return (
<Carousel
Expand All @@ -47,13 +33,13 @@ export const MarketsHighlight = () => {
opts={{ loop: true }}
className="group relative mb-6 w-full"
>
<CarouselSelector className="absolute bottom-0 left-0 right-0 z-50 mx-auto mb-6" />
<div className="absolute bottom-0 right-0 z-50 mb-4 mr-6 flex space-x-2 opacity-0 transition duration-300 ease-in-out group-hover:opacity-100">
<CarouselSelector className="absolute bottom-3 left-0 right-0 z-50 mx-auto mb-6 md:bottom-0" />
<div className="absolute bottom-2 right-0 z-50 mb-4 mr-6 flex space-x-2 opacity-0 transition duration-300 ease-in-out group-hover:opacity-100">
<CarouselPrevious />
<CarouselNext />
</div>
<CarouselContent className="pb-2">
{markets.map(market => (
<CarouselContent className="relative pb-2">
{randomMarkets.map(market => (
<HighlightCarouselItem key={market.id} market={market} />
))}
</CarouselContent>
Expand All @@ -62,14 +48,14 @@ export const MarketsHighlight = () => {
};

const HighlightCarouselItem = ({ market }: { market: FixedProductMarketMaker }) => {
const [image, setImage] = useState(highlightedMarketsList[market.id].image);
const closingDate = new Date(+market.openingTimestamp * 1000);

return (
<CarouselItem key={market.id}>
<Link
onClick={() => trackEvent(FA_EVENTS.MARKETS.CAROUSEL)}
href={`/markets?id=${market.id}`}
className="flex h-auto min-h-[400px] w-full flex-col-reverse justify-between rounded-20 bg-surface-primary-main bg-gradient-to-b from-surface-surface-0 to-surface-surface-1 shadow-2 ring-1 ring-outline-base-em md:h-72 md:min-h-fit md:flex-row 2xl:h-96"
className="flex min-h-[600px] w-auto flex-col-reverse justify-between rounded-20 bg-surface-primary-main bg-gradient-to-b from-surface-surface-0 to-surface-surface-1 shadow-2 ring-1 ring-outline-base-em md:h-72 md:min-h-fit md:flex-row 2xl:h-96"
>
<div className="m-0 flex w-full max-w-2xl flex-col space-y-8 p-4 md:mx-6 md:my-8 md:mr-10 md:p-0 lg:mx-8 lg:mr-28">
<div className="flex flex-col space-y-4">
Expand All @@ -86,13 +72,14 @@ const HighlightCarouselItem = ({ market }: { market: FixedProductMarketMaker })
</p>
</div>
</div>
<Image
className="h-44 w-full rounded-e-0 rounded-t-20 md:h-full md:w-1/2 md:rounded-e-20 md:rounded-s-0 2xl:w-2/5"
src={image}
<MarketThumbnail
priority
alt="Market highlight"
width={200}
height={200}
className="h-full w-full rounded-e-0 rounded-t-20 bg-outline-primary-low-em md:w-1/2 md:rounded-e-20 md:rounded-s-0 2xl:w-2/5"
marketId={market.id}
style={{ objectFit: 'cover', objectPosition: 'top' }}
onError={() => setImage(defaultHighlightImage)}
alt="Market highlight"
/>
</Link>
</CarouselItem>
Expand Down
2 changes: 1 addition & 1 deletion app/(main)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ export default function HomePage() {

return (
<div className="mt-12 justify-center space-y-8 px-6 md:flex md:flex-col md:items-center md:px-10 lg:px-20 xl:px-40">
<MarketsHighlight />
<MarketsHighlight markets={markets ?? []} />
{openMarketsLoading ? (
<LoadingMarketCategories />
) : (
Expand Down
3 changes: 2 additions & 1 deletion app/components/MarketThumbnail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import request from 'graphql-request';

interface MarketThumbnailProps extends Omit<ImageProps, 'src' | 'alt'> {
marketId: string;
alt?: string;
}

type OmenThumbnailMapping = { omenThumbnailMapping: { image_hash: string } };
Expand Down Expand Up @@ -37,6 +38,6 @@ export const MarketThumbnail = ({ marketId, ...props }: MarketThumbnailProps) =>

if (!ipfsHash) return null;
return (
<Image {...props} src={`https://ipfs.io/ipfs/${ipfsHash}`} alt="Thumbnail image" />
<Image src={`https://ipfs.io/ipfs/${ipfsHash}`} alt="Thumbnail image" {...props} />
);
};

0 comments on commit 641e3ae

Please sign in to comment.