diff --git a/components/openEdition/MintingDetails.tsx b/components/openEdition/MintingDetails.tsx index a707321..7ccded2 100644 --- a/components/openEdition/MintingDetails.tsx +++ b/components/openEdition/MintingDetails.tsx @@ -1,6 +1,7 @@ /* eslint-disable eslint-comments/disable-enable-pair */ /* eslint-disable @typescript-eslint/no-unnecessary-condition */ /* eslint-disable no-nested-ternary */ +import { Conditional } from 'components/Conditional' import { FormControl } from 'components/FormControl' import { FormGroup } from 'components/FormGroup' import { useInputState, useNumberInputState } from 'components/forms/FormInput.hooks' @@ -16,6 +17,8 @@ import { useWallet } from 'utils/wallet' import { NumberInput, TextInput } from '../forms/FormInput' import type { UploadMethod } from './OffChainMetadataUploadDetails' +export type LimitType = 'count_limited' | 'time_limited' + interface MintingDetailsProps { onChange: (data: MintingDetailsDataProps) => void uploadMethod: UploadMethod @@ -28,9 +31,11 @@ export interface MintingDetailsDataProps { unitPrice: string perAddressLimit: number startTime: string - endTime: string + endTime?: string + tokenCountLimit?: number paymentAddress?: string selectedMintToken?: TokenInfo + limitType: LimitType } export const MintingDetails = ({ @@ -46,6 +51,7 @@ export const MintingDetails = ({ const [endTimestamp, setEndTimestamp] = useState() const [selectedMintToken, setSelectedMintToken] = useState(stars) const [mintingDetailsImported, setMintingDetailsImported] = useState(false) + const [limitType, setLimitType] = useState('time_limited') const { timezone } = useGlobalSettings() const unitPriceState = useNumberInputState({ @@ -66,6 +72,14 @@ export const MintingDetails = ({ placeholder: '1', }) + const tokenCountLimitState = useNumberInputState({ + id: 'tokencountlimit', + name: 'tokencountlimit', + title: 'Maximum Token Count', + subtitle: 'Total number of mintable tokens', + placeholder: '100', + }) + const paymentAddressState = useInputState({ id: 'payment-address', name: 'paymentAddress', @@ -98,6 +112,8 @@ export const MintingDetails = ({ endTime: endTimestamp ? (endTimestamp.getTime() * 1_000_000).toString() : '', paymentAddress: paymentAddressState.value.trim(), selectedMintToken, + limitType, + tokenCountLimit: limitType === 'count_limited' ? tokenCountLimitState.value : undefined, } onChange(data) // eslint-disable-next-line react-hooks/exhaustive-deps @@ -108,6 +124,8 @@ export const MintingDetails = ({ endTimestamp, paymentAddressState.value, selectedMintToken, + tokenCountLimitState.value, + limitType, ]) useEffect(() => { @@ -115,6 +133,8 @@ export const MintingDetails = ({ console.log('Selected Token ID: ', importedMintingDetails.selectedMintToken?.id) unitPriceState.onChange(Number(importedMintingDetails.unitPrice) / 1000000) perAddressLimitState.onChange(importedMintingDetails.perAddressLimit) + setLimitType(importedMintingDetails.limitType) + tokenCountLimitState.onChange(importedMintingDetails.tokenCountLimit ? importedMintingDetails.tokenCountLimit : 0) setTimestamp(new Date(Number(importedMintingDetails.startTime) / 1_000_000)) setEndTimestamp(new Date(Number(importedMintingDetails.endTime) / 1_000_000)) paymentAddressState.onChange(importedMintingDetails.paymentAddress ? importedMintingDetails.paymentAddress : '') @@ -171,32 +191,65 @@ export const MintingDetails = ({ } /> - - - date - ? setEndTimestamp( - timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000), - ) - : setEndTimestamp(undefined) - } - value={ - timezone === 'Local' - ? endTimestamp - : endTimestamp - ? new Date(endTimestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000) - : undefined - } - /> - + +
+

Limit Type:

+ + +
+ + + + date + ? setEndTimestamp( + timezone === 'Local' + ? date + : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000), + ) + : setEndTimestamp(undefined) + } + value={ + timezone === 'Local' + ? endTimestamp + : endTimestamp + ? new Date(endTimestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000) + : undefined + } + /> + + + + + diff --git a/components/openEdition/OpenEditionMinterCreator.tsx b/components/openEdition/OpenEditionMinterCreator.tsx index 8368833..a24449d 100644 --- a/components/openEdition/OpenEditionMinterCreator.tsx +++ b/components/openEdition/OpenEditionMinterCreator.tsx @@ -37,7 +37,7 @@ import { useWallet } from 'utils/wallet' import { type CollectionDetailsDataProps, CollectionDetails } from './CollectionDetails' import type { ImageUploadDetailsDataProps } from './ImageUploadDetails' import { ImageUploadDetails } from './ImageUploadDetails' -import type { MintingDetailsDataProps } from './MintingDetails' +import type { LimitType, MintingDetailsDataProps } from './MintingDetails' import { MintingDetails } from './MintingDetails' import type { UploadMethod } from './OffChainMetadataUploadDetails' import { @@ -314,11 +314,27 @@ export const OpenEditionMinterCreator = ({ if (!mintingDetails.perAddressLimit || mintingDetails.perAddressLimit < 1 || mintingDetails.perAddressLimit > 50) throw new Error('Invalid limit for tokens per address') if (mintingDetails.startTime === '') throw new Error('Start time is required') - if (mintingDetails.endTime === '') throw new Error('End time is required') + if (mintingDetails.limitType === 'time_limited' && mintingDetails.endTime === '') + throw new Error('End time is required') + if (mintingDetails.limitType === 'count_limited' && mintingDetails.tokenCountLimit === undefined) + throw new Error('Token count limit is required') + if ( + mintingDetails.limitType === 'count_limited' && + mintingDetails.perAddressLimit > (mintingDetails.tokenCountLimit as number) + ) + throw new Error('Per address limit cannot exceed maximum token count limit') + if (mintingDetails.limitType === 'count_limited' && (mintingDetails.tokenCountLimit as number) > 10000) + throw new Error('Maximum token count cannot exceed 10000') if (Number(mintingDetails.startTime) < new Date().getTime() * 1000000) throw new Error('Invalid start time') - if (Number(mintingDetails.endTime) < Number(mintingDetails.startTime)) + if ( + mintingDetails.limitType === 'time_limited' && + Number(mintingDetails.endTime) < Number(mintingDetails.startTime) + ) throw new Error('End time cannot be earlier than start time') - if (Number(mintingDetails.endTime) === Number(mintingDetails.startTime)) + if ( + mintingDetails.limitType === 'time_limited' && + Number(mintingDetails.endTime) === Number(mintingDetails.startTime) + ) throw new Error('End time cannot be equal to the start time') if ( @@ -603,12 +619,14 @@ export const OpenEditionMinterCreator = ({ : null, }, start_time: mintingDetails?.startTime, - end_time: mintingDetails?.endTime, + end_time: mintingDetails?.limitType === ('time_limited' as LimitType) ? mintingDetails.endTime : null, mint_price: { amount: Number(mintingDetails?.unitPrice).toString(), denom: (mintTokenFromFactory?.denom as string) || 'ustars', }, per_address_limit: mintingDetails?.perAddressLimit, + num_tokens: + mintingDetails?.limitType === ('count_limited' as LimitType) ? mintingDetails.tokenCountLimit : null, payment_address: mintingDetails?.paymentAddress || null, }, collection_params: {