feat: add creators

This commit is contained in:
bartosz-lipinski 2021-04-13 23:25:43 -05:00
parent 00de45009f
commit 1e35a14628
4 changed files with 116 additions and 4 deletions

View File

@ -0,0 +1,91 @@
import { Select, Spin } from 'antd';
import { SelectProps } from 'antd/es/select';
import debounce from 'lodash/debounce';
import React, { useMemo, useRef, useState } from 'react';
import './styles.less';
export interface DebounceSelectProps<ValueType = any>
extends Omit<SelectProps<ValueType>, 'options' | 'children'> {
fetchOptions: (search: string) => Promise<ValueType[]>;
debounceTimeout?: number;
}
function DebounceSelect<
ValueType extends { key?: string; label: React.ReactNode; value: string | number } = any
>({ fetchOptions, debounceTimeout = 800, ...props }: DebounceSelectProps) {
const [fetching, setFetching] = useState(false);
const [options, setOptions] = useState<ValueType[]>([]);
const fetchRef = useRef(0);
const debounceFetcher = useMemo(() => {
const loadOptions = (value: string) => {
fetchRef.current += 1;
const fetchId = fetchRef.current;
setOptions([]);
setFetching(true);
fetchOptions(value).then(newOptions => {
if (fetchId !== fetchRef.current) {
// for fetch callback order
return;
}
setOptions(newOptions);
setFetching(false);
});
};
return debounce(loadOptions, debounceTimeout);
}, [fetchOptions, debounceTimeout]);
return (
<Select<ValueType>
labelInValue
filterOption={false}
onSearch={debounceFetcher}
notFoundContent={fetching ? <Spin size="small" /> : null}
{...props}
options={options}
/>
);
}
// Usage of DebounceSelect
interface UserValue {
label: string;
value: string;
}
async function fetchUserList(username: string): Promise<UserValue[]> {
console.log('fetching user', username);
return fetch('https://randomuser.me/api/?results=5')
.then(response => response.json())
.then(body =>
body.results.map(
(user: { name: { first: string; last: string }; login: { username: string } }) => ({
label: `${user.name.first} ${user.name.last}`,
value: user.login.username,
}),
),
);
}
export const UserSearch = () => {
const [value, setValue] = React.useState<UserValue[]>([]);
return (
<DebounceSelect
className="user-selector"
mode="multiple"
size="large"
value={value}
placeholder="Select creator"
fetchOptions={fetchUserList}
onChange={newValue => {
setValue(newValue);
}}
style={{ width: '100%' }}
/>
);
};

View File

@ -0,0 +1,11 @@
.user-selector {
background: #282828;
border-radius: 8px;
padding: 3px 0px;
overflow: hidden;
.ant-select-selector {
border-width: 0px !important;
text-align: left;
}
}

View File

@ -11,8 +11,10 @@ import {
Progress,
Spin,
InputNumber,
Select,
} from 'antd';
import { ArtCard } from './../../components/ArtCard';
import { UserSearch } from './../../components/UserSearch';
import './styles.less';
import { mintNFT } from '../../models';
import {
@ -33,6 +35,7 @@ import { MintLayout } from '@solana/spl-token';
import { useHistory, useParams } from 'react-router-dom';
const { Step } = Steps;
const { Option } = Select;
const { Dragger } = Upload;
export const ArtCreateView = () => {
@ -158,11 +161,9 @@ const CategoryStep = (props: { confirm: (category: MetadataCategory) => void })
return (
<>
<Row className="call-to-action">
<h2>Create your NFT artwork on Meta</h2>
<h2>Create a new item</h2>
<p>
Creating NFT on Solana is not only low cost for artists but supports
environment with 20% of the fees form the platform donated to
charities.
First time creating on Metaplex? <a>Read our creators guide.</a>
</p>
</Row>
<Row>
@ -374,6 +375,12 @@ const InfoStep = (props: {
}
/>
</label>
<label className="action-field">
<span className="field-title">Creators</span>
<UserSearch
/>
</label>
<label className="action-field">
<span className="field-title">Description</span>
<Input.TextArea

View File

@ -22,6 +22,9 @@
p {
color: #6d6d6d;
font-family: Inter;
font-style: normal;
font-size: 20px;
}
margin-bottom: 50px;