import Link from 'next/link' ; import Head from 'next/head' ; import { GetServerSideProps , NextPage } from "next" ; import layout from "../../styles/Layout.module.scss" ; import style from "../../styles/GenerativeTokenDetails.module.scss" ; import colors from "../../styles/Colors.module.css" ; import cs from "classnames" ; import client from "../../services/ApolloClient" ; import { Spacing } from '../../components/Layout/Spacing' ; import { UserBadge } from '../../components/User/UserBadge' ; import { Button } from '../../components/Button' ; import nl2br from 'react-nl2br' ; import { ipfsGatewayUrl } from '../../services/Ipfs' ; import { SectionHeader } from '../../components/Layout/SectionHeader' ; import { Activity } from '../../components/Activity/Activity' ; import { Objkt } from '../../types/entities/Objkt' ; import { User } from '../../types/entities/User' ; import { ClientOnlyEmpty } from '../../components/Utils/ClientOnly' ; import { UserGuard } from '../../components/Guards/UserGuard' ; import { OfferControl } from '../../containers/Objkt/OfferControl' ; import { Collect } from '../../containers/Objkt/Collect' ; import { truncateEnd } from '../../utils/strings' ; import { TitleHyphen } from '../../components/Layout/TitleHyphen' ; import { ArtworkIframe , ArtworkIframeRef } from '../../components/Artwork/PreviewIframe' ; import { useRef } from 'react' ; import { Features } from '../../components/Features/Features' ; import { format } from 'date-fns' ; import { displayPercentage , displayRoyalties } from '../../utils/units' ; import { Qu_objkt } from '../../queries/objkt' ; import { getGenerativeTokenMarketplaceUrl , getGenerativeTokenUrl } from '../../utils/generative-token' ; import { GenerativeFlagBanner } from '../../containers/Generative/FlagBanner' ; interface Props { objkt : Objkt ; } const ObjktDetails = ( { objkt } ) => { const owner = ( objkt . offer ? objkt . offer . issuer : objkt . owner ) ! ; const creator = objkt . issuer . author ; const displayUrl = objkt . metadata ?. displayUri && ipfsGatewayUrl ( objkt . metadata ?. displayUri ) ; const iframeRef = useRef < ArtworkIframeRef > ( null ) ; const reload = ( ) => { if ( iframeRef . current ) { iframeRef . current . reloadIframe ( ) ; } } ; return ( < > < Head > < title > fxhash — { objkt . name } < /title> < meta key = "og:title" property = "og:title" content = { `${ objkt . name } — fxhash` } />  < meta key = "description" name = "description" content = { truncateEnd ( objkt . metadata ?. description || "" , 200 , "" ) } / > < meta key = "og:description" property = "og:description" content = { truncateEnd ( objkt . metadata ?. description || "" , 200 , "" ) } / > < meta key = "og:type" property = "og:type" content = "website" / > < meta key = "og:image" property = "og:image" content = { displayUrl || "https://www.fxhash.xyz/images/og/og1.jpg" } /> < meta name = "twitter:site" content = "@fx_hash_" / > < meta name = "twitter:card" content = "summary_large_image" / > < meta name = "twitter:title" content = { `${ objkt . name } — fxhash` } /> < meta name = "twitter:description" content = { truncateEnd ( objkt . metadata ?. description || "" , 200 , "" ) } / > < meta name = "twitter:image" content = { displayUrl || "https://www.fxhash.xyz/images/og/og1.jpg" } /> < /Head> < GenerativeFlagBanner token = { objkt . issuer } / > < Spacing size = "6x-large" / > < section className = { cs ( layout . cols2 , layout [ 'responsive-reverse' ] , layout [ 'padding-big' ] ) } > < div className = { cs ( style [ 'presentation-details' ] ) } > < header > < small className = { cs ( colors . gray ) } > GENTK # { objkt . id } < /small> < h3 > { objkt . name } { objkt . assigned === false && ` - ${ objkt . issuer . name }` } < /h3> < Spacing size = "x-small" / > < UserBadge prependText = "created by" user = { creator } size = "big" / > < Spacing size = "2x-small" / > < UserBadge prependText = "owned by" user = { owner } size = "big" / > < /header> < Spacing size = "large" / > < p > { nl2br ( objkt . metadata ?. description ) } < /p> < Spacing size = "2x-large" / > < div className = { cs ( style [ 'artwork-details' ] ) } style = { { width : "100%" } } > < div className = { cs ( style . buttons ) } > { objkt . offer && ( < Collect offer = { objkt . offer } objkt = { objkt } / > ) } { } < ClientOnlyEmpty style = { { width : "100%" } } > < UserGuard forceRedirect = { false } > < > < OfferControl objkt = { objkt } /> < /> < /UserGuard> < /ClientOnlyEmpty> < Link href = { getGenerativeTokenUrl ( objkt . issuer ) } passHref > < Button isLink = { true } size = "small" > See Generative Token < /Button> < /Link> < Link href = { getGenerativeTokenMarketplaceUrl ( objkt . issuer ) } passHref > < Button isLink = { true } size = "small" > See Marketplace < /Button> < /Link> < /div> < /div> < /div> < div className = { cs ( style [ 'presentation-artwork' ] ) } > < div className = { cs ( style [ 'preview-container-auto' ] ) } > < div className = { cs ( style [ 'preview-wrapper' ] ) } > < ArtworkIframe ref = { iframeRef } url = { ipfsGatewayUrl ( objkt . metadata ?. artifactUri , "pinata-fxhash-safe" ) } / > < /div> < /div> < Spacing size = "8px" / > < div className = { cs ( layout [ 'x-inline' ] ) } > < Button size = "small" iconComp = { < i aria - hidden className = "fas fa-redo" / > } iconSide = "right" onClick = { reload } > reload < /Button> < Link href = { ipfsGatewayUrl ( objkt . metadata ?. artifactUri ) } passHref > < Button isLink = { true } size = "small" iconComp = { < i aria - hidden className = "fas fa-external-link-alt" > < /i>}  target = "_blank" > open live < /Button> < /Link> < /div> < /div> < /section> < Spacing size = "6x-large" / > < section > < SectionHeader > < TitleHyphen > gentk details < /TitleHyphen> < /SectionHeader> < main className = { cs ( layout [ 'padding-big' ] , layout . break_words ) } > < Spacing size = "small" / > < div className = { cs ( style . buttons ) } > < span > < strong > Minted the : < /strong> {format(new Date(objkt.createdAt), "dd/MM / yyyy ' at ' HH : mm ")}</span> < span > < strong > Royalties : < /strong> {displayRoyalties(objkt.royalties)}</span > < span > < strong > Metadata assigned : < /strong> {objkt.assigned ? "yes" : "no"}</span > < span > < strong > Transaction hash : < /strong> {objkt.generationHash}</span > < span > < strong > Iteration number : < /strong> {objkt.iteration}</span > { objkt . features && objkt . features . length > 0 && objkt . rarity && ( < span > < strong > Rarity : < /strong> {displayPercentage(objkt.rarity)}% (lower is rarer)</span > ) } < span > < strong > Metadata : < /strong> <a target="_blank" href={ipfsGatewayUrl(objkt.metadataUri, "pinata-fxhash")}>{objkt.metadataUri}</a > < /span> < /div> { objkt . features && objkt . features . length > 0 && ( < > < Spacing size = "x-large" / > < h4 > Features < /h4> < Spacing size = "small" / > < Features features = { objkt . features } /> < />)} < /main> < /section> < Spacing size = "6x-large" / > < Spacing size = "6x-large" / > < section > < SectionHeader > < TitleHyphen > activity ⚡ < /TitleHyphen> < /SectionHeader> < Spacing size = "3x-large" / > < main className = { cs ( layout [ 'padding-big' ] ) } > < div className = { cs ( style [ 'activity-wrapper' ] ) } > < Activity actions = { objkt . actions } className = { style . activity } / > < /div> < /main> < /section> < Spacing size = "6x-large" / > < Spacing size = "6x-large" / > < />); } ; export const getServerSideProps = async ( context ) => { let idStr , slug ; if ( context . params ?. params && context . params . params [ 0 ] ) { if ( context . params . params [ 0 ] === "slug" && context . params . params [ 1 ] ) { slug = context . params . params [ 1 ] ; } else if ( context . params . params [ 0 ] ) { idStr = context . params . params [ 0 ] ; } } let variables = { } , token = null ; if ( idStr ) { const id = parseInt ( idStr as string ) ; if ( id === 0 || id ) { variables . id = id ; } } else if ( slug ) { variables . slug = slug ; } if ( Object . keys ( variables ) . length > 0 ) { const { data } = await client . query ( { query : Qu_objkt , fetchPolicy : "no-cache" , variables } ) ; if ( data ) { token = data . objkt ; } } return { props : { objkt : token , } , notFound : ! token } ; } ; export default ObjktDetails ;