Merge pull request #209 from public-awesome/utc-option-for-time-input

Global time input switch (local vs. UTC)
This commit is contained in:
Serkan Reis 2023-09-04 10:40:30 +03:00 committed by GitHub
commit 5fc43159e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 618 additions and 48 deletions

View File

@ -1,4 +1,4 @@
APP_VERSION=0.7.4
APP_VERSION=0.7.5
NEXT_PUBLIC_PINATA_ENDPOINT_URL=https://api.pinata.cloud/pinning/pinFileToIPFS
NEXT_PUBLIC_SG721_CODE_ID=2595

View File

@ -0,0 +1,74 @@
import type { Timezone } from 'contexts/globalSettings'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useRef, useState } from 'react'
import { setTimezone } from '../contexts/globalSettings'
import { Button } from './Button'
export interface SettingsModalProps {
timezone?: Timezone
}
export const SettingsModal = (props: SettingsModalProps) => {
const globalSettings = useGlobalSettings()
const [isChecked, setIsChecked] = useState(false)
const checkBoxRef = useRef<HTMLInputElement>(null)
return (
<div>
<input className="modal-toggle" defaultChecked={false} id="my-modal-9" ref={checkBoxRef} type="checkbox" />
<label className="cursor-pointer modal" htmlFor="my-modal-9">
<label
className={`absolute top-[42%] bottom-5 left-[260px] max-w-[450px] max-h-[250px]
border-[1px] no-scrollbar modal-box`}
htmlFor="temp"
>
<div className="flex flex-col justify-between h-full">
<div className="flex flex-col">
<h1 className="text-2xl font-bold underline underline-offset-2">Settings</h1>
<div className="flex justify-start w-full">
<div className="flex-row mt-2 w-full form-control">
<h1 className="mt-[5px] text-lg font-bold">Time & Date: </h1>
<label className="justify-start ml-6 cursor-pointer label">
<span className="mr-2 font-bold">Local</span>
<input
checked={globalSettings.timezone === 'Local'}
className={`${globalSettings.timezone === 'Local' ? `bg-stargaze` : `bg-gray-600`} checkbox`}
onClick={() => {
setTimezone('Local' as Timezone)
window.localStorage.setItem('timezone', 'Local')
}}
type="checkbox"
/>
</label>
<label className="justify-start ml-4 cursor-pointer label">
<span className="mr-2 font-bold">UTC</span>
<input
checked={globalSettings.timezone === 'UTC'}
className={`${globalSettings.timezone === 'UTC' ? `bg-stargaze` : `bg-gray-600`} checkbox`}
onClick={() => {
setTimezone('UTC' as Timezone)
window.localStorage.setItem('timezone', 'UTC')
}}
type="checkbox"
/>
</label>
</div>
</div>
</div>
<Button
className="w-[40%] max-h-12 bg-blue-500 hover:bg-blue-600"
isWide
onClick={() => {
setTimezone('UTC' as Timezone)
window.localStorage.setItem('timezone', 'UTC')
}}
>
Use Defaults
</Button>
</div>
</label>
</label>
</div>
)
}

View File

