Created
October 26, 2022 13:49
-
-
Save JWPapi/9f0a4c0f677e2712e6949e336174603d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Image from "next/image"; | |
import useSWR from "swr"; | |
import {useInView} from "react-intersection-observer"; | |
const fetcher = (url) => fetch(url).then((res) => res.json()) | |
export default function Collection({name, items, slug}) { | |
const {ref, inView} = useInView({ | |
rootMargin: '500px', | |
triggerOnce: true, | |
}); | |
const {data} = useSWR(() => inView && slug ? `https://api.opensea.io/api/v1/collection/${slug}/stats` : null, fetcher) | |
return ( | |
<div className="mb-8 card bg-base-300 p-4 shadow-xl" ref={ref}> | |
<a href={'https://opensea.io/collection/' + slug} target="_blank" rel="noreferrer" className="cursor-pointer"> | |
<h2 className="text-xl text-left text-primary mb-4"> {name}</h2> | |
</a> | |
<div className={"md:grid grid-cols-2"}> | |
<div className="flex flex-col"> | |
{items?.map((item) => <Item key={item.id} {...item} collectionSlug={slug}/>)} | |
</div> | |
{data && slug && <Stats stats={data.stats}/>} | |
</div> | |
</div>) | |
} | |
const Item = ({name, imageUrl, series, mintCount,collectionSlug}) => { | |
return ( | |
<a href={openSeaSearchUrl(name,collectionSlug )} target="_blank" id={name} rel="noreferrer" | |
className="cursor-pointer block m-2"> | |
<div className="bg-transparent flex flex-row"> | |
<Image src={imageUrl} alt={name} layout="fixed" width={64} height={85}/> | |
<div className="p-2 items-center text-left rounded-xl mt-1 "> | |
<h2 className="card-title text-md">{name} </h2> | |
{mintCount && <div className="mx-auto">{mintCount} / {series}</div>} | |
{!mintCount && <p>Series of {series}</p>} | |
</div> | |
</div> | |
</a> | |
) | |
} | |
const Stat = ({title, value, description}) => { | |
return (<div className="stat border-none text-center"> | |
<div className="stat-title">{title}</div> | |
<div className="stat-value text-lg text-primary ">{value}</div> | |
<div className="stat-description text-sm">{description}</div> | |
</div>) | |
} | |
const Stats = ({stats}) => { | |
const format = { | |
eth: (value) => Math.round(value * 100) / 100 + ' ETH', | |
pc: (value, trend) => (trend ? (value > 0 ? '📈' : '📉') : '') + Math.round(value * 100) + '%', | |
volume: (title, value, description) => ({ | |
title, | |
value: format.eth(value), | |
description: format.pc(description, true) | |
}) | |
} | |
return ( | |
<div className="grid grid-cols-2 gap-2 "> | |
<div className="stats stats-vertical bg-transparent"> | |
<Stat {...format.volume('1d Volume', stats.one_day_volume, stats.one_day_change)} /> | |
<Stat {...format.volume('7d Volume', stats.seven_day_volume, stats.seven_day_change)}/> | |
</div> | |
<div className="stats stats-vertical bg-transparent"> | |
<Stat | |
title='Unique Owners' | |
value={format.pc(stats.num_owners / stats.total_supply)} | |
description={stats.total_supply + ' Supply'} | |
/> | |
<Stat title="Floor Price" value={format.eth(stats.floor_price)} | |
description={format.eth(stats.market_cap)}/> | |
</div> | |
</div>) | |
} | |
const openSeaSearchUrl = (name, collectionSlug) => { | |
return 'https://opensea.io/assets?search[collections][0]=' | |
+ collectionSlug | |
+ '&search[query]=' | |
+ name | |
+ '&search[resultModel]=ASSETS&search[sortAscending]=true&search[sortBy]=UNIT_PRICE' | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment