Metaplex: winners range, datetime fields (#91)

* winners range

* store datetime fields on attributes

* initial landing page

* responsiveness with bootstrap
This commit is contained in:
Jose 2021-04-27 17:32:53 -05:00 committed by GitHub
parent fa203e280e
commit 4248648f76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 241 additions and 22 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

View File

@ -0,0 +1,102 @@
body {
background-color: black;
}
.header {
font-family: Graphik Web Regular;
font-style: italic;
font-weight: 500;
font-size: 2rem;
line-height: 40px;
color: #FFFFFF;
border: 1px solid #000000;
}
.subheader {
font-family: Graphik Web Regular;
font-style: normal;
font-weight: 500;
font-size: 36px;
line-height: 48px;
color: #FFFFFF;
margin: 42px 0px;
}
.text {
font-family: Graphik Web Regular;
font-style: normal;
font-weight: normal;
font-size: 18px;
line-height: 1.5;
color: rgba(255, 255, 255, 0.7);
}
.image {
width: 100%;
height: 100vw;
background: url(image.png);
background-repeat: no-repeat;
background-size: contain;
}
/* button {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
padding: 20px 10px;
position: static;
width: 350px;
height: 59px;
left: 0px;
top: 69px;
background: linear-gradient(270deg, #616774 7.29%, #403F4C 100%);
border-radius: 8px;
flex: none;
order: 1;
flex-grow: 0;
margin: 15px 0px;
color: white;
}
.email-input {
display: flex;
flex-direction: row;
align-items: center;
padding: 16px 10px 16px 24px;
position: static;
width: 348px;
height: 54px;
left: 0px;
top: 0px;
background: #282828;
border-radius: 8px;
flex: none;
order: 0;
flex-grow: 0;
margin: 15px 0px;
} */
.typeform-widget {
height: 360px !important;
}
#form {
width: 100%;
max-width: 400px;
margin-bottom: 50px;
}

View File

@ -0,0 +1,47 @@
<html>
<head>
<title>Metaplex NFT Marketplace</title>
<meta content="width=device-width, initial-scale=1" name="viewport" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
<link href="//db.onlinewebfonts.com/c/105007d99d9df64c50cc24d696d79555?family=Graphik+Web+Regular" rel="stylesheet"
type="text/css" />
<link rel="stylesheet" href="landing.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf"
crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<div class="header my-3 my-md-5">METAPLEX</div>
<div class="row">
<div class="col-12 col-md-6">
<div>
<div class="subheader">NFT platforms. Push to start.</div>
<div class="text">
Metaplex is an open source NFT framework built on Solana that puts creators and artists in the drivers
seat.
<br />
<br />
With Metaplex, you can launch an NFT marketplace in minutes.
</div>
</div>
<div>
<!-- <input class="email-input" placeholder="Email Address"/> -->
<!-- <button>SIGN UP FOR EARLY ACCESS</button> -->
<div id="form" data-tf-widget="gZ8mozPq"></div>
<script src="//embed.typeform.com/next/embed.js"></script>
</div>
</div>
<div class="col-12 col-md-6">
<div class="image mx-auto"></div>
</div>
</div>
</div>
</body>
</html>

View File

