diff --git a/minter/src/components/outfits.js b/minter/src/components/outfits.js index b18a335..5a855fa 100644 --- a/minter/src/components/outfits.js +++ b/minter/src/components/outfits.js @@ -2,24 +2,74 @@ import { Container, Loading } from './generic' import '../App.css' import { useState, useEffect } from 'react' -import { useRocketeers } from '../modules/api' +import { useRocketeers, callApi } from '../modules/api' +import { useChainId, useAddress, sign } from '../modules/web3' import { log } from '../modules/helpers' -import { useAddress } from '../modules/web3' +import { useParams, useNavigate } from 'react-router' export default function Verifier() { + const { rocketeerId } = useParams() + const navigate = useNavigate() + // /////////////////////////////// // State management // /////////////////////////////// const address = useAddress() const metamaskAddress = useAddress() const [ validatorAddress, setValidatorAddress ] = useState( ) - const rocketeers = useRocketeers() - const [ selectedId, setSelectedId ] = useState( ) + const rocketeers = useRocketeers( rocketeerId ) + const chainId = useChainId() const [ rocketeer, setRocketeer ] = useState( ) + const [ loading, setLoading ] = useState( ) + /* /////////////////////////////// + // Functions + // /////////////////////////////*/ + async function setPrimaryOutfit( outfitId ) { + + try { + + log( `Setting outfit ${ outfitId } for Rocketeer #${ rocketeerId }` ) + setLoading( `Setting outfit ${ outfitId } for Rocketeer #${ rocketeerId }` ) + alert( 'You will be prompted to sign a message, this is NOT a transaction' ) + + const signature = await sign( JSON.stringify( { + signer: address.toLowerCase(), + outfitId: outfitId, + chainId, + } ), address ) + + log( 'Making request with ', signature ) + + setLoading( 'Updating profile' ) + + const { error, success } = await callApi( `/rocketeer/${ rocketeerId }/outfits`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify( signature ) + } ) + + if( error ) throw new Error( error ) + + alert( `Success! Outfit changed, please click "refresh metadata" on Opensea to update it there.\nForwarding you to the tools homepage.` ) + navigate( `/` ) + + } catch( e ) { + + log( e ) + alert( e.message ) + + } finally { + + setLoading( false ) + + } + + } + // /////////////////////////////// // Lifecycle // /////////////////////////////// @@ -29,8 +79,10 @@ export default function Verifier() { useEffect( f => { - const selected = rocketeers.find( ( { id } ) => id === selectedId ) + // Find the data for the clicked Rocketeer + const selected = rocketeers.find( ( { id } ) => id === rocketeerId ) + // If the selected rocketeer is available, compute it's available outfits to an easy to access property if( selected ) { const { value: outfits } = selected.attributes.find( ( { trait_type } ) => trait_type === 'available outfits' ) || 0 selected.outfits = outfits @@ -38,15 +90,16 @@ export default function Verifier() { log( "Selecting rocketeer ", selected ) + // Set the selected rocketeer to state if( selected ) setRocketeer( selected ) - }, [ selectedId, rocketeers ] ) + }, [ rocketeerId, rocketeers ] ) // /////////////////////////////// // Rendering // /////////////////////////////// - if( !rocketeers.length ) return + if( !rocketeers.length || loading ) return // Rocketeer selector if(!rocketeer ) return 1 ? 'wide' : '' }> @@ -57,7 +110,7 @@ export default function Verifier() { { rocketeers.map( ( { id, image } ) => { - return setSelectedId( id ) } key={ id } className='rocketeer' src={ image } alt={ `Rocketeer number ${ id }` } /> + return navigate( `/outfits/${ id }` ) } key={ id } className='rocketeer' src={ image } alt={ `Rocketeer number ${ id }` } /> } ) } @@ -69,16 +122,18 @@ export default function Verifier() { // Changing room - if( rocketeer ) return 1 ? 'wide' : '' }> + if( rocketeer ) return 0 ? 'wide' : '' }> -

Changing room for Rocketeer { selectedId }

- window.location.href =`https://viewer.rocketeer.fans/?rocketeer=${ rocketeer.id }` } key={ rocketeer.id } className='rocketeer' src={ rocketeer.image } alt={ `Rocketeer number ${ rocketeer.id }` } /> -

This Rocketeer has { rocketeer.outfits } alternative outfits. { rocketeer.outfits > 0 && 'Click any outfit to select it as primary.' }

+

Changing room for Rocketeer { rocketeerId }

+ { +

This Rocketeer has { 1 + rocketeer.outfits } outfits. { rocketeer.outfits > 0 && 'Click any outfit to select it as primary.' }

+ + setPrimaryOutfit( 0 ) } className='rocketeer' src={ rocketeer.image } alt={ `Rocketeer number ${ rocketeer.id }` } /> { Array.from( Array( rocketeer.outfits ) ).map( ( val, i ) => { - return f } key={ rocketeer.id } className='rocketeer' src={ rocketeer.image.replace( '.jpg', `-${ i + 1 }.jpg` ) } alt={ `Rocketeer number ${ rocketeer.id }` } /> + return setPrimaryOutfit( i ) } key={ rocketeer.id + i } className='rocketeer' src={ rocketeer.image.replace( '.jpg', `-${ i + 1 }.jpg` ) } alt={ `Rocketeer number ${ rocketeer.id }` } /> } ) }
diff --git a/minter/src/components/router.js b/minter/src/components/router.js index 0ba6ddd..326d071 100644 --- a/minter/src/components/router.js +++ b/minter/src/components/router.js @@ -53,7 +53,9 @@ function Router() { } /> } /> - } /> + }> + } /> + diff --git a/minter/src/modules/api.js b/minter/src/modules/api.js index 14cff2b..618f84e 100644 --- a/minter/src/modules/api.js +++ b/minter/src/modules/api.js @@ -36,9 +36,10 @@ export function getImage( id, ext='jpg', network ) { } -export function useRocketeers() { +export function useRocketeers( onlyGrabThisId ) { - const ids = useTokenIds() + const tokenIds = useTokenIds() + const ids = onlyGrabThisId ? [ onlyGrabThisId ] : tokenIds const [ rocketeers, setRocketeers ] = useState( [] ) useEffect( f => { @@ -54,7 +55,7 @@ export function useRocketeers() { } )( ) - }, [ ids ] ) + }, [ tokenIds, onlyGrabThisId ] ) return rocketeers