mirror of https://github.com/certusone/oyster.git
Improves to artwork creation flow (#56)
* MainAuctionCard * trending auctions * fix scroll, reduce padding * fixing errors/warnings and formatting * formatting & sold auctions * artists cards * initial presale banner. move sample data to own file * new home layout * presale banner image fix * countdown implementation * initial artwork implementation * getCountdown * presale card * fix presale banner image * fix width. show preview. load only 1 file * remove preview/keep filename. url id for steps * slider > input number Co-authored-by: B <264380+bartosz-lipinski@users.noreply.github.com>
This commit is contained in:
parent
6eb0e43a2c
commit
91b8870952
|
@ -1,5 +1,5 @@
|
||||||
import { HashRouter, Route, Switch } from 'react-router-dom';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { BrowserRouter, Route, Switch } from 'react-router-dom';
|
||||||
import { contexts } from '@oyster/common';
|
import { contexts } from '@oyster/common';
|
||||||
import {
|
import {
|
||||||
MarketProvider,
|
MarketProvider,
|
||||||
|
@ -16,7 +16,7 @@ const { AccountsProvider } = contexts.Accounts;
|
||||||
export function Routes() {
|
export function Routes() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HashRouter basename={'/'}>
|
<BrowserRouter basename={'/'}>
|
||||||
<ConnectionProvider>
|
<ConnectionProvider>
|
||||||
<WalletProvider>
|
<WalletProvider>
|
||||||
<UseWalletProvider chainId={5}>
|
<UseWalletProvider chainId={5}>
|
||||||
|
@ -32,7 +32,7 @@ export function Routes() {
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/art/create"
|
path="/art/create/:step_param?"
|
||||||
component={() => <ArtCreateView />}
|
component={() => <ArtCreateView />}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
|
@ -73,7 +73,7 @@ export function Routes() {
|
||||||
</UseWalletProvider>
|
</UseWalletProvider>
|
||||||
</WalletProvider>
|
</WalletProvider>
|
||||||
</ConnectionProvider>
|
</ConnectionProvider>
|
||||||
</HashRouter>
|
</BrowserRouter>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,10 +7,10 @@ import {
|
||||||
Col,
|
Col,
|
||||||
Input,
|
Input,
|
||||||
Statistic,
|
Statistic,
|
||||||
Slider,
|
|
||||||
Modal,
|
Modal,
|
||||||
Progress,
|
Progress,
|
||||||
Spin,
|
Spin,
|
||||||
|
InputNumber,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import { InboxOutlined } from '@ant-design/icons';
|
import { InboxOutlined } from '@ant-design/icons';
|
||||||
import { ArtCard } from './../../components/ArtCard';
|
import { ArtCard } from './../../components/ArtCard';
|
||||||
|
@ -31,7 +31,7 @@ import {
|
||||||
import { getAssetCostToStore, LAMPORT_MULTIPLIER } from '../../utils/assets';
|
import { getAssetCostToStore, LAMPORT_MULTIPLIER } from '../../utils/assets';
|
||||||
import { Connection } from '@solana/web3.js';
|
import { Connection } from '@solana/web3.js';
|
||||||
import { MintLayout } from '@solana/spl-token';
|
import { MintLayout } from '@solana/spl-token';
|
||||||
import { ArtContent } from '../../components/ArtContent';
|
import { useHistory, useParams } from 'react-router-dom';
|
||||||
|
|
||||||
const { Step } = Steps;
|
const { Step } = Steps;
|
||||||
const { Dragger } = Upload;
|
const { Dragger } = Upload;
|
||||||
|
@ -40,6 +40,9 @@ export const ArtCreateView = () => {
|
||||||
const connection = useConnection();
|
const connection = useConnection();
|
||||||
const { env } = useConnectionConfig();
|
const { env } = useConnectionConfig();
|
||||||
const { wallet, connected } = useWallet();
|
const { wallet, connected } = useWallet();
|
||||||
|
const { step_param }: { step_param: string } = useParams()
|
||||||
|
const history = useHistory()
|
||||||
|
|
||||||
const [step, setStep] = useState(0);
|
const [step, setStep] = useState(0);
|
||||||
const [saving, setSaving] = useState(false);
|
const [saving, setSaving] = useState(false);
|
||||||
const [attributes, setAttributes] = useState<IMetadataExtension>({
|
const [attributes, setAttributes] = useState<IMetadataExtension>({
|
||||||
|
@ -53,6 +56,15 @@ export const ArtCreateView = () => {
|
||||||
category: MetadataCategory.Image,
|
category: MetadataCategory.Image,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (step_param) setStep(parseInt(step_param))
|
||||||
|
else gotoStep(0)
|
||||||
|
}, [step_param])
|
||||||
|
|
||||||
|
const gotoStep = (_step: number) => {
|
||||||
|
history.push(`/art/create/${_step.toString()}`)
|
||||||
|
}
|
||||||
|
|
||||||
// store files
|
// store files
|
||||||
const mint = async () => {
|
const mint = async () => {
|
||||||
const metadata = {
|
const metadata = {
|
||||||
|
@ -102,7 +114,7 @@ export const ArtCreateView = () => {
|
||||||
...attributes,
|
...attributes,
|
||||||
category,
|
category,
|
||||||
});
|
});
|
||||||
setStep(1);
|
gotoStep(1);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -110,7 +122,7 @@ export const ArtCreateView = () => {
|
||||||
<UploadStep
|
<UploadStep
|
||||||
attributes={attributes}
|
attributes={attributes}
|
||||||
setAttributes={setAttributes}
|
setAttributes={setAttributes}
|
||||||
confirm={() => setStep(2)}
|
confirm={() => gotoStep(2)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
@ -118,13 +130,13 @@ export const ArtCreateView = () => {
|
||||||
<InfoStep
|
<InfoStep
|
||||||
attributes={attributes}
|
attributes={attributes}
|
||||||
setAttributes={setAttributes}
|
setAttributes={setAttributes}
|
||||||
confirm={() => setStep(3)}
|
confirm={() => gotoStep(3)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{step === 3 && (
|
{step === 3 && (
|
||||||
<RoyaltiesStep
|
<RoyaltiesStep
|
||||||
attributes={attributes}
|
attributes={attributes}
|
||||||
confirm={() => setStep(4)}
|
confirm={() => gotoStep(4)}
|
||||||
setAttributes={setAttributes}
|
setAttributes={setAttributes}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -135,7 +147,7 @@ export const ArtCreateView = () => {
|
||||||
connection={connection}
|
connection={connection}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{step > 0 && <Button onClick={() => setStep(step - 1)}>Back</Button>}
|
{step > 0 && <Button onClick={() => gotoStep(step - 1)}>Back</Button>}
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</>
|
</>
|
||||||
|
@ -185,8 +197,7 @@ const UploadStep = (props: {
|
||||||
setAttributes: (attr: IMetadataExtension) => void;
|
setAttributes: (attr: IMetadataExtension) => void;
|
||||||
confirm: () => void;
|
confirm: () => void;
|
||||||
}) => {
|
}) => {
|
||||||
const [fileList, setFileList] = useState<any[]>([])
|
const [fileList, setFileList] = useState<any[]>(props.attributes.files ?? [])
|
||||||
const [preview, setPreview] = useState<string>("")
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -204,7 +215,6 @@ const UploadStep = (props: {
|
||||||
<Dragger
|
<Dragger
|
||||||
style={{ padding: 20 }}
|
style={{ padding: 20 }}
|
||||||
multiple={false}
|
multiple={false}
|
||||||
showUploadList={false}
|
|
||||||
customRequest={info => {
|
customRequest={info => {
|
||||||
// dont upload files here, handled outside of the control
|
// dont upload files here, handled outside of the control
|
||||||
info?.onSuccess?.({}, null as any);
|
info?.onSuccess?.({}, null as any);
|
||||||
|
@ -214,16 +224,14 @@ const UploadStep = (props: {
|
||||||
const file = info.file.originFileObj;
|
const file = info.file.originFileObj;
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.onload = function (event) {
|
reader.onload = function (event) {
|
||||||
const image = (event.target?.result as string) || ''
|
|
||||||
props.setAttributes({
|
props.setAttributes({
|
||||||
...props.attributes,
|
...props.attributes,
|
||||||
files: [file],
|
files: [file],
|
||||||
image,
|
image: (event.target?.result as string) || '',
|
||||||
})
|
})
|
||||||
setPreview(image)
|
|
||||||
};
|
};
|
||||||
reader.readAsDataURL(file);
|
if (file) reader.readAsDataURL(file);
|
||||||
setFileList(info.fileList.slice(-1)) // Keep only the last dropped file
|
setFileList(info.fileList?.slice(-1) ?? []) // Keep only the last dropped file
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<p className="ant-upload-drag-icon">
|
<p className="ant-upload-drag-icon">
|
||||||
|
@ -233,9 +241,6 @@ const UploadStep = (props: {
|
||||||
Click or drag file to this area to upload
|
Click or drag file to this area to upload
|
||||||
</p>
|
</p>
|
||||||
</Dragger>
|
</Dragger>
|
||||||
<div style={{ marginTop: 10 }}>
|
|
||||||
<ArtContent category={props.attributes.category} content={preview} className="art-content" />
|
|
||||||
</div>
|
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Button
|
<Button
|
||||||
|
@ -368,12 +373,14 @@ const RoyaltiesStep = (props: {
|
||||||
<Col className="section" xl={12}>
|
<Col className="section" xl={12}>
|
||||||
<label className="action-field">
|
<label className="action-field">
|
||||||
<span className="field-title">Royalty Percentage</span>
|
<span className="field-title">Royalty Percentage</span>
|
||||||
<Slider
|
<InputNumber
|
||||||
min={0}
|
min={0}
|
||||||
max={100}
|
max={100}
|
||||||
|
placeholder="Between 0 and 100"
|
||||||
onChange={(val: number) => {
|
onChange={(val: number) => {
|
||||||
props.setAttributes({ ...props.attributes, royalty: val });
|
props.setAttributes({ ...props.attributes, royalty: val });
|
||||||
}}
|
}}
|
||||||
|
className="royalties-input"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</Col>
|
</Col>
|
||||||
|
|
|
@ -162,3 +162,20 @@
|
||||||
|
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.royalties-input {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
background: #282828;
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
flex: none;
|
||||||
|
order: 1;
|
||||||
|
align-self: stretch;
|
||||||
|
flex-grow: 0;
|
||||||
|
margin: 12px 0px;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue