mirror of https://github.com/certusone/oyster.git
Auction creation steps (#82)
* torus context * bye torus as context * torus mess * price step * initial phase * end phase * review step
This commit is contained in:
parent
4c6c1ad934
commit
2b6a4b5016
|
@ -1,5 +1,6 @@
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import {
|
import {
|
||||||
|
Divider,
|
||||||
Steps,
|
Steps,
|
||||||
Row,
|
Row,
|
||||||
Button,
|
Button,
|
||||||
|
@ -14,6 +15,7 @@ import {
|
||||||
Select,
|
Select,
|
||||||
TimePicker,
|
TimePicker,
|
||||||
DatePicker,
|
DatePicker,
|
||||||
|
Radio,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { ArtCard } from './../../components/ArtCard';
|
import { ArtCard } from './../../components/ArtCard';
|
||||||
import { UserSearch, UserValue } from './../../components/UserSearch';
|
import { UserSearch, UserValue } from './../../components/UserSearch';
|
||||||
|
@ -43,9 +45,9 @@ const { Dragger } = Upload;
|
||||||
|
|
||||||
export enum AuctionCategory {
|
export enum AuctionCategory {
|
||||||
Limited,
|
Limited,
|
||||||
|
Single,
|
||||||
Open,
|
Open,
|
||||||
Tiered,
|
Tiered,
|
||||||
Single,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AuctionState {
|
export interface AuctionState {
|
||||||
|
@ -68,6 +70,10 @@ export interface AuctionState {
|
||||||
gapTime?: Date
|
gapTime?: Date
|
||||||
|
|
||||||
category: AuctionCategory;
|
category: AuctionCategory;
|
||||||
|
price?: number;
|
||||||
|
startSaleTS?: number;
|
||||||
|
startListTS?: number;
|
||||||
|
endTS?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AuctionCreateView = () => {
|
export const AuctionCreateView = () => {
|
||||||
|
@ -92,7 +98,7 @@ export const AuctionCreateView = () => {
|
||||||
}, [step_param])
|
}, [step_param])
|
||||||
|
|
||||||
const gotoNextStep = (_step?: number) => {
|
const gotoNextStep = (_step?: number) => {
|
||||||
const nextStep = _step === undefined ? (step + 1) : step;
|
const nextStep = _step === undefined ? (step + 1) : _step;
|
||||||
history.push(`/auction/create/${nextStep.toString()}`)
|
history.push(`/auction/create/${nextStep.toString()}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +177,7 @@ export const AuctionCreateView = () => {
|
||||||
confirm={() => gotoNextStep()}
|
confirm={() => gotoNextStep()}
|
||||||
/>;
|
/>;
|
||||||
|
|
||||||
const congratsStep = <Congrats />;
|
const congratsStep = <Congrats />;
|
||||||
|
|
||||||
const stepsByCategory = {
|
const stepsByCategory = {
|
||||||
[AuctionCategory.Limited]: [
|
[AuctionCategory.Limited]: [
|
||||||
|
@ -185,9 +191,8 @@ export const AuctionCreateView = () => {
|
||||||
['Publish', waitStep],
|
['Publish', waitStep],
|
||||||
[undefined, congratsStep],
|
[undefined, congratsStep],
|
||||||
],
|
],
|
||||||
[AuctionCategory.Open]: [
|
[AuctionCategory.Single]: [
|
||||||
['Category', categoryStep],
|
['Category', categoryStep],
|
||||||
['Copies', copiesStep],
|
|
||||||
['Price', priceStep],
|
['Price', priceStep],
|
||||||
['Initial Phase', initialStep],
|
['Initial Phase', initialStep],
|
||||||
['Ending Phase', endingStep],
|
['Ending Phase', endingStep],
|
||||||
|
@ -196,8 +201,9 @@ export const AuctionCreateView = () => {
|
||||||
['Publish', waitStep],
|
['Publish', waitStep],
|
||||||
[undefined, congratsStep],
|
[undefined, congratsStep],
|
||||||
],
|
],
|
||||||
[AuctionCategory.Single]: [
|
[AuctionCategory.Open]: [
|
||||||
['Category', categoryStep],
|
['Category', categoryStep],
|
||||||
|
['Copies', copiesStep],
|
||||||
['Price', priceStep],
|
['Price', priceStep],
|
||||||
['Initial Phase', initialStep],
|
['Initial Phase', initialStep],
|
||||||
['Ending Phase', endingStep],
|
['Ending Phase', endingStep],
|
||||||
|
@ -343,23 +349,23 @@ const CopiesStep = (props: {
|
||||||
</Row>
|
</Row>
|
||||||
<Row className="content-action">
|
<Row className="content-action">
|
||||||
<Col>
|
<Col>
|
||||||
<ArtSelector selected={[]} setSelected={() => {}} allowMultiple={false}>Select NFT</ArtSelector>
|
<ArtSelector selected={[]} setSelected={() => { }} allowMultiple={false}>Select NFT</ArtSelector>
|
||||||
<label className="action-field">
|
<label className="action-field">
|
||||||
<span className="field-title">How many copies do you want to create?</span>
|
<span className="field-title">How many copies do you want to create?</span>
|
||||||
<span className="field-info">Each copy will be given unique edition number e.g. 1 of 30</span>
|
<span className="field-info">Each copy will be given unique edition number e.g. 1 of 30</span>
|
||||||
<Input
|
<Input
|
||||||
autoFocus
|
autoFocus
|
||||||
className="input"
|
className="input"
|
||||||
placeholder="Enter number of copies sold"
|
placeholder="Enter number of copies sold"
|
||||||
allowClear
|
allowClear
|
||||||
onChange={info =>
|
onChange={info =>
|
||||||
props.setAttributes({
|
props.setAttributes({
|
||||||
...props.attributes,
|
...props.attributes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Button
|
<Button
|
||||||
|
@ -388,25 +394,25 @@ const NumberOfWinnersStep = (props: {
|
||||||
}) => {
|
}) => {
|
||||||
return <>
|
return <>
|
||||||
<Row className="call-to-action">
|
<Row className="call-to-action">
|
||||||
<h2>Specify the terms of your auction</h2>
|
<h2>Specify the terms of your auction</h2>
|
||||||
<p>
|
<p>
|
||||||
Provide detailed auction parameters such as price, start time, etc.
|
Provide detailed auction parameters such as price, start time, etc.
|
||||||
</p>
|
</p>
|
||||||
</Row>
|
</Row>
|
||||||
<Row className="content-action">
|
<Row className="content-action">
|
||||||
<Col className="section" xl={24}>
|
<Col className="section" xl={24}>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="large"
|
size="large"
|
||||||
onClick={props.confirm}
|
onClick={props.confirm}
|
||||||
className="action-btn"
|
className="action-btn"
|
||||||
>
|
>
|
||||||
Continue to Tiers
|
Continue to Tiers
|
||||||
</Button>
|
</Button>
|
||||||
</Row>
|
</Row>
|
||||||
</>;
|
</>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -446,14 +452,31 @@ const PriceStep = (props: {
|
||||||
}) => {
|
}) => {
|
||||||
return <>
|
return <>
|
||||||
<Row className="call-to-action">
|
<Row className="call-to-action">
|
||||||
<h2>Specify the terms of your auction</h2>
|
<h2>Price</h2>
|
||||||
<p>
|
<p>
|
||||||
Provide detailed auction parameters such as price, start time, etc.
|
Set the price for your auction.
|
||||||
</p>
|
</p>
|
||||||
</Row>
|
</Row>
|
||||||
<Row className="content-action">
|
<Row className="content-action">
|
||||||
<Col className="section" xl={24}>
|
<label className="action-field">
|
||||||
</Col>
|
<span className="field-title">Sale price</span>
|
||||||
|
<span className="field-info">This is the starting bid price for your auction.</span>
|
||||||
|
<Input
|
||||||
|
type="number"
|
||||||
|
min={0}
|
||||||
|
autoFocus
|
||||||
|
className="input"
|
||||||
|
placeholder="Price"
|
||||||
|
prefix="$"
|
||||||
|
suffix="USD"
|
||||||
|
onChange={info =>
|
||||||
|
props.setAttributes({
|
||||||
|
...props.attributes,
|
||||||
|
price: parseFloat(info.target.value) || undefined
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Button
|
<Button
|
||||||
|
@ -473,30 +496,56 @@ const InitialPhaseStep = (props: {
|
||||||
setAttributes: (attr: AuctionState) => void;
|
setAttributes: (attr: AuctionState) => void;
|
||||||
confirm: () => void;
|
confirm: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
|
const [saleNow, setSaleNow] = useState<boolean>(true)
|
||||||
|
const [listNow, setListNow] = useState<boolean>(true)
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<Row className="call-to-action">
|
<Row className="call-to-action">
|
||||||
<h2>Specify the terms of your auction</h2>
|
<h2>Initial Phase</h2>
|
||||||
<p>
|
<p>
|
||||||
Provide detailed auction parameters such as price, start time, etc.
|
Set the terms for your sale.
|
||||||
</p>
|
</p>
|
||||||
</Row>
|
</Row>
|
||||||
<Row className="content-action">
|
<Row className="content-action">
|
||||||
<Col className="section" xl={24}>
|
<Col className="section" xl={24}>
|
||||||
|
|
||||||
<label className="action-field">
|
<label className="action-field">
|
||||||
<span className="field-title">Preview Start Date</span>
|
<span className="field-title">When do you want the sale to begin?</span>
|
||||||
<DatePicker className="field-date" size="large" />
|
<Radio.Group defaultValue="now" onChange={info => setSaleNow(info.target.value === "now")}>
|
||||||
<TimePicker className="field-date" size="large" />
|
<Radio className="radio-field" value="now">Immediately</Radio>
|
||||||
</label>
|
<div className="radio-subtitle">Participants can buy the NFT as soon as you finish setting up the auction.</div>
|
||||||
<label className="action-field">
|
<Radio className="radio-field" value="later">At a specified date</Radio>
|
||||||
<span className="field-title">When do you want the auction to begin?</span>
|
<div className="radio-subtitle">Participants can start buying the NFT at a specified date.</div>
|
||||||
<span>Immediately</span>
|
</Radio.Group>
|
||||||
<span>At a specified data</span>
|
|
||||||
</label>
|
|
||||||
<label className="action-field">
|
|
||||||
<span className="field-title">Auction Start Date</span>
|
|
||||||
<DatePicker className="field-date" size="large" />
|
|
||||||
<TimePicker className="field-date" size="large" />
|
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
|
{!saleNow && <>
|
||||||
|
|
||||||
|
<label className="action-field">
|
||||||
|
<span className="field-title">Auction Start Date</span>
|
||||||
|
<DatePicker className="field-date" size="large" onChange={(dt, dtString) => console.log({ dt, dtString })} />
|
||||||
|
<TimePicker className="field-date" size="large" onChange={(dt, dtString) => console.log({ dt, dtString })} />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label className="action-field">
|
||||||
|
<span className="field-title">When do you want the listing to go live?</span>
|
||||||
|
<Radio.Group defaultValue="now" onChange={info => setListNow(info.target.value === "now")}>
|
||||||
|
<Radio className="radio-field" value="now" defaultChecked={true}>Immediately</Radio>
|
||||||
|
<div className="radio-subtitle">Participants will be able to view the listing with a countdown to the start date as soon as you finish setting up the sale.</div>
|
||||||
|
<Radio className="radio-field" value="later">At a specified date</Radio>
|
||||||
|
<div className="radio-subtitle">Participants will be able to view the listing with a countdown to the start date at the specified date.</div>
|
||||||
|
</Radio.Group>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
{!listNow &&
|
||||||
|
<label className="action-field">
|
||||||
|
<span className="field-title">Preview Start Date</span>
|
||||||
|
<DatePicker className="field-date" size="large" />
|
||||||
|
<TimePicker className="field-date" size="large" />
|
||||||
|
</label>
|
||||||
|
}
|
||||||
|
|
||||||
|
</>}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -517,20 +566,34 @@ const EndingPhaseStep = (props: {
|
||||||
setAttributes: (attr: AuctionState) => void;
|
setAttributes: (attr: AuctionState) => void;
|
||||||
confirm: () => void;
|
confirm: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
|
const [untilSold, setUntilSold] = useState<boolean>(true)
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
<Row className="call-to-action">
|
<Row className="call-to-action">
|
||||||
<h2>Specify the terms of your auction</h2>
|
<h2>Ending Phase</h2>
|
||||||
<p>
|
<p>
|
||||||
Provide detailed auction parameters such as price, start time, etc.
|
Set the terms for your sale..
|
||||||
</p>
|
</p>
|
||||||
</Row>
|
</Row>
|
||||||
<Row className="content-action">
|
<Row className="content-action">
|
||||||
<Col className="section" xl={24}>
|
<Col className="section" xl={24}>
|
||||||
|
<label className="action-field">
|
||||||
|
<span className="field-title">When do you want the sale to begin?</span>
|
||||||
|
<Radio.Group defaultValue="now" onChange={info => setUntilSold(info.target.value === "now")}>
|
||||||
|
<Radio className="radio-field" value="now">Until sols</Radio>
|
||||||
|
<div className="radio-subtitle">The sale will end once the supply goes to zero.</div>
|
||||||
|
<Radio className="radio-field" value="later">At a specified date</Radio>
|
||||||
|
<div className="radio-subtitle">The sale will end at this date, regardless if there is remaining supply.</div>
|
||||||
|
</Radio.Group>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
{!untilSold &&
|
||||||
<label className="action-field">
|
<label className="action-field">
|
||||||
<span className="field-title">End Start Date</span>
|
<span className="field-title">End Date</span>
|
||||||
<DatePicker className="field-date" size="large" />
|
<DatePicker className="field-date" size="large" onChange={(dt, dtString) => console.log(dt?.unix())} />
|
||||||
<TimePicker className="field-date" size="large" />
|
<TimePicker className="field-date" size="large" onChange={(dt, dtString) => console.log(dt?.unix())} />
|
||||||
</label>
|
</label>
|
||||||
|
}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -560,7 +623,7 @@ const ParticipationStep = (props: {
|
||||||
</Row>
|
</Row>
|
||||||
<Row className="content-action">
|
<Row className="content-action">
|
||||||
<Col className="section" xl={24}>
|
<Col className="section" xl={24}>
|
||||||
<ArtSelector selected={[]} setSelected={() => {}} allowMultiple={false}>Select NFT</ArtSelector>
|
<ArtSelector selected={[]} setSelected={() => { }} allowMultiple={false}>Select NFT</ArtSelector>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
|
@ -689,7 +752,7 @@ const ReviewStep = (props: {
|
||||||
<Statistic
|
<Statistic
|
||||||
className="create-statistic"
|
className="create-statistic"
|
||||||
title="Copies"
|
title="Copies"
|
||||||
value={props.attributes.editions === undefined ? 'Unique' : props.attributes.editions }
|
value={props.attributes.editions === undefined ? 'Unique' : props.attributes.editions}
|
||||||
/>
|
/>
|
||||||
{cost ? (
|
{cost ? (
|
||||||
<Statistic
|
<Statistic
|
||||||
|
@ -703,6 +766,26 @@ const ReviewStep = (props: {
|
||||||
)}
|
)}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
<Row style={{ display: 'block' }}>
|
||||||
|
<Divider />
|
||||||
|
{props.attributes.startSaleTS && <Statistic
|
||||||
|
className="create-statistic"
|
||||||
|
title="Start date"
|
||||||
|
value={props.attributes.startSaleTS}
|
||||||
|
/>}
|
||||||
|
<br />
|
||||||
|
{props.attributes.startListTS && <Statistic
|
||||||
|
className="create-statistic"
|
||||||
|
title="Listing go live date"
|
||||||
|
value={props.attributes.startListTS}
|
||||||
|
/>}
|
||||||
|
<Divider />
|
||||||
|
{props.attributes.endTS && <Statistic
|
||||||
|
className="create-statistic"
|
||||||
|
title="Sale ends"
|
||||||
|
value={props.attributes.endTS}
|
||||||
|
/>}
|
||||||
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Button
|
<Button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
|
|
@ -292,3 +292,15 @@
|
||||||
height: 24px;
|
height: 24px;
|
||||||
margin-top: -7px;
|
margin-top: -7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.radio-field {
|
||||||
|
display: block;
|
||||||
|
height: 30px;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-subtitle {
|
||||||
|
color: dimgray;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue