Trending auctions (#40)

* MainAuctionCard

* trending auctions

* fix scroll, reduce padding

* fixing errors/warnings and formatting

* formatting & sold auctions

* artists cards
This commit is contained in:
Jose 2021-04-05 10:37:56 -05:00 committed by GitHub
parent c905efd2c3
commit 763337ddc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 267 additions and 68 deletions

View File

@ -2,7 +2,7 @@ import { WalletAdapter } from "@solana/wallet-base";
import Wallet from "@project-serum/sol-wallet-adapter";
import { Button, Modal } from "antd";
import React, { useCallback, useContext, useEffect, useMemo, useState} from "react";
import React, { useCallback, useContext, useEffect, useMemo, useState } from "react";
import { notify } from "./../utils/notifications";
import { useConnectionConfig } from "./connection";
import { useLocalStorageState } from "./../utils/utils";
@ -14,20 +14,20 @@ const ASSETS_URL = 'https://raw.githubusercontent.com/solana-labs/oyster/main/as
export const WALLET_PROVIDERS = [
{
name: "Sollet",
url: "https://www.sollet.io",
url: "https://www.sollet.io",
icon: `${ASSETS_URL}sollet.svg`,
}, {
name: "Solong",
url: "https://solongwallet.com",
url: "https://solongwallet.com",
icon: `${ASSETS_URL}solong.png`,
adapter: SolongWalletAdapter,
}, {
name: "Solflare",
url: "https://solflare.com/access-wallet",
url: "https://solflare.com/access-wallet",
icon: `${ASSETS_URL}solflare.svg`,
}, {
name: "MathWallet",
url: "https://mathwallet.org",
url: "https://mathwallet.org",
icon: `${ASSETS_URL}mathwallet.svg`,
},
LedgerProvider,
@ -47,7 +47,7 @@ const WalletContext = React.createContext<{
}>({
wallet: undefined,
connected: false,
select () {},
select() { },
provider: undefined,
});
@ -59,7 +59,7 @@ export function WalletProvider({ children = null as any }) {
const provider = useMemo(() => WALLET_PROVIDERS.find(({ url }) => url === providerUrl), [providerUrl]);
const wallet = useMemo(function() {
const wallet = useMemo(function () {
if (provider) {
return new (provider.adapter || Wallet)(providerUrl, endpoint) as WalletAdapter;
}
@ -74,12 +74,12 @@ export function WalletProvider({ children = null as any }) {
setConnected(true);
const walletPublicKey = wallet.publicKey.toBase58();
const keyToDisplay =
walletPublicKey.length > 20
? `${walletPublicKey.substring(0, 7)}.....${walletPublicKey.substring(
walletPublicKey.length - 7,
walletPublicKey.length
)}`
: walletPublicKey;
walletPublicKey.length > 20
? `${walletPublicKey.substring(0, 7)}.....${walletPublicKey.substring(
walletPublicKey.length - 7,
walletPublicKey.length
)}`
: walletPublicKey;
notify({
message: "Wallet update",
@ -99,19 +99,19 @@ export function WalletProvider({ children = null as any }) {
return () => {
setConnected(false);
if(wallet) {
if (wallet) {
wallet.disconnect();
}
};
}, [wallet]);
useEffect(() => {
if(wallet && autoConnect) {
if (wallet && autoConnect) {
wallet.connect();
setAutoConnect(false);
}
return () => {}
return () => { }
}, [wallet, autoConnect]);
const [isModalVisible, setIsModalVisible] = useState(false);
@ -135,8 +135,8 @@ export function WalletProvider({ children = null as any }) {
visible={isModalVisible}
okButtonProps={{ style: { display: "none" } }}
onCancel={close}
width={ 400 }>
{WALLET_PROVIDERS.map((provider) => {
width={400}>
{WALLET_PROVIDERS.map((provider, idx) => {
const onClick = function () {
setProviderUrl(provider.url);
setAutoConnect(true);
@ -144,24 +144,25 @@ export function WalletProvider({ children = null as any }) {
}
return (
<Button
size="large"
type={ providerUrl === provider.url ? "primary" : "ghost" }
onClick={onClick}
icon={
<img
alt={`${provider.name}`}
width={ 20 }
height={ 20 }
src={ provider.icon }
style={{ marginRight: 8 }}/>
}
style={{
display: "block",
width: "100%",
textAlign: "left",
marginBottom: 8,
}}>{ provider.name }</Button>
<Button
key={idx}
size="large"
type={providerUrl === provider.url ? "primary" : "ghost"}
onClick={onClick}
icon={
<img
alt={`${provider.name}`}
width={20}
height={20}
src={provider.icon}
style={{ marginRight: 8 }} />
}
style={{
display: "block",
width: "100%",
textAlign: "left",
marginBottom: 8,
}}>{provider.name}</Button>
)
})}
</Modal>
@ -176,10 +177,10 @@ export const useWallet = () => {
connected,
provider,
select,
connect () {
connect() {
wallet ? wallet.connect() : select();
},
disconnect () {
disconnect() {
wallet?.disconnect();
},
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View File

@ -20,7 +20,7 @@
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Wormhole Solana Bridge" />
<meta name="description" content="Metavinci NFT Marketplace" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
@ -35,7 +35,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Metavinci</title>
<title>Metavinci NFT Marketplace</title>
<style type="text/css">
#root {
height: 100%;
@ -61,6 +61,8 @@
min-width: 100%;
display: flex;
flex-direction: column;
background-color: black;
color: white;
}
</style>
<link

View File

@ -1,6 +1,6 @@
{
"short_name": "Wormhole Solana Bridge",
"name": "Wormhole Solana Bridge",
"short_name": "Metavinci NFT Marketplace",
"name": "Metavinci NFT Marketplace",
"icons": [
{
"src": "/android-icon-36x36.png",

View File

@ -24,7 +24,7 @@ body {
.App {
background: #101010 !important;
padding: 0px 72px;
padding: 0px 30px;
}
code {

View File

@ -1,10 +1,8 @@
import React, { useCallback } from 'react';
import React from 'react';
import './index.less';
import { Link, useLocation } from 'react-router-dom';
import { SearchBox } from './searchBox';
import { Button, Popover } from 'antd';
import { ConnectButton, CurrentUserBadge, useWallet,Settings } from '@oyster/common';
import { SettingOutlined } from '@ant-design/icons';
import { Button } from 'antd';
import { ConnectButton, CurrentUserBadge, useWallet } from '@oyster/common';
const UserActions = () => {
return <>

View File

@ -0,0 +1,11 @@
.artist-card {
margin: 15px auto;
background: unset;
border: unset;
}
.artist-card img {
border-radius: 50%;
cursor: pointer;
}

View File

@ -0,0 +1,26 @@
import React from 'react'
import { useHistory } from 'react-router-dom'
import { Card } from 'antd'
import { Artist } from '../../types'
import './index.less'
export const ArtistCard = ({artist}: {artist: Artist}) => {
const history = useHistory()
const handleCoverClick = async () => {
history.push(artist.link)
}
return (
<Card
className="artist-card"
cover={<img alt={artist.name} src={artist.image} onClick={handleCoverClick} />}
>
<div>{artist.name}</div>
<div style={{color: "#ffd691"}}>{artist.itemsAvailable} items available</div>
<div style={{color: "#82dfd5"}}>{artist.itemsSold} sold</div>
</Card>
)
}

View File

@ -0,0 +1,9 @@
.auction-bid {
font-size: 0.8rem;
font-weight: 100;
}
.ant-card-body {
padding: 12px;
}

View File

@ -0,0 +1,28 @@
import React from 'react'
import { useHistory } from 'react-router-dom'
import { Card } from 'antd'
import { Auction } from '../../types'
import './index.less'
export const AuctionCard = ({ auction, sold }: { auction: Auction, sold?: boolean }) => {
const history = useHistory()
const handleCoverClick = async () => {
history.push(auction.link)
}
return (
<Card
hoverable
style={{ width: 210, textAlign: 'left' }}
cover={<img alt={auction.name} src={auction.image} onClick={handleCoverClick} />}
>
<div>{auction.name}</div>
<a href={auction.auctionerLink}>{auction.auctionerName}</a>
<div className="auction-bid">{sold ? 'SOLD' : 'Highest Bid:'} <span style={{color: '#13c2c2'}}>${auction.highestBid}</span> / {auction.solAmt}</div>
</Card>
)
}

View File

@ -1,6 +1,5 @@
import React from 'react';
import { Link, useLocation } from 'react-router-dom';
import { Layout, Button, Popover } from 'antd';
import { Layout } from 'antd';
import './../../App.less';
import './index.less';

View File

@ -3,7 +3,7 @@
background-size: cover;
background-repeat: no-repeat;
background-position-y: center;
height: 300px;
min-height: 300px;
margin-bottom: 1rem;
border-radius: 4px;
}

View File

@ -8,3 +8,11 @@ export interface Auction {
link: string,
image: string,
}
export interface Artist {
name: string,
link: string,
image: string,
itemsAvailable?: number,
itemsSold?: number,
}

View File

@ -8,13 +8,11 @@ section.ant-layout {
}
header.ant-layout-header.App-Bar {
// position: absolute;
width: 100%;
background: transparent;
display: flex;
justify-content: center;
height: 80px;
}
.custom-card {
@ -27,10 +25,14 @@ header.ant-layout-header.App-Bar {
}
footer.ant-layout-footer {
padding: 30px 0;
padding: 10px 0;
width: 100%;
}
.ant-layout-sider {
background-color: unset;
}
a:link {
color: #b480eb;
}

View File

@ -1,11 +1,12 @@
import React from 'react'
import { Layout, Card, Avatar } from 'antd'
import { Layout, Row, Col } from 'antd'
import { Auction } from '../../types'
import { Artist, Auction } from '../../types'
import { MainAuctionCard } from '../../components/MainAuctionCard'
import { AuctionCard } from '../../components/AuctionCard'
import { ArtistCard } from '../../components/ArtistCard'
import './index.less'
import { ArtCard } from '../../components/ArtCard'
const { Meta } = Card;
const { Content, Sider } = Layout
@ -19,22 +20,136 @@ const sampleAuction: Auction = {
image: "http://localhost:3000/img/auction1.jpg",
}
const sampleAuctions: Array<Auction> = [
{
name: "Team Trees",
auctionerName: "NFToros",
auctionerLink: "/address/4321dcba",
highestBid: 23000,
solAmt: 115,
link: "/auction/1234abcd",
image: "http://localhost:3000/img/auction2.jpg",
},
{
name: "Miko 4",
auctionerName: "Hello World",
auctionerLink: "/address/4321dcba",
highestBid: 13000,
solAmt: 75,
link: "/auction/1234abcd",
image: "http://localhost:3000/img/auction3.jpg",
},
{
name: "Tell Me",
auctionerName: "Supper Club",
auctionerLink: "/address/4321dcba",
highestBid: 24000,
solAmt: 120,
link: "/auction/1234abcd",
image: "http://localhost:3000/img/auction4.jpg",
},
{
name: "Saucy",
auctionerName: "Mr. Momo",
auctionerLink: "/address/4321dcba",
highestBid: 23000,
solAmt: 200,
link: "/auction/1234abcd",
image: "http://localhost:3000/img/auction5.jpg",
},
{
name: "Haze",
auctionerName: "Daily Dose",
auctionerLink: "/address/4321dcba",
highestBid: 23000,
solAmt: 200,
link: "/auction/1234abcd",
image: "http://localhost:3000/img/auction6.jpg",
},
{
name: "Wounderground",
auctionerName: "The Maze",
auctionerLink: "/address/4321dcba",
highestBid: 23000,
solAmt: 200,
link: "/auction/1234abcd",
image: "http://localhost:3000/img/auction7.jpg",
},
]
const sampleArtists: Array<Artist> = [
{
name: "Yuzu415",
link: "/artist/1234abcd",
image: "http://localhost:3000/img/artist1.jpeg",
itemsAvailable: 7,
itemsSold: 215,
},
{
name: "Mischa",
link: "/artist/1234abcd",
image: "http://localhost:3000/img/artist2.jpeg",
itemsAvailable: 2,
itemsSold: 215,
},
{
name: "Sammy",
link: "/artist/1234abcd",
image: "http://localhost:3000/img/artist3.jpeg",
itemsAvailable: 7,
itemsSold: 215,
},
{
name: "Wonderful",
link: "/artist/1234abcd",
image: "http://localhost:3000/img/artist4.jpeg",
itemsAvailable: 7,
itemsSold: 215,
},
]
export const HomeView = () => {
// TODO: fetch real data
const auction: Auction = sampleAuction
const auctions: Array<Auction> = sampleAuctions
const soldAuctions: Array<Auction> = sampleAuctions.slice(0, 3)
const artists: Array<Artist> = sampleArtists
return (
<Layout style={{ margin: 0 }}>
<MainAuctionCard auction={sampleAuction} />
<MainAuctionCard auction={auction} />
<Layout>
<Content style={{ display: 'flex', justifyContent: 'space-between', alignContent: 'space-between', flexWrap: 'wrap' }}>
<ArtCard />
<ArtCard />
<ArtCard />
<ArtCard />
<ArtCard />
<ArtCard />
<ArtCard />
<ArtCard />
<Content style={{ display: 'flex', flexWrap: 'wrap' }}>
<Col>
<Row style={{ marginBottom: 10 }}>Trending Auctions</Row>
<Row gutter={16} justify="space-around" style={{ marginRight: 0 }}>
{auctions.map((auction, idx) => (
<Col key={idx} className="gutter-row" style={{ marginBottom: 15 }}>
<AuctionCard auction={auction} />
</Col>
))}
</Row>
<Row style={{ marginBottom: 10 }}>Recently Sold</Row>
<Row gutter={16} justify="space-around" style={{ marginRight: 0 }}>
{soldAuctions.map((auction, idx) => (
<Col key={idx} className="gutter-row" style={{ marginBottom: 15 }}>
<AuctionCard auction={auction} sold={true} />
</Col>
))}
</Row>
</Col>
</Content>
<Sider breakpoint="md" collapsedWidth="0">
<Col>
<Row style={{ marginBottom: 10 }}>Top Artists</Row>
{artists.map((artist, idx) => (
<Row key={idx} style={{ backgroundColor: "#222222" }}>
<ArtistCard artist={artist} />
</Row>
))}
</Col>
</Sider>
</Layout>
</Layout>
);