Merge pull request #143 from public-awesome/fix-disappearing-base-minter-list

UI Improvements
This commit is contained in:
Serkan Reis 2023-04-04 15:45:31 +03:00 committed by GitHub
commit 498c858c3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 403 additions and 169 deletions

View File

@ -1,4 +1,4 @@
APP_VERSION=0.5.5
APP_VERSION=0.5.6
NEXT_PUBLIC_PINATA_ENDPOINT_URL=https://api.pinata.cloud/pinning/pinFileToIPFS
NEXT_PUBLIC_SG721_CODE_ID=1911

View File

@ -22,6 +22,7 @@ export type BaseMinterAcquisitionMethod = 'existing' | 'new'
export interface MinterInfo {
name: string
minter: string
contractAddress: string
}
interface BaseMinterDetailsProps {
@ -32,6 +33,8 @@ interface BaseMinterDetailsProps {
export interface BaseMinterDetailsDataProps {
baseMinterAcquisitionMethod: BaseMinterAcquisitionMethod
existingBaseMinter: string | undefined
selectedCollectionAddress: string | undefined
collectionTokenCount: number | undefined
}
export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsProps) => {
@ -39,6 +42,8 @@ export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsPro
const [myBaseMinterContracts, setMyBaseMinterContracts] = useState<MinterInfo[]>([])
const [baseMinterAcquisitionMethod, setBaseMinterAcquisitionMethod] = useState<BaseMinterAcquisitionMethod>('new')
const [selectedCollectionAddress, setSelectedCollectionAddress] = useState<string | undefined>(undefined)
const [collectionTokenCount, setCollectionTokenCount] = useState<number | undefined>(undefined)
const existingBaseMinterState = useInputState({
id: 'existingMinter',
@ -54,7 +59,7 @@ export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsPro
.then((response) => {
const collectionData = response.data
const minterContracts = collectionData.map((collection: any) => {
return { name: collection.name, minter: collection.minter }
return { name: collection.name, minter: collection.minter, contractAddress: collection.contractAddress }
})
return minterContracts
})
@ -100,7 +105,7 @@ export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsPro
const debouncedMyBaseMinterContracts = useDebounce(myBaseMinterContracts, 500)
const renderBaseMinterContracts = useCallback(() => {
return myBaseMinterContracts.map((baseMinterContract, index) => {
return debouncedMyBaseMinterContracts.map((baseMinterContract, index) => {
return (
<option key={index} className="mt-2 text-lg bg-[#1A1A1A]">
{`${baseMinterContract.name} - ${baseMinterContract.minter}`}
@ -111,6 +116,8 @@ export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsPro
const debouncedWalletAddress = useDebounce(wallet.address, 300)
const debouncedExistingBaseMinterContract = useDebounce(existingBaseMinterState.value, 300)
const displayToast = async () => {
await toast.promise(filterBaseMinterContracts(), {
loading: 'Retrieving previous 1/1 collections...',
@ -119,6 +126,38 @@ export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsPro
})
}
const fetchSg721Address = async () => {
if (debouncedExistingBaseMinterContract.length === 0) return
await wallet.client
?.queryContractSmart(debouncedExistingBaseMinterContract, {
config: {},
})
.then((response) => {
console.log(response.collection_address)
setSelectedCollectionAddress(response.collection_address)
})
.catch((err) => {
console.log(err)
console.log('Unable to retrieve collection address')
})
}
const fetchCollectionTokenCount = async () => {
if (selectedCollectionAddress === undefined) return
await wallet.client
?.queryContractSmart(selectedCollectionAddress, {
num_tokens: {},
})
.then((response) => {
console.log(response)
setCollectionTokenCount(Number(response.count))
})
.catch((err) => {
console.log(err)
console.log('Unable to retrieve collection token count')
})
}
useEffect(() => {
if (debouncedWalletAddress && baseMinterAcquisitionMethod === 'existing') {
setMyBaseMinterContracts([])
@ -130,14 +169,34 @@ export const BaseMinterDetails = ({ onChange, minterType }: BaseMinterDetailsPro
}
}, [debouncedWalletAddress, baseMinterAcquisitionMethod])
useEffect(() => {
if (baseMinterAcquisitionMethod === 'existing') {
void fetchSg721Address()
}
}, [debouncedExistingBaseMinterContract])
useEffect(() => {
if (baseMinterAcquisitionMethod === 'existing') {
void fetchCollectionTokenCount()
}
}, [selectedCollectionAddress])
useEffect(() => {
const data: BaseMinterDetailsDataProps = {
baseMinterAcquisitionMethod,
existingBaseMinter: existingBaseMinterState.value,
selectedCollectionAddress,
collectionTokenCount,
}
onChange(data)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [existingBaseMinterState.value, baseMinterAcquisitionMethod, wallet.initialized])
}, [
existingBaseMinterState.value,
baseMinterAcquisitionMethod,
wallet.initialized,
selectedCollectionAddress,
collectionTokenCount,
])
return (
<div className="mx-10 mb-4 rounded border-2 border-white/20">

View File

@ -144,15 +144,93 @@ export const CollectionDetails = ({ onChange, uploadMethod, coverImageUrl, minte
<TextInput className="mt-2" {...symbolState} isRequired />
</div>
<div className={clsx(minterType === 'base' ? 'ml-10' : '')}>
<TextInput className="mt-2" {...externalLinkState} />
<FormControl
className={clsx(minterType === 'base' ? 'mt-12' : 'mt-2')}
htmlId="timestamp"
subtitle="Trading start time offset will be set as 2 weeks by default."
title="Trading Start Time (optional)"
>
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
</FormControl>
<TextInput className={clsx(minterType === 'base' ? 'mt-0' : 'mt-2')} {...externalLinkState} />
{/* Currently trading starts immediately for 1/1 Collections */}
<Conditional test={minterType !== 'base'}>
<FormControl
className={clsx(minterType === 'base' ? 'mt-10' : 'mt-2')}
htmlId="timestamp"
subtitle="Trading start time offset will be set as 2 weeks by default."
title="Trading Start Time (optional)"
>
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
</FormControl>
</Conditional>
<Conditional test={minterType === 'base'}>
<div
className={clsx(minterType === 'base' ? 'flex flex-col -ml-6 space-y-2' : 'flex flex-col space-y-2')}
>
<div>
<div className="flex mt-9 ml-6">
<span className="mt-1 ml-[2px] text-sm first-letter:capitalize">
Does the collection contain explicit content?
</span>
<div className="ml-2 font-bold form-check form-check-inline">
<input
checked={explicit}
className="peer sr-only"
id="explicitRadio1"
name="explicitRadioOptions1"
onClick={() => {
setExplicit(true)
}}
type="radio"
/>
<label
className="inline-block py-1 px-2 text-sm text-gray peer-checked:text-white hover:text-white peer-checked:bg-black hover:rounded-sm peer-checked:border-b-2 hover:border-b-2 peer-checked:border-plumbus hover:border-plumbus cursor-pointer form-check-label"
htmlFor="explicitRadio1"
>
YES
</label>
</div>
<div className="ml-2 font-bold form-check form-check-inline">
<input
checked={!explicit}
className="peer sr-only"
id="explicitRadio2"
name="explicitRadioOptions2"
onClick={() => {
setExplicit(false)
}}
type="radio"
/>
<label
className="inline-block py-1 px-2 text-sm text-gray peer-checked:text-white hover:text-white peer-checked:bg-black hover:rounded-sm peer-checked:border-b-2 hover:border-b-2 peer-checked:border-plumbus hover:border-plumbus cursor-pointer form-check-label"
htmlFor="explicitRadio2"
>
NO
</label>
</div>
</div>
</div>
</div>
<Conditional test={SG721_UPDATABLE_CODE_ID > 0}>
<Tooltip
backgroundColor="bg-blue-500"
label={
<div className="grid grid-flow-row">
<span>
When enabled, the metadata for tokens can be updated after the collection is created until
the collection is frozen by the creator.
</span>
</div>
}
placement="bottom"
>
<div className={clsx('flex flex-col mt-11 space-y-2 w-full form-control')}>
<label className="justify-start cursor-pointer label">
<span className="mr-4 font-bold">Updatable Token Metadata</span>
<input
checked={updatable}
className={`toggle ${updatable ? `bg-stargaze` : `bg-gray-600`}`}
onClick={() => setUpdatable(!updatable)}
type="checkbox"
/>
</label>
</div>
</Tooltip>
</Conditional>
</Conditional>
</div>
</div>
@ -200,82 +278,84 @@ export const CollectionDetails = ({ onChange, uploadMethod, coverImageUrl, minte
<span className="italic font-light ">Waiting for cover image URL to be specified.</span>
)}
</FormControl>
<div className={clsx(minterType === 'base' ? 'flex flex-col -ml-16 space-y-2' : 'flex flex-col space-y-2')}>
<div>
<div className="flex mt-4">
<span className="mt-1 ml-[2px] text-sm first-letter:capitalize">
Does the collection contain explicit content?
</span>
<div className="ml-2 font-bold form-check form-check-inline">
<input
checked={explicit}
className="peer sr-only"
id="explicitRadio1"
name="explicitRadioOptions1"
onClick={() => {
setExplicit(true)
}}
type="radio"
/>
<label
className="inline-block py-1 px-2 text-sm text-gray peer-checked:text-white hover:text-white peer-checked:bg-black hover:rounded-sm peer-checked:border-b-2 hover:border-b-2 peer-checked:border-plumbus hover:border-plumbus cursor-pointer form-check-label"
htmlFor="explicitRadio1"
>
YES
</label>
</div>
<div className="ml-2 font-bold form-check form-check-inline">
<input
checked={!explicit}
className="peer sr-only"
id="explicitRadio2"
name="explicitRadioOptions2"
onClick={() => {
setExplicit(false)
}}
type="radio"
/>
<label
className="inline-block py-1 px-2 text-sm text-gray peer-checked:text-white hover:text-white peer-checked:bg-black hover:rounded-sm peer-checked:border-b-2 hover:border-b-2 peer-checked:border-plumbus hover:border-plumbus cursor-pointer form-check-label"
htmlFor="explicitRadio2"
>
NO
</label>
<Conditional test={minterType !== 'base'}>
<div className={clsx(minterType === 'base' ? 'flex flex-col -ml-6 space-y-2' : 'flex flex-col space-y-2')}>
<div>
<div className="flex mt-4">
<span className="mt-1 ml-[2px] text-sm first-letter:capitalize">
Does the collection contain explicit content?
</span>
<div className="ml-2 font-bold form-check form-check-inline">
<input
checked={explicit}
className="peer sr-only"
id="explicitRadio1"
name="explicitRadioOptions1"
onClick={() => {
setExplicit(true)
}}
type="radio"
/>
<label
className="inline-block py-1 px-2 text-sm text-gray peer-checked:text-white hover:text-white peer-checked:bg-black hover:rounded-sm peer-checked:border-b-2 hover:border-b-2 peer-checked:border-plumbus hover:border-plumbus cursor-pointer form-check-label"
htmlFor="explicitRadio1"
>
YES
</label>
</div>
<div className="ml-2 font-bold form-check form-check-inline">
<input
checked={!explicit}
className="peer sr-only"
id="explicitRadio2"
name="explicitRadioOptions2"
onClick={() => {
setExplicit(false)
}}
type="radio"
/>
<label
className="inline-block py-1 px-2 text-sm text-gray peer-checked:text-white hover:text-white peer-checked:bg-black hover:rounded-sm peer-checked:border-b-2 hover:border-b-2 peer-checked:border-plumbus hover:border-plumbus cursor-pointer form-check-label"
htmlFor="explicitRadio2"
>
NO
</label>
</div>
</div>
</div>
</div>
</div>
<Conditional test={SG721_UPDATABLE_CODE_ID > 0}>
<Tooltip
backgroundColor="bg-blue-500"
label={
<div className="grid grid-flow-row">
<span>
When enabled, the metadata for tokens can be updated after the collection is created until the
collection is frozen by the creator.
</span>
</div>
}
placement="bottom"
>
<div
className={clsx(
minterType === 'base'
? 'flex flex-col -ml-16 space-y-2 w-1/2 form-control'
: 'flex flex-col space-y-2 w-3/4 form-control',
)}
<Conditional test={SG721_UPDATABLE_CODE_ID > 0}>
<Tooltip
backgroundColor="bg-blue-500"
label={
<div className="grid grid-flow-row">
<span>
When enabled, the metadata for tokens can be updated after the collection is created until the
collection is frozen by the creator.
</span>
</div>
}
placement="bottom"
>
<label className="justify-start cursor-pointer label">
<span className="mr-4 font-bold">Updatable Token Metadata</span>
<input
checked={updatable}
className={`toggle ${updatable ? `bg-stargaze` : `bg-gray-600`}`}
onClick={() => setUpdatable(!updatable)}
type="checkbox"
/>
</label>
</div>
</Tooltip>
<div
className={clsx(
minterType === 'base'
? 'flex flex-col -ml-16 space-y-2 w-1/2 form-control'
: 'flex flex-col space-y-2 w-3/4 form-control',
)}
>
<label className="justify-start cursor-pointer label">
<span className="mr-4 font-bold">Updatable Token Metadata</span>
<input
checked={updatable}
className={`toggle ${updatable ? `bg-stargaze` : `bg-gray-600`}`}
onClick={() => setUpdatable(!updatable)}
type="checkbox"
/>
</label>
</div>
</Tooltip>
</Conditional>
</Conditional>
</FormGroup>
</div>

View File

@ -105,7 +105,7 @@ export const MintingDetails = ({ onChange, numberOfTokens, uploadMethod }: Minti
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
</FormControl>
</FormGroup>
<TextInput className="p-4 mt-5" {...paymentAddressState} />
<TextInput className="p-4 mt-10" {...paymentAddressState} />
</div>
)
}

View File

@ -73,9 +73,9 @@ export function MetadataAttribute({ id, isLast, onAdd, onChange, onRemove, defau
}, [traitTypeState.value, traitValueState.value, id])
return (
<div className="grid relative 2xl:grid-cols-[1fr_1fr_auto] 2xl:space-x-2">
<TraitTypeInput {...traitTypeState} />
<TraitValueInput {...traitValueState} />
<div className="grid relative xl:grid-cols-[6fr_6fr_1fr] xl:-space-x-8 2xl:space-x-2">
<TraitTypeInput className="lg:w-4/5 2xl:w-full" {...traitTypeState} />
<TraitValueInput className="lg:w-4/5 xl:pr-2 xl:w-full" {...traitValueState} />
<div className="flex justify-end items-end pb-2 w-8">
<button

View File

@ -1,6 +1,6 @@
{
"name": "stargaze-studio",
"version": "0.5.5",
"version": "0.5.6",
"workspaces": [
"packages/*"
],

View File

@ -9,6 +9,7 @@ import { coin } from '@cosmjs/proto-signing'
import clsx from 'clsx'
import { Alert } from 'components/Alert'
import { Anchor } from 'components/Anchor'
import { AnchorButton } from 'components/AnchorButton'
import { Button } from 'components/Button'
import {
CollectionDetails,
@ -143,10 +144,7 @@ const CollectionCreationPage: NextPage = () => {
setReadyToCreateBm(true)
})
.catch((err) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
if (!err.message.includes('Insufficient wallet balance'))
toast.error(`Error in Whitelist Configuration: ${err.message}`, { style: { maxWidth: 'none' } })
else toast.error(`${err.message}`, { style: { maxWidth: 'none' } })
toast.error(`${err.message}`, { style: { maxWidth: 'none' } })
setReadyToCreateBm(false)
})
} catch (error: any) {
@ -164,7 +162,7 @@ const CollectionCreationPage: NextPage = () => {
setReadyToUploadAndMint(true)
})
.catch((err) => {
toast.error(`Error in Whitelist Configuration: ${err.message}`, { style: { maxWidth: 'none' } })
toast.error(`${err.message}`, { style: { maxWidth: 'none' } })
setReadyToUploadAndMint(false)
})
} catch (error: any) {
@ -300,12 +298,12 @@ const CollectionCreationPage: NextPage = () => {
if (!wallet.initialized) throw new Error('Wallet not connected')
if (!baseMinterContract) throw new Error('Contract not found')
setCreatingCollection(true)
setIsMintingComplete(false)
setBaseTokenUri(null)
setCoverImageUrl(null)
setVendingMinterContractAddress(null)
setSg721ContractAddress(null)
setTransactionHash(null)
if (uploadDetails?.uploadMethod === 'new') {
console.log(JSON.stringify(uploadDetails.baseMinterMetadataFile?.text()))
setUploading(true)
@ -333,7 +331,6 @@ const CollectionCreationPage: NextPage = () => {
return result
}
setBaseTokenUri(baseUri)
const result = await baseMinterContract
.use(baseMinterDetails?.existingBaseMinter as string)
?.batchMint(wallet.address, `ipfs://${baseUri}`, uploadDetails.assetFiles.length)
@ -346,6 +343,8 @@ const CollectionCreationPage: NextPage = () => {
duration: 5000,
})
setIsMintingComplete(true)
setSg721ContractAddress(baseMinterDetails?.selectedCollectionAddress as string)
setTransactionHash(result as string)
})
.catch((error) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
@ -364,6 +363,9 @@ const CollectionCreationPage: NextPage = () => {
style: { maxWidth: 'none' },
duration: 5000,
})
setIsMintingComplete(true)
setSg721ContractAddress(baseMinterDetails?.selectedCollectionAddress as string)
setTransactionHash(result)
})
.catch((error) => {
toast.error(error.message, { style: { maxWidth: 'none' } })
@ -504,7 +506,7 @@ const CollectionCreationPage: NextPage = () => {
external_link: collectionDetails?.externalLink,
explicit_content: collectionDetails?.explicit,
royalty_info: royaltyInfo,
start_trading_time: collectionDetails?.startTradingTime || null,
start_trading_time: null, //collectionDetails?.startTradingTime || null,
},
},
},
@ -936,8 +938,9 @@ const CollectionCreationPage: NextPage = () => {
}
}
useEffect(() => {
if (vendingMinterContractAddress !== null) scrollRef.current?.scrollIntoView({ behavior: 'smooth' })
}, [vendingMinterContractAddress])
if (vendingMinterContractAddress !== null || isMintingComplete)
scrollRef.current?.scrollIntoView({ behavior: 'smooth' })
}, [vendingMinterContractAddress, isMintingComplete])
useEffect(() => {
setBaseTokenUri(uploadDetails?.baseTokenURI as string)
@ -984,7 +987,7 @@ const CollectionCreationPage: NextPage = () => {
</p>
</div>
<div className="mx-10" ref={scrollRef}>
<Conditional test={vendingMinterContractAddress !== null}>
<Conditional test={vendingMinterContractAddress !== null || isMintingComplete}>
<Alert className="mt-5" type="info">
<div>
<Conditional test={minterType === 'vending' || isMintingComplete}>
@ -1010,80 +1013,145 @@ const CollectionCreationPage: NextPage = () => {
</Anchor>
)}
<br />
<Conditional test={vendingMinterContractAddress === null && isMintingComplete}>
Transaction Hash: {' '}
<Conditional test={NETWORK === 'testnet'}>
<Anchor
className="text-stargaze hover:underline"
external
href={`${BLOCK_EXPLORER_URL}/tx/${transactionHash as string}`}
>
{transactionHash}
</Anchor>
</Conditional>
<Conditional test={NETWORK === 'mainnet'}>
<Anchor
className="text-stargaze hover:underline"
external
href={`${BLOCK_EXPLORER_URL}/txs/${transactionHash as string}`}
>
{transactionHash}
</Anchor>
</Conditional>
<br />
Minter Contract Address:{' '}
<Anchor
className="text-stargaze hover:underline"
external
href={`/contracts/baseMinter/query/?contractAddress=${
baseMinterDetails?.existingBaseMinter as string
}`}
>
{baseMinterDetails?.existingBaseMinter as string}
</Anchor>
<br />
SG721 Contract Address:{' '}
<Anchor
className="text-stargaze hover:underline"
external
href={`/contracts/sg721/query/?contractAddress=${sg721ContractAddress as string}`}
>
{sg721ContractAddress}
</Anchor>
<br />
<div className="flex flex-row mt-2">
<AnchorButton className="text-white" external href={`${STARGAZE_URL}/profile/${wallet.address}`}>
Visit Your Profile
</AnchorButton>
<AnchorButton
className="ml-2 text-white"
external
href={`${STARGAZE_URL}/marketplace/${sg721ContractAddress as string}/${
baseMinterDetails?.collectionTokenCount
? (baseMinterDetails.collectionTokenCount + 1).toString()
: '1'
}`}
>
View the Token(s) on Marketplace
</AnchorButton>
</div>
</Conditional>
</Conditional>
Minter Contract Address:{' '}
<Anchor
className="text-stargaze hover:underline"
external
href={
minterType === 'vending'
? `/contracts/vendingMinter/query/?contractAddress=${vendingMinterContractAddress as string}`
: `/contracts/baseMinter/query/?contractAddress=${vendingMinterContractAddress as string}`
}
>
{vendingMinterContractAddress}
</Anchor>
<br />
SG721 Contract Address:{' '}
<Anchor
className="text-stargaze hover:underline"
external
href={`/contracts/sg721/query/?contractAddress=${sg721ContractAddress as string}`}
>
{sg721ContractAddress}
</Anchor>
<br />
<Conditional test={whitelistContractAddress !== null && whitelistContractAddress !== undefined}>
Whitelist Contract Address:{' '}
<Conditional test={vendingMinterContractAddress !== null}>
Minter Contract Address:{' '}
<Anchor
className="text-stargaze hover:underline"
external
href={`/contracts/whitelist/query/?contractAddress=${whitelistContractAddress as string}`}
href={
minterType === 'vending'
? `/contracts/vendingMinter/query/?contractAddress=${vendingMinterContractAddress as string}`
: `/contracts/baseMinter/query/?contractAddress=${vendingMinterContractAddress as string}`
}
>
{whitelistContractAddress}
{vendingMinterContractAddress}
</Anchor>
<br />
</Conditional>
Transaction Hash: {' '}
<Conditional test={NETWORK === 'testnet'}>
SG721 Contract Address:{' '}
<Anchor
className="text-stargaze hover:underline"
external
href={`${BLOCK_EXPLORER_URL}/tx/${transactionHash as string}`}
href={`/contracts/sg721/query/?contractAddress=${sg721ContractAddress as string}`}
>
{transactionHash}
{sg721ContractAddress}
</Anchor>
</Conditional>
<Conditional test={NETWORK === 'mainnet'}>
<Anchor
className="text-stargaze hover:underline"
external
href={`${BLOCK_EXPLORER_URL}/txs/${transactionHash as string}`}
>
{transactionHash}
</Anchor>
</Conditional>
<Conditional test={minterType === 'vending'}>
<Button className="mt-2">
<br />
<Conditional test={whitelistContractAddress !== null && whitelistContractAddress !== undefined}>
Whitelist Contract Address:{' '}
<Anchor
className="text-white"
className="text-stargaze hover:underline"
external
href={`${STARGAZE_URL}/launchpad/${vendingMinterContractAddress as string}`}
href={`/contracts/whitelist/query/?contractAddress=${whitelistContractAddress as string}`}
>
View on Launchpad
{whitelistContractAddress}
</Anchor>
</Button>
</Conditional>
<Conditional test={minterType === 'base'}>
<Button className="mt-2">
<br />
</Conditional>
Transaction Hash: {' '}
<Conditional test={NETWORK === 'testnet'}>
<Anchor
className="text-white"
className="text-stargaze hover:underline"
external
href={`${STARGAZE_URL}/marketplace/${sg721ContractAddress as string}?sort=price_asc`}
href={`${BLOCK_EXPLORER_URL}/tx/${transactionHash as string}`}
>
View on Marketplace
{transactionHash}
</Anchor>
</Button>
</Conditional>
<Conditional test={NETWORK === 'mainnet'}>
<Anchor
className="text-stargaze hover:underline"
external
href={`${BLOCK_EXPLORER_URL}/txs/${transactionHash as string}`}
>
{transactionHash}
</Anchor>
</Conditional>
<Conditional test={minterType === 'vending'}>
<Button className="mt-2">
<Anchor
className="text-white"
external
href={`${STARGAZE_URL}/launchpad/${vendingMinterContractAddress as string}`}
>
View on Launchpad
</Anchor>
</Button>
</Conditional>
<Conditional test={minterType === 'base'}>
<div className="flex flex-row mt-2">
<AnchorButton className="text-white" external href={`${STARGAZE_URL}/profile/${wallet.address}`}>
Visit Your Profile
</AnchorButton>
<AnchorButton
className="ml-2 text-white"
external
href={`${STARGAZE_URL}/marketplace/${sg721ContractAddress as string}${
!isMintingComplete ? `?sort=price_asc` : `/1`
}`}
>
View the Collection on Marketplace
</AnchorButton>
</div>
</Conditional>
</Conditional>
</div>
</Alert>

View File

@ -20,6 +20,7 @@ import { copy } from 'utils/clipboard'
import { API_URL, STARGAZE_URL } from 'utils/constants'
import { withMetadata } from 'utils/layout'
import { links } from 'utils/links'
import { truncateMiddle } from 'utils/text'
const CollectionList: NextPage = () => {
const wallet = useWallet()
@ -84,7 +85,9 @@ const CollectionList: NextPage = () => {
<div>
{myStandardCollections.length > 0 && (
<div className="bg-transparent">
<span className="text-2xl font-bold text-blue-300">Standard Collections</span>
<span className="ml-6 text-2xl font-bold text-blue-300 underline underline-offset-4">
Standard Collections
</span>
<table className="table w-full">
<thead>
<tr>
@ -97,7 +100,7 @@ const CollectionList: NextPage = () => {
{myStandardCollections.map((collection: any, index: any) => {
return (
<tr key={index}>
<td className="w-[55%] bg-black">
<td className="w-[40%] bg-black">
<div className="flex items-center space-x-3">
<div className="avatar">
<div className="w-28 h-28 mask mask-squircle">
@ -114,12 +117,16 @@ const CollectionList: NextPage = () => {
</div>
</div>
<div className="pl-2">
<p className="overflow-auto max-w-xs font-bold no-scrollbar ">{collection.name}</p>
<p className="max-w-xs text-sm truncate opacity-50">{collection.description}</p>
<p className="overflow-auto font-bold lg:max-w-[160px] xl:max-w-[220px] 2xl:max-w-xs no-scrollbar ">
{collection.name}
</p>
<p className="text-sm truncate opacity-50 lg:max-w-[160px] xl:max-w-[220px] 2xl:max-w-xs">
{collection.description}
</p>
</div>
</div>
</td>
<td className="w-[35%] bg-black">
<td className="w-[50%] bg-black">
<div className="flex flex-row items-center space-x-3">
Minter:
<span className="ml-2">
@ -132,7 +139,9 @@ const CollectionList: NextPage = () => {
onClick={() => void copy(collection.minter as string)}
type="button"
>
<span>{collection.minter}</span>
<span>
{truncateMiddle(collection.minter ? (collection.minter as string) : '', 36)}
</span>
<FaCopy className="opacity-0 group-hover:opacity-100" />
</button>
</Tooltip>
@ -147,7 +156,12 @@ const CollectionList: NextPage = () => {
onClick={() => void copy(collection.contractAddress as string)}
type="button"
>
<span>{collection.contractAddress}</span>
<span>
{truncateMiddle(
collection.contractAddress ? (collection.contractAddress as string) : '',
36,
)}
</span>
<FaCopy className="opacity-0 group-hover:opacity-100" />
</button>
</Tooltip>
@ -180,7 +194,9 @@ const CollectionList: NextPage = () => {
)}
{myOneOfOneCollections.length > 0 && (
<div className="mt-4">
<span className="text-2xl font-bold text-blue-300">1/1 Collections</span>
<span className="ml-6 text-2xl font-bold text-blue-300 underline underline-offset-4">
1/1 Collections
</span>
<table className="table w-full">
<thead>
<tr>
@ -193,7 +209,7 @@ const CollectionList: NextPage = () => {
{myOneOfOneCollections.map((collection: any, index: any) => {
return (
<tr key={index}>
<td className="w-[55%] bg-black">
<td className="w-[40%] bg-black">
<div className="flex items-center space-x-3">
<div className="avatar">
<div className="w-28 h-28 mask mask-squircle">
@ -210,12 +226,16 @@ const CollectionList: NextPage = () => {
</div>
</div>
<div className="pl-2">
<p className="overflow-auto max-w-xs font-bold no-scrollbar ">{collection.name}</p>
<p className="max-w-xs text-sm truncate opacity-50">{collection.description}</p>
<p className="overflow-auto font-bold lg:max-w-[160px] xl:max-w-[220px] 2xl:max-w-xs no-scrollbar ">
{collection.name}
</p>
<p className="text-sm truncate opacity-50 lg:max-w-[160px] xl:max-w-[220px] 2xl:max-w-xs">
{collection.description}
</p>
</div>
</div>
</td>
<td className="w-[35%] bg-black">
<td className="w-[50%] bg-black">
<div className="flex flex-row items-center space-x-3">
Minter:
<span className="ml-2">
@ -228,7 +248,9 @@ const CollectionList: NextPage = () => {
onClick={() => void copy(collection.minter as string)}
type="button"
>
<span>{collection.minter}</span>
<span>
{truncateMiddle(collection.minter ? (collection.minter as string) : '', 36)}
</span>
<FaCopy className="opacity-0 group-hover:opacity-100" />
</button>
</Tooltip>
@ -243,7 +265,12 @@ const CollectionList: NextPage = () => {
onClick={() => void copy(collection.contractAddress as string)}
type="button"
>
<span>{collection.contractAddress}</span>
<span>
{truncateMiddle(
collection.contractAddress ? (collection.contractAddress as string) : '',
36,
)}
</span>
<FaCopy className="opacity-0 group-hover:opacity-100" />
</button>
</Tooltip>