import style from "./Action.module.scss" ; import effects from "../../styles/Effects.module.scss" ; import colors from "../../styles/Colors.module.css" ; import cs from "classnames" ; import { Action as ActionType } from "../../types/entities/Action" ; import { UserBadge } from "../User/UserBadge" ; import { FunctionComponent , useMemo } from "react" ; import { format , formatDistance , formatRelative , subDays } from 'date-fns' ; import { displayMutez , displayRoyalties } from "../../utils/units" ; import Link from "next/link" ; import { PropsWithChildren } from "react-router/node_modules/@types/react" ; interface Props { action : ActionType ; verbose : boolean ; } const getTokenIdx = ( name ) => '#' + name . split ( "#" ) . pop ( ) ; const DateDistance = ( { timestamptz , append = false } ) => { const dist = useMemo ( ( ) => formatDistance ( new Date ( timestamptz ) , new Date ( ) , { addSuffix : true } ) , [ ] ) ; return < span className = { cs ( style . date ) } > { dist } < /span>; } ; const ActionMinted = ( { action , verbose } ) => ( < > 🤖 < UserBadge className = { cs ( style . user ) } hasLink = { true } user = { ( action . issuer || action . target ) ! } size = "regular" / > < span > created { verbose ? ( < > generative < strong > { action . token ?. name } < /strong></ > ) : ( < strong > generative token < /strong>)} < /span> < DateDistance timestamptz = { action . createdAt } / > < />); const ActionMintedFrom = ( { action , verbose } ) => ( < > ✨ < UserBadge className = { cs ( style . user ) } hasLink = { true } user = { ( action . issuer || action . target ) ! } size = "regular" / > < span > minted { verbose ? ( < > token < strong > { action . objkt ?. name } < /strong></ > ) : ( < strong > token { getTokenIdx ( action . objkt ?. name ! ) } < /strong>)} < /span> < DateDistance timestamptz = { action . createdAt } / > < />); const ActionTransfered = ( { action , verbose } ) => ( < > ⬅ ️ < UserBadge className = { cs ( style . user ) } hasLink = { true } user = { ( action . issuer || action . target ) ! } size = "regular" / > < span > received { verbose ? ( < > token < strong > { action . objkt ?. name } < /strong></ > ) : ( < strong > token { getTokenIdx ( action . objkt ?. name ! ) } < /strong>)} < /span> < DateDistance timestamptz = { action . createdAt } / > < />); const ActionOffer = ( { action , verbose } ) => ( < > 🟢 < UserBadge className = { cs ( style . user ) } hasLink = { true } user = { ( action . issuer || action . target ) ! } size = "regular" / > < span > listed { verbose ? ( < > < strong > { action . objkt ?. name } < /strong></ > ) : ( < strong > token { getTokenIdx ( action . objkt ?. name ! ) } < /strong>)} for sale for < span className = { cs ( style . price ) } > { displayMutez ( action . metadata . price ) } tez < /span> < /span> < DateDistance timestamptz = { action . createdAt } append / > < />); const ActionOfferAccepted = ( { action } ) => ( < > 🔄 < UserBadge className = { cs ( style . user ) } hasLink = { true } user = { ( action . issuer || action . target ) ! } size = "regular" / > < span > sold < strong > token { getTokenIdx ( action . objkt ?. name ! ) } < /strong> for <span className={cs(style.price)}>{displayMutez(action.metadata.price)} tez</span > < /span> < DateDistance timestamptz = { action . createdAt } append / > < />); const ActionOfferCancelled = ( { action } ) => ( < > ⛔ < UserBadge className = { cs ( style . user ) } hasLink = { true } user = { ( action . issuer || action . target ) ! } size = "regular" / > < span > < strong className = { cs ( colors . error ) } > cancelled < /strong> their offer on <strong>token {getTokenIdx(action.objkt?.name!)}</strong > < /span> < DateDistance timestamptz = { action . createdAt } append / > < />); const ActionUpdateState = ( { action } ) => { const changes = action . metadata . changes ; return ( < > 🔵 < UserBadge className = { cs ( style . user ) } hasLink = { true } user = { ( action . issuer || action . target ) ! } size = "regular" / > < span > updated generative : { changes . enabled !== undefined && ( < > < strong className = { cs ( changes . enabled ? colors . success : colors . error ) } > { changes . enabled ? "enabled" : "disabled" } < /strong></ > ) } { changes . price !== undefined && ( < > < strong className = { cs ( style . price ) } > { displayMutez ( changes . price ) } tez < /strong>, </ > ) } { changes . royalties !== undefined && ( < > < strong className = { cs ( style . price ) } > { displayRoyalties ( changes . royalties ) } < /strong> royalties</ > ) } < /span> < DateDistance timestamptz = { action . createdAt } append / > < />); } ; const ActionBurnSupply = ( { action } ) => { const metadata = action . metadata ; return ( < > 🔥 < UserBadge className = { cs ( style . user ) } hasLink = { true } user = { ( action . issuer || action . target ) ! } size = "regular" / > < span > burnt some supply , < strong className = { cs ( colors . secondary ) } > { metadata . from } < /strong> -&#62; <strong className={cs(colors.secondary)}>{metadata.to}</strong > < /span> < DateDistance timestamptz = { action . createdAt } append / > < />); } ; const ActionCompleted = ( { action } ) => ( < > < span className = { cs ( style . align ) } > < strong className = { cs ( colors . success , style . align ) } > < i aria - hidden className = { cs ( style . icon , "fas" , "fa-check-circle" ) } / > completed < /strong>  — Generative Token fully minted < /span> < DateDistance timestamptz = { action . createdAt } append / > < />); const ActionMapComponent = { MINTED : ActionMinted , MINTED_FROM : ActionMintedFrom , TRANSFERED : ActionTransfered , OFFER : ActionOffer , OFFER_ACCEPTED : ActionOfferAccepted , OFFER_CANCELLED : ActionOfferCancelled , UPDATE_STATE : ActionUpdateState , BURN_SUPPLY : ActionBurnSupply , COMPLETED : ActionCompleted } ; const actionMapLink = { MINTED : ( action ) => `/generative/${ action . token ?. id }` , MINTED_FROM : ( action ) => `/gentk/${ action . objkt ?. id }` , TRANSFERED : ( action ) => `/gentk/${ action . objkt ?. id }` , OFFER : ( action ) => `/gentk/${ action . objkt ?. id }` , OFFER_ACCEPTED : ( action ) => `/gentk/${ action . objkt ?. id }` , OFFER_CANCELLED : ( action ) => `/gentk/${ action . objkt ?. id }` , UPDATE_STATE : ( action ) => `/gentk/${ action . objkt ?. id }` , BURN_SUPPLY : ( action ) => `/gentk/${ action . token ?. id }` , COMPLETED : ( action ) => `/generative/${ action . token ?. id }` , } ; function LinkWrapper ( { action , children } ) { const link = actionMapLink [ action . type ] && actionMapLink [ action . type ] ( action ) ; return link ? ( < article className = { cs ( style . container , style . is_link , effects [ 'drop-shadow-big' ] ) } > < Link href = { link } > < a className = { cs ( style . link_wrapper ) } /> < /Link> { children } < /article>) : (<article className={cs(style.container, effects['drop-shadow-big'])}>{children}</article > ) ; } export function Action ( { action , verbose } ) { const ActionComponent = ActionMapComponent [ action . type ] ; return ( < LinkWrapper action = { action } > < ActionComponent action = { action } verbose = { verbose } / > < /LinkWrapper>); }