@ -53,6 +53,7 @@ import {
WinningConstraint,
} from '../../models/metaplex';
import { serialize } from 'borsh';
import moment from 'moment'
import {
createAuctionManager,
SafetyDepositDraft,
@ -94,7 +95,8 @@ export interface AuctionState {
// suggested date time when auction should end UTC+0
endDate?: Date;
// Jose's attributes
//////////////////
category: AuctionCategory;
saleType?: 'auction' | 'sale';
@ -362,7 +364,7 @@ export const AuctionCreateView = () => {
)}
<Col {...(saving ? { xl: 24 } : { xl: 16, md: 17 })}>
{stepsByCategory[attributes.category][step][1]}
{0 < step && step < (stepsByCategory[attributes.category].length -1) && (
{0 < step && step < (stepsByCategory[attributes.category].length - 1) && (
<Button
style={{ width: '100%' }}
onClick={() => gotoNextStep(step - 1)}
@ -526,12 +528,12 @@ const CopiesStep = (props: {
tiers:
!props.attributes.tiers || props.attributes.tiers?.length == 0
? [
{
to: 0,
name: 'Default Tier',
items: props.attributes.items,
},
]
{
to: 0,
name: 'Default Tier',
items: props.attributes.items,
},
]
: props.attributes.tiers,
});
props.confirm();
@ -599,28 +601,39 @@ const TierWinners = (props: {
tier: Tier;
setTier: Function;
previousTo?: number;
lastTier?: Tier;
}) => {
const from = (props.previousTo || 0) + 1
return (
<>
<Divider />
<label className="action-field">
<span className="field-title">Winners</span>
<div>
<Input
disabled={props.idx === 0}
defaultValue={(props.previousTo || 0) + 1}
<InputNumber
disabled={true}
value={from}
type="number"
className="input"
style={{ width: '30%' }}
onChange={info => null}
onChange={value =>
null
}
/>
&nbsp;to&nbsp;
<Input
<InputNumber
min={from + 1}
disabled={props.lastTier?.to == props.tier.to}
defaultValue={props.tier.to}
type="number"
className="input"
style={{ width: '30%' }}
onChange={info => null}
onChange={value =>
props.setTier(props.idx, {
...props.tier,
to: value || props.tier.to,
})
}
/>
</div>
</label>
@ -654,7 +667,7 @@ const TierWinners = (props: {
/>
</label>
<ArtSelector selected={[]} setSelected={_ => {}} allowMultiple={true} />
<ArtSelector selected={[]} setSelected={_ => { }} allowMultiple={true} />
</>
);
};
@ -703,7 +716,7 @@ const TierStep = (props: {
(_, idx) => ({
to: Math.trunc(
((idx + 1) * (props.attributes.spots as number)) /
parseInt(info.target.value),
parseInt(info.target.value),
),
name: '',
description: '',
@ -722,8 +735,10 @@ const TierStep = (props: {
tier={tier}
setTier={setTier}
previousTo={tiers[idx - 1]?.to}
lastTier={tiers.slice(-1)[0]}
/>
))}
</Col>
</Row>
<Row>
@ -903,7 +918,6 @@ const PriceAuction = (props: {
<Input
type="number"
min={0}
autoFocus
className="input"
placeholder="Tick size in USD"
prefix="$"
@ -941,6 +955,31 @@ const InitialPhaseStep = (props: {
const [startNow, setStartNow] = useState<boolean>(true);
const [listNow, setListNow] = useState<boolean>(true);
const [saleMoment, setSaleMoment] = useState<moment.Moment | undefined>(props.attributes.startSaleTS ? moment.unix(props.attributes.startSaleTS) : undefined)
const [listMoment, setListMoment] = useState<moment.Moment | undefined>(props.attributes.startListTS ? moment.unix(props.attributes.startListTS) : undefined)
useEffect(() => {
props.setAttributes({
...props.attributes,
startSaleTS: saleMoment && saleMoment.unix() * 1000
})
}, [saleMoment])
useEffect(() => {
props.setAttributes({
...props.attributes,
startListTS: listMoment && listMoment.unix() * 1000
})
}, [listMoment])
useEffect(() => {
if (startNow) setSaleMoment(moment())
}, [startNow])
useEffect(() => {
if (listNow) setListMoment(moment())
}, [listNow])
return (
<>
<Row className="call-to-action">
@ -1104,7 +1143,6 @@ const EndingPhaseAuction = (props: {
</span>
<Input
type="number"
autoFocus
className="input"
placeholder="Duration in minutes"
suffix="minutes"
@ -1126,7 +1164,6 @@ const EndingPhaseAuction = (props: {
</span>
<Input
type="number"
autoFocus
className="input"
placeholder="Percentage"
suffix="%"
@ -1160,6 +1197,18 @@ const EndingPhaseSale = (props: {
confirm: () => void;
}) => {
const [untilSold, setUntilSold] = useState<boolean>(true);
const [endMoment, setEndMoment] = useState<moment.Moment | undefined>(props.attributes.endTS ? moment.unix(props.attributes.endTS) : undefined)
useEffect(() => {
props.setAttributes({
...props.attributes,
endTS: endMoment && endMoment.unix() * 1000
})
}, [endMoment])
useEffect(() => {
if (untilSold) setEndMoment(undefined)
}, [untilSold])
return (
<>
@ -1199,12 +1248,33 @@ const EndingPhaseSale = (props: {
<DatePicker
className="field-date"
size="large"
onChange={(dt, dtString) => console.log(dt?.unix())}
disabledDate={current => current && current < moment().endOf('day')}
value={endMoment}
onChange={value => {
if (!value) return
if (!endMoment) return setEndMoment(value)
const currentMoment = endMoment.clone()
currentMoment.hour(value.hour())
currentMoment.minute(value.minute())
currentMoment.second(value.second())
setEndMoment(currentMoment)
}}
/>
<TimePicker
className="field-date"
size="large"
onChange={(dt, dtString) => console.log(dt?.unix())}
value={endMoment}
onChange={value => {
if (!value) return
if (!endMoment) return setEndMoment(value)
const currentMoment = endMoment.clone()
currentMoment.hour(value.hour())
currentMoment.minute(value.minute())
currentMoment.second(value.second())
setEndMoment(currentMoment)
}}
/>
</label>
)}
@ -1242,7 +1312,7 @@ const ParticipationStep = (props: {
<Col className="section" xl={24}>
<ArtSelector
selected={[]}
setSelected={() => {}}
setSelected={() => { }}
allowMultiple={false}
>
Select NFT