Skip to content
This repository has been archived by the owner on Dec 11, 2021. It is now read-only.

Develop auction and mint pages #1

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
bf9cedb
Update footer and auction landing
thebeyondr Nov 16, 2021
7382162
Add responsive styles
thebeyondr Nov 17, 2021
f90be69
Switched to quiver web3 library
thebeyondr Nov 23, 2021
f3fb027
Update read/write flow for contracts and create public mint page
thebeyondr Nov 24, 2021
b07c302
Update UI for public mint page
thebeyondr Nov 26, 2021
0e7071f
Add modal and batchMint
thebeyondr Nov 28, 2021
4e626fa
Add bid history modal and toast to auction landing page
thebeyondr Nov 29, 2021
fa5a867
Update card hover animations
thebeyondr Nov 29, 2021
d12782e
Removed custom modal files
thebeyondr Nov 29, 2021
365230d
Update modals on public mint
thebeyondr Nov 29, 2021
446c172
Update mint UX and batchMint parameters
thebeyondr Dec 1, 2021
5d2f333
Update batchMint test variables
thebeyondr Dec 2, 2021
0f5b356
Add Zora zdk testing
thebeyondr Dec 2, 2021
5ea5146
Add fetchGraph to quiver
thebeyondr Dec 3, 2021
1a1fb67
Add auction subgraph interaction
thebeyondr Dec 5, 2021
69337ec
Add metadata fetching for songs
thebeyondr Dec 5, 2021
f525019
Add modals in a test state
thebeyondr Dec 6, 2021
079eb2a
Add ReadyForMint Modal
thebeyondr Dec 6, 2021
3dfe3b9
Add ReservingSong modal
thebeyondr Dec 6, 2021
ab4a632
Add Minting Song modal
thebeyondr Dec 6, 2021
8f1d947
Add Minting in progress modal
thebeyondr Dec 6, 2021
19ed648
Add voucher explained page
thebeyondr Dec 6, 2021
dcfebcb
feat(): added support for static json rpc provider to interact with c…
midgerate Dec 6, 2021
8f96ce2
Add card-to-subgraph connection
thebeyondr Dec 8, 2021
f8a6a1c
feat(): basic auction page integration done
midgerate Dec 8, 2021
2cea69e
Update bid history, add modal for placing bid
thebeyondr Dec 9, 2021
9a6495a
feat(): handle settle auction and other integrations
midgerate Dec 9, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
734 changes: 734 additions & 0 deletions components/Auction.tsx

Large diffs are not rendered by default.

165 changes: 165 additions & 0 deletions components/AuctionSongCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
import {
AspectRatio,
Box,
BoxProps,
Button,
Heading,
HStack,
Image,
Text,
VStack,
Wrap,
} from '@chakra-ui/react';
import { DateTime } from 'luxon';
import React, { useMemo } from 'react';
import { SongMetadata } from '../lib/types';
import { SONGADAY_CONTRACT_ADDRESS } from '../utils/constants';
import { getSongAttributeValue, youTubeGetID } from '../utils/helpers';
import { parseTokenURI } from '../web3/helpers';
import YoutubeEmbed from './YoutubeEmbed';

const SHOULD_AUTOPLAY = process.env.NODE_ENV === 'production';

// The contract address for all the songs on OpenSea.

interface SongCardProps {
song: SongMetadata;
}

function AuctionSongCard({ song }: BoxProps & SongCardProps) {
const date = DateTime.fromFormat(getSongAttributeValue(song?.attributes, 'Date'), 'yyyy-MM-dd');

const subtitleDateString = useMemo(() => date.toLocaleString(DateTime.DATE_FULL), [date]);

// Get the `tokenId` from the url param if it exists, otherwise try and
// get it from the generated list of ids.
const finalTokenId = song.token_id;

// const { data, loading: niftyLoading, isHydrating, error, openSeaUri } = useNifty(finalTokenId);

// const ownedByJonathan = data?.ownerships[0]?.owner?.id === JONATHAN_ID;

// const { account, provider } = Account.useContainer();
// const [isBuyLoading, setIsBuyLoading] = useState(false);
// const [showBuyButton, setShowBuyButton] = useState(false);

// useEffect(() => {
// setShowBuyButton(finalTokenId && openSeaPort && ownedByJonathan);
// }, [openSeaPort, ownedByJonathan, finalTokenId]);

// const buyAsset = async () => {
// if (openSeaPort && showBuyButton) {
// setIsBuyLoading(true);
// setIsModalOpen(true);
// try {
// const order = await openSeaPort?.api.getOrder({
// side: 1,
// token_id: finalTokenId,
// asset_contract_address: ASSET_CONTRACT_ADDRESS,
// });
// await openSeaPort?.fulfillOrder({ order, accountAddress: address });
// toast({
// title: 'Transaction Successful!',
// description: 'Thank you for your purchase',
// status: 'success',
// position: 'top',
// });
// setIsBuyLoading(false);
// setIsModalOpen(false);
// setShowBuyButton(false);
// } catch (error) {
// setIsBuyLoading(false);
// setIsModalOpen(false);
// toast({
// title: 'An error has occurred',
// description: error.message,
// status: 'error',
// position: 'top',
// });
// }
// }
// };

return (
<VStack
{...{
borderWidth: '1px',
borderColor: 'gray.200',
borderRadius: 'md',
_hover: {
shadow: 'lg',
transform: 'scale(1.02)',
},
transition: 'all 200ms ease-out',
}}
spacing="2"
alignItems="stretch"
bg="white"
>
<HStack p={3} justify="space-between" spacing="4">
<VStack align="stretch" flex="1" minW="0">
<Heading as="h3" fontSize="2xl" isTruncated>
{song.name}
</Heading>

<Text as="h4" fontSize="xs" isTruncated>
{subtitleDateString}
</Text>
</VStack>
<VStack
borderRadius="1"
borderColor="black"
justifyContent="center"
alignItems="self-start"
>
<Text fontWeight="bold" fontSize="xl">
#{song.token_id}
</Text>

{/* <Text whiteSpace="nowrap" fontSize="sm" textTransform="uppercase">
{calendarDateString}
</Text> */}
</VStack>
</HStack>

<AspectRatio ratio={16 / 9}>
{song.youtube_url ? (
<YoutubeEmbed id={youTubeGetID(song.youtube_url)} autoPlay={SHOULD_AUTOPLAY} />
) : (
<Image w="full" h="full" src={parseTokenURI(song.image)} />
)}
</AspectRatio>

<VStack flex="1" p="2" spacing={4} align="stretch">
<Text>{song.description}</Text>

<Wrap>
{song?.attributes?.map((attribute) => (
<Button key={attribute.value} as="a" zIndex="1" size="xs">
{attribute.trait_type}: {attribute.value}
</Button>
))}
</Wrap>

<HStack justifyContent="space-between">
<Button
as="a"
size="xs"
variant="ghost"
href={`https://testnets.opensea.io/assets/${SONGADAY_CONTRACT_ADDRESS}/${finalTokenId}`}
target="_blank"
rel="noopener noreferrer"
zIndex="1"
>
See on OpenSea
</Button>
</HStack>
</VStack>

{/* margin collapse fix */}
<Box />
</VStack>
);
}

export default AuctionSongCard;
26 changes: 8 additions & 18 deletions components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { Stack, Box, Text, Container, Link } from '@chakra-ui/react';

const Footer = () => {
const footerNav = [
// {
// key: '1',
// href: 'https://discord.gg/p3aW7F7J5h',
// name: 'Discord',
// },
{
key: '1',
href: 'http://enter.songaday.world/',
name: 'Discord',
},
{
key: '2',
href: 'https://twitter.com/songadaymann',
Expand All @@ -31,22 +31,12 @@ const Footer = () => {
];
return (
<Box bg="teal.50" color="gray.700">
<Container
as={Stack}
spacing={6}
py={8}
direction="column"
align={{ base: 'flex-start', md: 'center' }}
>
<Stack
align={{ base: 'flex-start', md: 'center' }}
direction={{ base: 'column', md: 'row' }}
spacing={6}
>
<Container as={Stack} spacing={6} py={8} direction="column" align="center">
<Stack align="center" direction={{ base: 'column', md: 'row' }} spacing={6}>
{footerNav.map((link) => (
// eslint-disable-next-line react/jsx-key

<Link key={link.key} href={link.href} fontSize={{ base: 'xl', md: 'lg' }} isExternal>
<Link key={link.key} href={link.href} isExternal>
{link.name}
</Link>
))}
Expand Down
22 changes: 12 additions & 10 deletions components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ import {
} from '@chakra-ui/react';
import NextLink from 'next/link';
import React from 'react';
import { Account } from '../containers/Account';
// import { Account } from '../containers/Account';
import { truncateHash } from '../lib/helpers';
import { useDidHydrate } from '../lib/useDidHydrate';
import { useWallet } from '../web3/WalletContext';

function Navbar() {
const { connect, disconnect, account, loading } = Account.useContainer();
// const { connect, disconnect, account, loading } = Account.useContainer();
const { connectWallet, disconnect, address, isConnecting } = useWallet();
const didHydrate = useDidHydrate();
const { isOpen, onOpen, onClose } = useDisclosure();

Expand Down Expand Up @@ -65,12 +67,12 @@ function Navbar() {
{links}
</HStack>
<Box display={{ base: 'none', md: 'block' }}>
{didHydrate && account ? (
{didHydrate && address ? (
<Menu>
<MenuButton as={Button}>{truncateHash(account)}</MenuButton>
<MenuButton as={Button}>{truncateHash(address)}</MenuButton>
<MenuList>
<MenuItem as="div" p="0">
<NextLink href={`/a/${account}`} passHref>
<NextLink href={`/a/${address}`} passHref>
<Link
px="3"
py="2"
Expand All @@ -88,7 +90,7 @@ function Navbar() {
</MenuList>
</Menu>
) : (
<Button onClick={connect} isLoading={loading}>
<Button onClick={connectWallet} isLoading={isConnecting}>
Connect Wallet
</Button>
)}
Expand Down Expand Up @@ -120,12 +122,12 @@ function Navbar() {
</DrawerHeader>
<DrawerBody>
<Box display={{ md: 'none' }}>
{didHydrate && account ? (
{didHydrate && address ? (
<Menu>
<MenuButton as={Button}>{truncateHash(account)}</MenuButton>
<MenuButton as={Button}>{truncateHash(address)}</MenuButton>
<MenuList>
<MenuItem as="div" p="0">
<NextLink href={`/a/${account}`} passHref>
<NextLink href={`/a/${address}`} passHref>
<Link
px="3"
py="2"
Expand All @@ -143,7 +145,7 @@ function Navbar() {
</MenuList>
</Menu>
) : (
<Button onClick={connect} isLoading={loading}>
<Button onClick={connectWallet} isLoading={isConnecting}>
Connect Wallet
</Button>
)}
Expand Down
6 changes: 4 additions & 2 deletions components/SongBuyCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { OpenSeaPort } from 'opensea-js';
import React, { useState } from 'react';
import { Account } from '../containers/Account';
import { OpenSeaSellTrait, OpenSeaSong } from '../lib/types';
import { useWallet } from '../web3/WalletContext';

interface SongBuyCardProps {
song: OpenSeaSong;
Expand All @@ -30,7 +31,8 @@ export function SongBuyCard({
}: SongBuyCardProps): JSX.Element {
const [isLoading, setIsLoading] = useState(false);

const { account, provider } = Account.useContainer();
// const { account, provider } = Account.useContainer();
const { address, provider } = useWallet();
const toast = useToast();

const buyAsset = async () => {
Expand All @@ -43,7 +45,7 @@ export function SongBuyCard({
token_id: song.token_id,
asset_contract_address: song.asset_contract.address,
});
await openSeaPort?.fulfillOrder({ order, accountAddress: account });
await openSeaPort?.fulfillOrder({ order, accountAddress: address });
toast({
title: 'Transaction Successful!',
description: 'Thank you for your purchase',
Expand Down
19 changes: 12 additions & 7 deletions components/SongCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ import { DateTime } from 'luxon';
import Link from 'next/link';
import { OpenSeaPort } from 'opensea-js';
import React, { useEffect, useMemo, useState } from 'react';
import { Account } from '../containers/Account';
// import { Account } from '../containers/Account';
import { Filters } from '../containers/Filters';
import tokenIds from '../generated/tokenIds';
import { formatNumber } from '../lib/helpers';
import { Song } from '../lib/types';
import { useNifty } from '../lib/useNifty';
import { useWallet } from '../web3/WalletContext';
import { FilterTag } from './FilterTag';
import { OwnershipButton } from './OwnershipButton';
import YoutubeEmbed from './YoutubeEmbed';
Expand Down Expand Up @@ -71,7 +72,8 @@ function SongCard({

const ownedByJonathan = data?.ownerships[0]?.owner?.id === JONATHAN_ID;

const { account, provider } = Account.useContainer();
const { address, provider } = useWallet();
// const { account, provider } = Account.useContainer();
const toast = useToast();
const [isBuyLoading, setIsBuyLoading] = useState(false);
const [showBuyButton, setShowBuyButton] = useState(false);
Expand All @@ -90,7 +92,7 @@ function SongCard({
token_id: finalTokenId,
asset_contract_address: ASSET_CONTRACT_ADDRESS,
});
await openSeaPort?.fulfillOrder({ order, accountAddress: account });
await openSeaPort?.fulfillOrder({ order, accountAddress: address });
toast({
title: 'Transaction Successful!',
description: 'Thank you for your purchase',
Expand Down Expand Up @@ -118,9 +120,12 @@ function SongCard({
{...(card && {
borderWidth: '1px',
borderColor: 'gray.200',
borderRadius: 'sm',
_hover: { shadow: 'sm' },
transition: 'all 100ms linear',
borderRadius: 'md',
_hover: {
shadow: 'lg',
transform: 'scale(1.02)',
},
transition: 'all 200ms ease-out',
})}
spacing="2"
alignItems="stretch"
Expand Down Expand Up @@ -277,7 +282,7 @@ function SongCard({
</Grid>

<SimpleGrid gap="2" minChildWidth="8rem">
{song?.tags.map((tag) => (
{song?.tags?.map((tag) => (
<Link key={tag} href={appendFilters({ ...filters, tag })} passHref shallow>
<Button
as="a"
Expand Down
Loading