diff --git a/.env.template b/.env.template new file mode 100644 index 00000000..01484809 --- /dev/null +++ b/.env.template @@ -0,0 +1,7 @@ +NEXT_PUBLIC_TREASURY_ADDRESS= +NEXT_PUBLIC_CANDY_MACHINE_CONFIG= +NEXT_PUBLIC_CANDY_MACHINE_ID= +NEXT_PUBLIC_CANDY_START_DATE= + +NEXT_PUBLIC_SOLANA_NETWORK=devnet +NEXT_PUBLIC_SOLANA_RPC_HOST=https://explorer-api.devnet.solana.com diff --git a/components/Navbar/Navbar.tsx b/components/Navbar/Navbar.tsx deleted file mode 100644 index 51bc407b..00000000 --- a/components/Navbar/Navbar.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import WalletMultiButton from "../WalletMultiButton/WalletMultiButton"; - -export default function Navbar() { - return ( -
-
-

- SOL -

-

Luck

-
- -
- -
-
- ); -} diff --git a/components/ProgressCircle/ProgressCircle.tsx b/components/ProgressCircle/ProgressCircle.tsx deleted file mode 100644 index d9b79cbf..00000000 --- a/components/ProgressCircle/ProgressCircle.tsx +++ /dev/null @@ -1,95 +0,0 @@ -import { useEffect, useState } from "react"; -import { buildStyles, CircularProgressbar } from "react-circular-progressbar"; -import useCandyMachine from "../../hooks/useCandyMachine"; - -import "react-circular-progressbar/dist/styles.css"; - -export default function ProgressCircle() { - const { nftsData } = useCandyMachine(); - const [percent, setPercent] = useState(0); - - useEffect(() => { - let x = 0; - setInterval(() => { - x += 5; - setPercent(x); - }, 2000); - }, []); - - return ( - <> -
- -
- - ); -} - -// const cleanPercentage = (percentage: number) => { -// const isNegativeOrNaN = !Number.isFinite(+percentage) || percentage < 0; // we can set non-numbers to 0 here -// const isTooHigh = percentage > 100; -// return isNegativeOrNaN ? 0 : isTooHigh ? 100 : +percentage; -// }; - -// const Circle = ({ -// color, -// percentage, -// }: { -// color: string; -// percentage: number; -// }) => { -// const r = 500; -// const circ = 2 * Math.PI * r; -// const strokePct = ((100 - percentage) * circ) / 100; // where stroke will start, e.g. from 15% to 100%. - -// return ( -// -// ); -// }; - -// const Text = ({ percentage }: { percentage: number }) => { -// return ( -// -// {percentage.toFixed(0)}% -// -// ); -// }; - -// const Pie = ({ color, percentage }: { color: string; percentage: number }) => { -// const pct = cleanPercentage(percentage); - -// return ( -// -// -// -// -// -// -// -// ); -// }; diff --git a/components/WalletMultiButton/WalletMultiButton.tsx b/components/WalletMultiButton/WalletMultiButton.tsx deleted file mode 100644 index 87bd6974..00000000 --- a/components/WalletMultiButton/WalletMultiButton.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { useWallet } from "@solana/wallet-adapter-react"; -import { useWalletModal } from "@solana/wallet-adapter-react-ui"; -import { useEffect, useMemo, useState } from "react"; -import Countdown from "react-countdown"; -import useCandyMachine from "../../hooks/useCandyMachine"; - -import { CSSTransition } from "react-transition-group"; - -export default function WalletMultiButton() { - const { mintStartDate } = useCandyMachine(); - const { wallet, connected, connecting, connect, publicKey } = useWallet(); - - const { visible, setVisible } = useWalletModal(); - - const [isMintLive, setIsMintLive] = useState(false); - - useEffect(() => { - if (new Date().getTime() > new Date(mintStartDate).getTime()) { - setIsMintLive(true); - } - }, []); - - async function handleClick() { - console.log("click"); - - if (isMintLive) { - if (!connected && !wallet) { - setVisible(!visible); - } - - if (wallet && !connected) { - window.open(wallet.url, "_blank"); - } - } - } - - const content = useMemo(() => { - if (!isMintLive) - return ( - setIsMintLive(true)} - /> - ); - if (connecting) return "Connecting ..."; - if (connected && publicKey) - return `${publicKey?.toString().slice(0, 10)}...`; - if (wallet) return `Install ${wallet.name} Wallet`; - return "Choose Wallet"; - }, [connecting, connected, wallet, isMintLive, mintStartDate, publicKey]); - - return ( -
- - - - setVisible(!visible)} - className="w-5 h-5 ml-4 transition-all duration-300 cursor-pointer hover:rotate-180 tranform hover:opacity-60" - viewBox="0 0 20 20" - fill="white" - > - - - -
- ); -} diff --git a/consts/index.ts b/consts/index.ts deleted file mode 100644 index 903a4eec..00000000 --- a/consts/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const NUM_TICKETS = 100; -export const TICKET_PRICE = 0.1; diff --git a/package.json b/package.json index c357a53a..48b54b6c 100644 --- a/package.json +++ b/package.json @@ -17,14 +17,11 @@ "@solana/wallet-adapter-react-ui": "^0.5.0", "@solana/wallet-adapter-wallets": "^0.10.0", "@solana/web3.js": "^1.29.2", - "@types/react-transition-group": "^4.4.4", "next": "11.1.2", "react": "17.0.2", - "react-circular-progressbar": "^2.0.4", "react-countdown": "^2.3.2", "react-dom": "17.0.2", - "react-hot-toast": "^2.1.1", - "react-transition-group": "^4.4.2" + "react-hot-toast": "^2.1.1" }, "devDependencies": { "@types/react": "17.0.27", diff --git a/pages/index.tsx b/pages/index.tsx index c9119dc6..3a3f8d68 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,76 +1,156 @@ -import { useWallet } from "@solana/wallet-adapter-react"; -import { useMemo } from "react"; -import Navbar from "../components/Navbar/Navbar"; -import ProgressCircle from "../components/ProgressCircle/ProgressCircle"; -import { NUM_TICKETS, TICKET_PRICE } from "../consts"; +/* eslint-disable react-hooks/exhaustive-deps */ +import Head from "next/head"; +import { useEffect, useState } from "react"; + +import { WalletMultiButton } from "@solana/wallet-adapter-react-ui"; import useCandyMachine from "../hooks/useCandyMachine"; +import useWalletBalance from "../hooks/useWalletBalance"; +import { useWallet } from "@solana/wallet-adapter-react"; + +import { Toaster } from "react-hot-toast"; +import Countdown from "react-countdown"; +import useWalletNfts from "../hooks/useWalletNFTs"; +import AnNFT from "../components/AnNFT/AnNFT"; export default function Home() { - const { nftsData, startMint, isMinting, mintStartDate } = useCandyMachine(); - const { wallet, connected, publicKey } = useWallet(); + const [balance] = useWalletBalance(); + const { + isSoldOut, + mintStartDate, + isMinting, + startMint, + startMintMultiple, + nftsData, + } = useCandyMachine(); + + const [isLoading, nfts] = useWalletNfts(); + + const { connected } = useWallet(); - const buttonContent = useMemo(() => { - if (isMinting) return "Minting ticket..."; - return "Buy a ticket"; - }, [isMinting]); + const [isMintLive, setIsMintLive] = useState(false); - async function handleClick() { - if ( - wallet && - connected && - publicKey && - new Date().getTime() > new Date(mintStartDate).getTime() - ) { - console.log("Starting mint"); - await startMint(); - } + useEffect(() => { + if (new Date(mintStartDate).getTime() < Date.now()) { + setIsMintLive(true); } + }, []); + + const MintMany = () => { + const [mintCount, setMintCount] = useState(5); return ( -
- -
-
-

- Feeling lucky? -

-

- The current payout is{" "} - - {( - (NUM_TICKETS * TICKET_PRICE * 0.9) / - TICKET_PRICE - ).toFixed(2)} - x - -

+ <> + - -

{TICKET_PRICE}/ticket

+ setMintCount((e.target as any).value)} + /> +

min 2; max 10;

+ + ); + }; -

- {nftsData.itemsRemaining} tickets remaining -

-
+ return ( + <> + + next-candy-machine + + + - -
+
+ +
+

next-candy-machine

+
+ {connected && ( +
+

balance

+

+ {balance.toFixed(2)} +

+

+ SOL +

+
+ )} + +
- ); + {connected && ( +

+ Available/Minted/Total:{" "} + {nftsData.itemsRemaining}/{nftsData.itemsRedeemed}/ + {nftsData.itemsAvailable} +

+ )} +
+ {connected ? ( + <> + {new Date(mintStartDate).getTime() < Date.now() ? ( + <> + {isSoldOut ? ( +

SOLD OUT

+ ) : ( + <> +
+

Mint One

+ +
+
+

Mint Many

+ +
+ + )} + + ) : ( + completed && setIsMintLive(true)} + onComplete={() => setIsMintLive(true)} + /> + )} + + ) : ( +

connect wallet to mint

+ )} +
+
+

My NFTs

+
+ {(nfts as any).map((nft: any, i: number) => { + return ; + })} +
+
+
+ + ); } diff --git a/styles/Home.module.css b/styles/Home.module.css new file mode 100644 index 00000000..35454bb7 --- /dev/null +++ b/styles/Home.module.css @@ -0,0 +1,121 @@ +.container { + min-height: 100vh; + padding: 0 0.5rem; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100vh; +} + +.main { + padding: 5rem 0; + flex: 1; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.footer { + width: 100%; + height: 100px; + border-top: 1px solid #eaeaea; + display: flex; + justify-content: center; + align-items: center; +} + +.footer a { + display: flex; + justify-content: center; + align-items: center; + flex-grow: 1; +} + +.title a { + color: #0070f3; + text-decoration: none; +} + +.title a:hover, +.title a:focus, +.title a:active { + text-decoration: underline; +} + +.title { + margin: 0; + line-height: 1.15; + font-size: 4rem; +} + +.title, +.description { + text-align: center; +} + +.description { + line-height: 1.5; + font-size: 1.5rem; +} + +.code { + background: #fafafa; + border-radius: 5px; + padding: 0.75rem; + font-size: 1.1rem; + font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, + Bitstream Vera Sans Mono, Courier New, monospace; +} + +.grid { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + max-width: 800px; + margin-top: 3rem; +} + +.card { + margin: 1rem; + padding: 1.5rem; + text-align: left; + color: inherit; + text-decoration: none; + border: 1px solid #eaeaea; + border-radius: 10px; + transition: color 0.15s ease, border-color 0.15s ease; + width: 45%; +} + +.card:hover, +.card:focus, +.card:active { + color: #0070f3; + border-color: #0070f3; +} + +.card h2 { + margin: 0 0 1rem 0; + font-size: 1.5rem; +} + +.card p { + margin: 0; + font-size: 1.25rem; + line-height: 1.5; +} + +.logo { + height: 1em; + margin-left: 0.5rem; +} + +@media (max-width: 600px) { + .grid { + width: 100%; + flex-direction: column; + } +} diff --git a/styles/globals.css b/styles/globals.css index 650b51c2..6138cf9c 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -1,23 +1,20 @@ -@import url("https://cdn.rawgit.com/mfd/09b70eb47474836f25a21660282ce0fd/raw/e06a670afcb2b861ed2ac4a1ef752d062ef6b46b/Gilroy.css"); - @tailwind base; @tailwind components; @tailwind utilities; html, body { - padding: 0; - margin: 0; - font-family: "Gilroy", -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, - Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, - sans-serif; + padding: 0; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, + Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; } a { - color: inherit; - text-decoration: none; + color: inherit; + text-decoration: none; } * { - box-sizing: border-box; + box-sizing: border-box; } diff --git a/tailwind.config.js b/tailwind.config.js index b9472292..d7ff5845 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,5 +1,4 @@ module.exports = { - mode: "jit", purge: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}"], darkMode: false, theme: { diff --git a/yarn.lock b/yarn.lock index fdb10be9..2e8e52b1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -64,13 +64,6 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" - integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== - dependencies: - regenerator-runtime "^0.13.4" - "@babel/types@7.15.0": version "7.15.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd" @@ -649,22 +642,6 @@ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== -"@types/react-transition-group@^4.4.4": - version "4.4.4" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.4.tgz#acd4cceaa2be6b757db61ed7b432e103242d163e" - integrity sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug== - dependencies: - "@types/react" "*" - -"@types/react@*": - version "17.0.35" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.35.tgz#217164cf830267d56cd1aec09dcf25a541eedd4c" - integrity sha512-r3C8/TJuri/SLZiiwwxQoLAoavaczARfT9up9b4Jr65+ErAUX3MIkU0oMOQnrpfgHme8zIqZLX7O5nnjm5Wayw== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - "@types/react@17.0.27": version "17.0.27" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.27.tgz#6498ed9b3ad117e818deb5525fa1946c09f2e0e6" @@ -1645,14 +1622,6 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dom-helpers@^5.0.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" - integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== - dependencies: - "@babel/runtime" "^7.8.7" - csstype "^3.0.2" - domain-browser@4.19.0: version "4.19.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.19.0.tgz#1093e17c0a17dbd521182fe90d49ac1370054af1" @@ -3604,7 +3573,7 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -3715,11 +3684,6 @@ raw-body@2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" -react-circular-progressbar@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/react-circular-progressbar/-/react-circular-progressbar-2.0.4.tgz#5b04a9cf6be8c522c180e4e99ec6db63677335b0" - integrity sha512-OfX0ThSxRYEVGaQSt0DlXfyl5w4DbXHsXetyeivmoQrh9xA9bzVPHNf8aAhOIiwiaxX2WYWpLDB3gcpsDJ9oww== - react-countdown@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/react-countdown/-/react-countdown-2.3.2.tgz#4cc27f28f2dcd47237ee66e4b9f6d2a21fc0b0ad" @@ -3758,16 +3722,6 @@ react-refresh@0.8.3: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f" integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg== -react-transition-group@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470" - integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg== - dependencies: - "@babel/runtime" "^7.5.5" - dom-helpers "^5.0.1" - loose-envify "^1.4.0" - prop-types "^15.6.2" - react@17.0.2: version "17.0.2" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"