@ -3,11 +3,14 @@
import clsx from 'clsx'
import { Anchor } from 'components/Anchor'
import type { Timezone } from 'contexts/globalSettings'
import { setTimezone } from 'contexts/globalSettings'
import { setLogItemList, useLogStore } from 'contexts/log'
import { useWallet } from 'contexts/wallet'
import Link from 'next/link'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { FaCog } from 'react-icons/fa'
// import BrandText from 'public/brand/brand-text.svg'
import { footerLinks, socialsLinks } from 'utils/links'
@ -15,6 +18,7 @@ import { BADGE_HUB_ADDRESS, BASE_FACTORY_ADDRESS, NETWORK, OPEN_EDITION_FACTORY_
import { Conditional } from './Conditional'
import { IncomeDashboardDisclaimer } from './IncomeDashboardDisclaimer'
import { LogModal } from './LogModal'
import { SettingsModal } from './SettingsModal'
import { SidebarLayout } from './SidebarLayout'
import { WalletLoader } from './WalletLoader'
@ -32,6 +36,11 @@ export const Sidebar = () => {
useEffect(() => {
console.log(window.localStorage.getItem('logs'))
setLogItemList(JSON.parse(window.localStorage.getItem('logs') || '[]'))
setTimezone(
(window.localStorage.getItem('timezone') as Timezone)
? (window.localStorage.getItem('timezone') as Timezone)
: 'UTC',
)
}, [])
return (
@ -231,16 +240,24 @@ export const Sidebar = () => {
<IncomeDashboardDisclaimer creatorAddress={wallet.address ? wallet.address : ''} />
<LogModal />
<SettingsModal />
<div className="flex-grow" />
{logs.itemList.length > 0 && (
<div className="flex-row w-full h-full">
<label
className="w-[65%] h-[4px] text-lg font-bold text-white normal-case bg-blue-500 hover:bg-blue-600 border-none animate-none btn modal-button"
className="absolute mb-8 w-[25%] text-lg font-bold text-white normal-case bg-zinc-500 hover:bg-zinc-600 border-none animate-none btn modal-button"
htmlFor="my-modal-9"
>
<FaCog className="justify-center align-bottom" size={20} />
</label>
<label
className="ml-16 w-[65%] text-lg font-bold text-white normal-case bg-blue-500 hover:bg-blue-600 border-none animate-none btn modal-button"
htmlFor="my-modal-8"
>
View Logs
</label>
)}
</div>
{/* Stargaze network status */}
<div className="text-sm capitalize">Network: {wallet.network}</div>

View File

@ -1,4 +1,5 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable no-nested-ternary */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
@ -10,6 +11,7 @@ import { FormControl } from 'components/FormControl'
import { useInputState, useNumberInputState } from 'components/forms/FormInput.hooks'
import { useMetadataAttributesState } from 'components/forms/MetadataAttributes.hooks'
import { InputDateTime } from 'components/InputDateTime'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { Trait } from 'contracts/badgeHub'
import type { ChangeEvent } from 'react'
@ -46,6 +48,7 @@ export interface BadgeDetailsDataProps {
export const BadgeDetails = ({ metadataSize, onChange, uploadMethod }: BadgeDetailsProps) => {
const wallet = useWallet()
const { timezone } = useGlobalSettings()
const [timestamp, setTimestamp] = useState<Date | undefined>(undefined)
const [transferrable, setTransferrable] = useState<boolean>(false)
const [metadataFile, setMetadataFile] = useState<File>()
@ -273,8 +276,29 @@ export const BadgeDetails = ({ metadataSize, onChange, uploadMethod }: BadgeDeta
{uploadMethod === 'existing' ? <TextInput className="mt-2" {...animationUrlState} /> : null}
<TextInput className="mt-2" {...externalUrlState} />
<FormControl className="mt-2" htmlId="expiry-date" subtitle="Badge minting expiry date" title="Expiry Date">
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<FormControl
className="mt-2"
htmlId="expiry-date"
subtitle={`Badge minting expiry date ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="Expiry Date"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
<div className="grid grid-cols-2">
<div className="mt-2 w-1/3 form-control">

View File

@ -1,3 +1,5 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable no-nested-ternary */
import { toUtf8 } from '@cosmjs/encoding'
import { AirdropUpload } from 'components/AirdropUpload'
import { Button } from 'components/Button'
@ -14,6 +16,7 @@ import { InputDateTime } from 'components/InputDateTime'
import { JsonPreview } from 'components/JsonPreview'
import { Tooltip } from 'components/Tooltip'
import { TransactionHash } from 'components/TransactionHash'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { BaseMinterInstance } from 'contracts/baseMinter'
import type { OpenEditionMinterInstance } from 'contracts/openEditionMinter'
@ -56,6 +59,7 @@ export const CollectionActions = ({
}: CollectionActionsProps) => {
const wallet = useWallet()
const [lastTx, setLastTx] = useState('')
const { timezone } = useGlobalSettings()
const [timestamp, setTimestamp] = useState<Date | undefined>(undefined)
const [endTimestamp, setEndTimestamp] = useState<Date | undefined>(undefined)
@ -501,13 +505,53 @@ export const CollectionActions = ({
</FormGroup>
)}
<Conditional test={showDateField}>
<FormControl className="mt-2" htmlId="start-date" title="Start Time">
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<FormControl
className="mt-2"
htmlId="start-date"
title={`Start Time ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</Conditional>
<Conditional test={showEndDateField}>
<FormControl className="mt-2" htmlId="end-date" title="End Time">
<InputDateTime minDate={new Date()} onChange={(date) => setEndTimestamp(date)} value={endTimestamp} />
<FormControl
className="mt-2"
htmlId="end-date"
title={`End Time ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setEndTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? endTimestamp
: endTimestamp
? new Date(endTimestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</Conditional>
<Conditional test={showBaseUriField}>

View File

@ -1,4 +1,5 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable no-nested-ternary */
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
@ -10,6 +11,7 @@ import { FormGroup } from 'components/FormGroup'
import { useInputState } from 'components/forms/FormInput.hooks'
import { InputDateTime } from 'components/InputDateTime'
import { Tooltip } from 'components/Tooltip'
import { useGlobalSettings } from 'contexts/globalSettings'
import { addLogItem } from 'contexts/log'
import type { ChangeEvent } from 'react'
import { useEffect, useRef, useState } from 'react'
@ -51,6 +53,7 @@ export const CollectionDetails = ({
const [timestamp, setTimestamp] = useState<Date | undefined>()
const [explicit, setExplicit] = useState<boolean>(false)
const [updatable, setUpdatable] = useState<boolean>(false)
const { timezone } = useGlobalSettings()
const initialRender = useRef(true)
@ -178,9 +181,29 @@ export const CollectionDetails = ({
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)"
title={`Trading Start Time (optional | ${timezone === 'Local' ? 'local)' : 'UTC)'}`}
>
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<InputDateTime
minDate={
timezone === 'Local'
? new Date()
: new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local'
? date
: new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</Conditional>
<Conditional test={minterType === 'base'}>

View File

@ -7,6 +7,7 @@ import { InputDateTime } from 'components/InputDateTime'
import { vendingMinterList } from 'config/minter'
import type { TokenInfo } from 'config/token'
import { stars, tokensList } from 'config/token'
import { useGlobalSettings } from 'contexts/globalSettings'
import React, { useEffect, useState } from 'react'
import { resolveAddress } from 'utils/resolveAddress'
@ -41,7 +42,7 @@ export const MintingDetails = ({
importedMintingDetails,
}: MintingDetailsProps) => {
const wallet = useWallet()
const { timezone } = useGlobalSettings()
const [timestamp, setTimestamp] = useState<Date | undefined>()
const [selectedMintToken, setSelectedMintToken] = useState<TokenInfo | undefined>(stars)
@ -103,6 +104,7 @@ export const MintingDetails = ({
paymentAddress: paymentAddressState.value.trim(),
selectedMintToken,
}
console.log('Timestamp:', timestamp?.getTime())
onChange(data)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
@ -154,8 +156,29 @@ export const MintingDetails = ({
</div>
<NumberInput {...perAddressLimitState} isRequired />
<FormControl htmlId="timestamp" isRequired subtitle="Minting start time (local)" title="Start Time">
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<FormControl
htmlId="timestamp"
isRequired
subtitle={`Minting start time ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="Start Time"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</FormGroup>
<TextInput className="p-4 mt-5" {...paymentAddressState} />

View File

@ -9,6 +9,7 @@ import { InputDateTime } from 'components/InputDateTime'
import type { WhitelistFlexMember } from 'components/WhitelistFlexUpload'
import { WhitelistFlexUpload } from 'components/WhitelistFlexUpload'
import type { TokenInfo } from 'config/token'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import React, { useEffect, useState } from 'react'
import { isValidAddress } from 'utils/isValidAddress'
@ -48,6 +49,7 @@ export const WhitelistDetails = ({
importedWhitelistDetails,
}: WhitelistDetailsProps) => {
const wallet = useWallet()
const { timezone } = useGlobalSettings()
const [whitelistState, setWhitelistState] = useState<WhitelistState>('none')
const [whitelistType, setWhitelistType] = useState<WhitelistType>('standard')
@ -329,17 +331,49 @@ export const WhitelistDetails = ({
htmlId="start-date"
isRequired
subtitle="Start time for minting tokens to whitelisted addresses"
title="Start Time"
title={`Start Time ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
>
<InputDateTime minDate={new Date()} onChange={(date) => setStartDate(date)} value={startDate} />
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setStartDate(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? startDate
: startDate
? new Date(startDate.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
<FormControl
htmlId="end-date"
isRequired
subtitle="End time for minting tokens to whitelisted addresses"
title="End Time"
title={`End Time ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
>
<InputDateTime minDate={new Date()} onChange={(date) => setEndDate(date)} value={endDate} />
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setEndDate(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? endDate
: endDate
? new Date(endDate.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</FormGroup>
<div>

View File

@ -1,4 +1,5 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable no-nested-ternary */
/* eslint-disable jsx-a11y/media-has-caption */
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
@ -11,6 +12,7 @@ import { FormGroup } from 'components/FormGroup'
import { useInputState } from 'components/forms/FormInput.hooks'
import { InputDateTime } from 'components/InputDateTime'
import { Tooltip } from 'components/Tooltip'
import { useGlobalSettings } from 'contexts/globalSettings'
import { addLogItem } from 'contexts/log'
import type { ChangeEvent } from 'react'
import { useEffect, useMemo, useRef, useState } from 'react'
@ -53,6 +55,7 @@ export const CollectionDetails = ({
const [timestamp, setTimestamp] = useState<Date | undefined>()
const [explicit, setExplicit] = useState<boolean>(false)
const [updatable, setUpdatable] = useState<boolean>(false)
const { timezone } = useGlobalSettings()
const initialRender = useRef(true)
@ -224,9 +227,25 @@ export const CollectionDetails = ({
className={clsx('mt-2')}
htmlId="timestamp"
subtitle="Trading start time offset will be set as 2 weeks by default."
title="Trading Start Time (optional)"
title={`Trading Start Time (optional | ${timezone === 'Local' ? 'local)' : 'UTC)'}`}
>
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</div>
</div>

View File

@ -7,6 +7,7 @@ import { InputDateTime } from 'components/InputDateTime'
import { openEditionMinterList } from 'config/minter'
import type { TokenInfo } from 'config/token'
import { stars, tokensList } from 'config/token'
import { useGlobalSettings } from 'contexts/globalSettings'
import React, { useEffect, useState } from 'react'
import { resolveAddress } from 'utils/resolveAddress'
@ -44,6 +45,7 @@ export const MintingDetails = ({
const [endTimestamp, setEndTimestamp] = useState<Date | undefined>()
const [selectedMintToken, setSelectedMintToken] = useState<TokenInfo | undefined>(stars)
const [mintingDetailsImported, setMintingDetailsImported] = useState(false)
const { timezone } = useGlobalSettings()
const unitPriceState = useNumberInputState({
id: 'unitPrice',
@ -142,11 +144,53 @@ export const MintingDetails = ({
</div>
<NumberInput {...perAddressLimitState} isRequired />
<FormControl htmlId="timestamp" isRequired subtitle="Minting start time (local)" title="Start Time">
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<FormControl
htmlId="timestamp"
isRequired
subtitle={`Minting start time ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="Start Time"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
<FormControl htmlId="endTimestamp" isRequired subtitle="Minting end time (local)" title="End Time">
<InputDateTime minDate={new Date()} onChange={(date) => setEndTimestamp(date)} value={endTimestamp} />
<FormControl
htmlId="endTimestamp"
isRequired
subtitle={`Minting end time ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="End Time"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setEndTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? endTimestamp
: endTimestamp
? new Date(endTimestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</FormGroup>
<TextInput className="pr-4 pl-4 mt-3" {...paymentAddressState} />

View File

@ -0,0 +1,11 @@
import create from 'zustand'
export type Timezone = 'UTC' | 'Local'
export const useGlobalSettings = create(() => ({
timezone: 'UTC' as Timezone,
}))
export const setTimezone = (timezone: Timezone) => {
useGlobalSettings.setState({ timezone })
}

View File

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

View File

@ -27,6 +27,7 @@ import { Tooltip } from 'components/Tooltip'
import { TransactionHash } from 'components/TransactionHash'
import { WhitelistUpload } from 'components/WhitelistUpload'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { Badge } from 'contracts/badgeHub'
import type { DispatchExecuteArgs } from 'contracts/badgeHub/messages/execute'
@ -63,6 +64,7 @@ const BadgeHubExecutePage: NextPage = () => {
const wallet = useWallet()
const [lastTx, setLastTx] = useState('')
const [badge, setBadge] = useState<Badge>()
const { timezone } = useGlobalSettings()
const [timestamp, setTimestamp] = useState<Date | undefined>(undefined)
const [transferrable, setTransferrable] = useState<boolean>(false)
@ -896,8 +898,32 @@ const BadgeHubExecutePage: NextPage = () => {
</FormControl>
<div className="pt-9">
<Conditional test={showBadgeField}>
<FormControl htmlId="expiry-date" subtitle="Badge minting expiry date" title="Expiry Date">
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<FormControl
htmlId="expiry-date"
subtitle={`Badge minting expiry date ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="Expiry Date"
>
<InputDateTime
minDate={
timezone === 'Local'
? new Date()
: new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local'
? date
: new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</Conditional>
{showBadgeField && <NumberInput className="mt-2" {...maxSupplyState} />}

View File

@ -12,6 +12,7 @@ import { LinkTabs } from 'components/LinkTabs'
import { baseMinterLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/baseMinter/messages/execute'
import { dispatchExecute, previewExecutePayload } from 'contracts/baseMinter/messages/execute'
@ -30,6 +31,7 @@ const BaseMinterExecutePage: NextPage = () => {
const { baseMinter: contract } = useContracts()
const wallet = useWallet()
const [lastTx, setLastTx] = useState('')
const { timezone } = useGlobalSettings()
const [timestamp, setTimestamp] = useState<Date | undefined>(undefined)
@ -119,8 +121,29 @@ const BaseMinterExecutePage: NextPage = () => {
<TextInput {...tokenUriState} />
</Conditional>
<Conditional test={showDateField}>
<FormControl htmlId="start-date" subtitle="Start time for trading." title="Trading Start Time">
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<FormControl
htmlId="start-date"
subtitle={`Start time for trading ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="Trading Start Time"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
// eslint-disable-next-line no-nested-ternary
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</Conditional>
</div>

View File

@ -1,3 +1,5 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable no-nested-ternary */
import { coin } from '@cosmjs/proto-signing'
import { Alert } from 'components/Alert'
import { Button } from 'components/Button'
@ -13,6 +15,7 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { baseMinterLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
@ -32,6 +35,7 @@ import { resolveAddress } from '../../../utils/resolveAddress'
const BaseMinterInstantiatePage: NextPage = () => {
const wallet = useWallet()
const contract = useContracts().baseFactory
const { timezone } = useGlobalSettings()
const [timestamp, setTimestamp] = useState<Date | undefined>()
const [explicit, setExplicit] = useState<boolean>(false)
@ -204,8 +208,28 @@ const BaseMinterInstantiatePage: NextPage = () => {
<FormTextArea isRequired {...descriptionState} />
<TextInput isRequired {...imageState} />
<TextInput {...externalLinkState} />
<FormControl htmlId="timestamp" subtitle="Trading start time (local)" title="Trading Start Time (optional)">
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<FormControl
htmlId="timestamp"
subtitle={`Trading start time ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="Trading Start Time (optional)"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
<div className="flex flex-col space-y-2">
<div>

View File

@ -1,3 +1,5 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable no-nested-ternary */
import { Button } from 'components/Button'
import { Conditional } from 'components/Conditional'
import { ContractPageHeader } from 'components/ContractPageHeader'
@ -12,6 +14,7 @@ import { LinkTabs } from 'components/LinkTabs'
import { openEditionMinterLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/openEditionMinter/messages/execute'
import { dispatchExecute, isEitherType, previewExecutePayload } from 'contracts/openEditionMinter/messages/execute'
@ -31,6 +34,7 @@ const OpenEditionMinterExecutePage: NextPage = () => {
const { openEditionMinter: contract } = useContracts()
const wallet = useWallet()
const [lastTx, setLastTx] = useState('')
const { timezone } = useGlobalSettings()
const [timestamp, setTimestamp] = useState<Date | undefined>(undefined)
const [endTimestamp, setEndTimestamp] = useState<Date | undefined>(undefined)
@ -218,13 +222,55 @@ const OpenEditionMinterExecutePage: NextPage = () => {
{showPriceField && <NumberInput {...priceState} />}
{/* TODO: Fix address execute message */}
<Conditional test={showDateField}>
<FormControl htmlId="start-date" subtitle="Start time for the minting" title="Start Time">
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<FormControl
htmlId="timestamp"
isRequired
subtitle={`Minting start time ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="Start Time"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</Conditional>
<Conditional test={showEndDateField}>
<FormControl htmlId="end-date" subtitle="End time for the minting" title="End Time">
<InputDateTime minDate={new Date()} onChange={(date) => setEndTimestamp(date)} value={endTimestamp} />
<FormControl
htmlId="endTimestamp"
isRequired
subtitle={`Minting end time ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="End Time"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setEndTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? endTimestamp
: endTimestamp
? new Date(endTimestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</Conditional>
</div>

View File

@ -1,3 +1,5 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable no-nested-ternary */
import { Button } from 'components/Button'
import { Conditional } from 'components/Conditional'
import { ContractPageHeader } from 'components/ContractPageHeader'
@ -12,6 +14,7 @@ import { LinkTabs } from 'components/LinkTabs'
import { vendingMinterLinkTabs } from 'components/LinkTabs.data'
import { TransactionHash } from 'components/TransactionHash'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/vendingMinter/messages/execute'
import { dispatchExecute, isEitherType, previewExecutePayload } from 'contracts/vendingMinter/messages/execute'
@ -31,6 +34,7 @@ const VendingMinterExecutePage: NextPage = () => {
const { vendingMinter: contract } = useContracts()
const wallet = useWallet()
const [lastTx, setLastTx] = useState('')
const { timezone } = useGlobalSettings()
const [timestamp, setTimestamp] = useState<Date | undefined>(undefined)
const [resolvedRecipientAddress, setResolvedRecipientAddress] = useState<string>('')
@ -228,8 +232,31 @@ const VendingMinterExecutePage: NextPage = () => {
{showPriceField && <NumberInput {...priceState} />}
{/* TODO: Fix address execute message */}
<Conditional test={showDateField}>
<FormControl htmlId="start-date" subtitle="Start time for the minting" title="Start Time">
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<FormControl
htmlId="timestamp"
isRequired
subtitle={`${type === 'update_start_time' ? 'Minting' : 'Trading'} start time ${
timezone === 'Local' ? '(local)' : '(UTC)'
}`}
title="Start Time"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</Conditional>
</div>

View File

@ -1,3 +1,5 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable no-nested-ternary */
import { coin } from '@cosmjs/proto-signing'
import { Alert } from 'components/Alert'
import { Button } from 'components/Button'
@ -13,6 +15,7 @@ import { JsonPreview } from 'components/JsonPreview'
import { LinkTabs } from 'components/LinkTabs'
import { vendingMinterLinkTabs } from 'components/LinkTabs.data'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { NextPage } from 'next'
import { NextSeo } from 'next-seo'
@ -31,6 +34,7 @@ import type { CreateVendingMinterResponse } from '../../../contracts/vendingFact
const VendingMinterInstantiatePage: NextPage = () => {
const wallet = useWallet()
const contract = useContracts().vendingFactory
const { timezone } = useGlobalSettings()
const [startDate, setStartDate] = useState<Date | undefined>(undefined)
const [timestamp, setTimestamp] = useState<Date | undefined>()
@ -267,8 +271,28 @@ const VendingMinterInstantiatePage: NextPage = () => {
<FormTextArea isRequired {...descriptionState} />
<TextInput isRequired {...imageState} />
<TextInput {...externalLinkState} />
<FormControl htmlId="timestamp" subtitle="Trading start time (local)" title="Trading Start Time (optional)">
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<FormControl
htmlId="start-date"
subtitle={`Start time for trading ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="Trading Start Time (optional)"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
<div className="flex flex-col space-y-2">
<div>
@ -327,8 +351,29 @@ const VendingMinterInstantiatePage: NextPage = () => {
<TextInput isRequired {...baseTokenUriState} />
<NumberInput isRequired {...tokenNumberState} />
<NumberInput isRequired {...perAddressLimitState} />
<FormControl htmlId="start-date" isRequired subtitle="Start time for the minting" title="Start Time">
<InputDateTime minDate={new Date()} onChange={(date) => setStartDate(date)} value={startDate} />
<FormControl
htmlId="start-date"
isRequired
subtitle={`Minting start time ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="Start Time"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setStartDate(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? startDate
: startDate
? new Date(startDate.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
<TextInput {...whitelistAddressState} />
</FormGroup>

View File

@ -23,6 +23,7 @@ import type { WhitelistFlexMember } from 'components/WhitelistFlexUpload'
import { WhitelistFlexUpload } from 'components/WhitelistFlexUpload'
import { WhitelistUpload } from 'components/WhitelistUpload'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { DispatchExecuteArgs } from 'contracts/whitelist/messages/execute'
import { dispatchExecute, isEitherType, previewExecutePayload } from 'contracts/whitelist/messages/execute'
@ -42,6 +43,7 @@ import { links } from 'utils/links'
const WhitelistExecutePage: NextPage = () => {
const { whitelist: contract } = useContracts()
const wallet = useWallet()
const { timezone } = useGlobalSettings()
const [lastTx, setLastTx] = useState('')
const [memberList, setMemberList] = useState<string[]>([])
@ -238,10 +240,28 @@ const WhitelistExecutePage: NextPage = () => {
<FormControl
htmlId="timestamp"
isRequired
subtitle={`${type === 'update_start_time' ? 'Start' : 'End'} time for the minting`}
subtitle={`${type === 'update_start_time' ? 'Start' : 'End'} time for minting ${
timezone === 'Local' ? '(local)' : '(UTC)'
}`}
title={`${type === 'update_start_time' ? 'Start' : 'End'} Time`}
>
<InputDateTime minDate={new Date()} onChange={(date) => setTimestamp(date)} value={timestamp} />
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setTimestamp(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? timestamp
: timestamp
? new Date(timestamp.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</Conditional>
<Conditional test={(whitelistType === 'standard' && showMemberList) || showAdminList || showRemoveMemberList}>

View File

@ -1,3 +1,5 @@
/* eslint-disable eslint-comments/disable-enable-pair */
/* eslint-disable no-nested-ternary */
import { coin } from '@cosmjs/proto-signing'
import { Alert } from 'components/Alert'
import { Button } from 'components/Button'
@ -16,6 +18,7 @@ import { whitelistLinkTabs } from 'components/LinkTabs.data'
import { type WhitelistFlexMember, WhitelistFlexUpload } from 'components/WhitelistFlexUpload'
import { WhitelistUpload } from 'components/WhitelistUpload'
import { useContracts } from 'contexts/contracts'
import { useGlobalSettings } from 'contexts/globalSettings'
import { useWallet } from 'contexts/wallet'
import type { InstantiateResponse } from 'contracts/sg721'
import type { NextPage } from 'next'
@ -33,6 +36,7 @@ import { WHITELIST_CODE_ID, WHITELIST_FLEX_CODE_ID } from '../../../utils/consta
const WhitelistInstantiatePage: NextPage = () => {
const wallet = useWallet()
const { whitelist: contract } = useContracts()
const { timezone } = useGlobalSettings()
const [startDate, setStartDate] = useState<Date | undefined>(undefined)
const [endDate, setEndDate] = useState<Date | undefined>(undefined)
@ -265,11 +269,53 @@ const WhitelistInstantiatePage: NextPage = () => {
<Conditional test={whitelistType === 'flex'}>
<NumberInput {...whaleCapState} />
</Conditional>
<FormControl htmlId="start-date" isRequired subtitle="Start time for the minting" title="Start Time">
<InputDateTime minDate={new Date()} onChange={(date) => setStartDate(date)} value={startDate} />
<FormControl
htmlId="start-date"
isRequired
subtitle={`Start time for minting ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="Start Time"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setStartDate(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? startDate
: startDate
? new Date(startDate.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
<FormControl htmlId="end-date" isRequired subtitle="End time for the minting" title="End Time">
<InputDateTime minDate={new Date()} onChange={(date) => setEndDate(date)} value={endDate} />
<FormControl
htmlId="end-date"
isRequired
subtitle={`End time for minting ${timezone === 'Local' ? '(local)' : '(UTC)'}`}
title="End Time"
>
<InputDateTime
minDate={
timezone === 'Local' ? new Date() : new Date(Date.now() + new Date().getTimezoneOffset() * 60 * 1000)
}
onChange={(date) =>
setEndDate(
timezone === 'Local' ? date : new Date(date.getTime() - new Date().getTimezoneOffset() * 60 * 1000),
)
}
value={
timezone === 'Local'
? endDate
: endDate
? new Date(endDate.getTime() + new Date().getTimezoneOffset() * 60 * 1000)
: undefined
}
/>
</FormControl>
</FormGroup>