From d9f6262a4c7b09ea16cf216cdd51a90b0e6b0a09 Mon Sep 17 00:00:00 2001 From: adetyaz Date: Sat, 17 Aug 2024 13:53:11 +0100 Subject: [PATCH] fix: data flow and architecture --- package.json | 2 + src/app/[id]/page.tsx | 161 +++++----- src/app/globals.css | 6 + src/app/layout.tsx | 7 +- src/app/page.tsx | 49 ++- src/components/avatar-card.tsx | 26 ++ src/components/avatar-leaderboard.js | 392 ------------------------ src/components/avatar-leaderboard.tsx | 197 ++++++++++++ src/components/avatars.js | 39 --- src/components/claim-nft-modal.tsx | 69 +++++ src/components/claim-nft-popup.js | 186 ----------- src/components/claim-nft.js | 232 -------------- src/components/claim-nft.tsx | 141 +++++++++ src/components/congratulations.js | 125 -------- src/components/connect-wallet-modal.js | 84 ----- src/components/connect-wallet-modal.tsx | 15 + src/components/create-wallet.jsx | 92 ------ src/components/footer.js | 131 -------- src/components/footer.tsx | 74 +++++ src/components/leaderboard.js | 84 ----- src/components/leaderboard.tsx | 66 ++++ src/components/minted-modal.tsx | 48 +++ src/components/nfc-mint-popup.js | 161 ---------- src/types/types.ts | 23 ++ src/utils/queries.ts | 29 ++ tsconfig.json | 2 +- yarn.lock | 21 ++ 27 files changed, 820 insertions(+), 1642 deletions(-) create mode 100644 src/components/avatar-card.tsx delete mode 100644 src/components/avatar-leaderboard.js create mode 100644 src/components/avatar-leaderboard.tsx delete mode 100644 src/components/avatars.js create mode 100644 src/components/claim-nft-modal.tsx delete mode 100644 src/components/claim-nft-popup.js delete mode 100644 src/components/claim-nft.js create mode 100644 src/components/claim-nft.tsx delete mode 100644 src/components/congratulations.js delete mode 100644 src/components/connect-wallet-modal.js create mode 100644 src/components/connect-wallet-modal.tsx delete mode 100644 src/components/create-wallet.jsx delete mode 100644 src/components/footer.js create mode 100644 src/components/footer.tsx delete mode 100644 src/components/leaderboard.js create mode 100644 src/components/leaderboard.tsx create mode 100644 src/components/minted-modal.tsx delete mode 100644 src/components/nfc-mint-popup.js create mode 100644 src/types/types.ts create mode 100644 src/utils/queries.ts diff --git a/package.json b/package.json index f924b09..b262235 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,10 @@ "@react-three/postprocessing": "^2.16.2", "@readyplayerme/visage": "^5.2.1", "@tanstack/react-query": "^5.51.23", + "@tanstack/react-query-devtools": "^5.51.23", "@wagmi/core": "^2.11.5", "@web3modal/wagmi": "^5.0.11", + "axios": "^1.7.4", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "ethers": "^6.13.1", diff --git a/src/app/[id]/page.tsx b/src/app/[id]/page.tsx index 6670fd8..2ddca66 100644 --- a/src/app/[id]/page.tsx +++ b/src/app/[id]/page.tsx @@ -6,91 +6,78 @@ import { useAccount } from 'wagmi' import { ConnectWallet } from '@/components/connect-wallet' import { useEffect, useState } from 'react' import { ConnectWalletModal } from '@/components/connect-wallet-modal' -import { NfcMintPopUp } from '@/components/nfc-mint-popup' +import { MintedModal } from '@/components/minted-modal' import { ClaimNft } from '@/components/claim-nft' +import { toast } from 'react-toastify' -import { CreateWallet } from '@/components/create-wallet' import { VoiceAssistant } from '@/components/voice-assistant' +import { useQueries, useQuery } from '@tanstack/react-query' +import { getAvatars, getPhygital, getWebXR } from '@/utils/queries' +import { AvatarType } from '@/types/types' export default function Home({ params }: { params: { id: string } }) { const { id } = params - const [unlockModal, setUnlockModal] = useState(false) - const [unlocked, setUnlocked] = useState(true) const [unlockClaimed, setUnlockClaimed] = useState(false) - const [loading, setLoading] = useState(false) - const [phygitalData, setPhygitalData] = useState([]) - const [webXrData, setWebXrData] = useState([]) - const [avatar, setAvatar] = useState([]) - const [productInfo, setProductInfo] = useState('') const account = useAccount() - const closeCongratulations = () => { - setUnlockModal(false) - } - - const closeClaimed = () => { - setUnlockClaimed(false) - } - - const fetchPhygitalData = async () => { - setLoading(true) - try { - const res = await fetch(`${process.env.NEXT_PUBLIC_URI}/phygitals/${id}`) - - const webxr = await fetch( - `${process.env.NEXT_PUBLIC_URI}/webxr/phygital/${id}` - ) - - const avatarRes = await fetch( - `${process.env.NEXT_PUBLIC_URI}/avatars/phygital/${id}` - ) - - const data = await res.json() - const webdata = await webxr.json() - const avatardata = await avatarRes.json() - - // console.log(data) - // console.log(avatardata) - - setProductInfo(data.product_info) - setPhygitalData(data) - setWebXrData(webdata) - setAvatar(avatardata) - setLoading(false) - } catch (error) { - console.log(error) - } - } + const results = useQueries({ + queries: [ + { + queryKey: ['phygital'], + queryFn: () => getPhygital(id), + }, + { + queryKey: ['webxr'], + queryFn: () => getWebXR(id), + }, + { + queryKey: ['avatar'], + queryFn: async () => { + const avatars = await getAvatars() + return avatars.filter( + (avatar: AvatarType) => avatar.phygital_id === id + ) + }, + }, + ], + }) + + const [phygitalResult, webxrResult, avatarResult] = results useEffect(() => { - fetchPhygitalData() - setTimeout(() => { - setUnlockModal(true) - }, 3000) + setUnlockClaimed(true) + }, 60000) }, []) - // useEffect(() => { - // if (account.address) { - // setTimeout(() => { - // setUnlockClaimed(true) - // }, 3000) - // } - // }, []) + const closeClaimed = () => { + setUnlockClaimed(false) + } const removePrefix = (uri: any) => { return uri?.substring(7, uri.length) } - if (loading) + if ( + phygitalResult.isLoading || + webxrResult.isLoading || + avatarResult.isLoading + ) return (
- loading + loading
) + if (phygitalResult.isError || webxrResult.isError || avatarResult.isError) + return toast.error('Error fetching data') + + const phygital = phygitalResult.data + const webxr = webxrResult.data + const avatar = avatarResult.data + return (
@@ -101,58 +88,58 @@ export default function Home({ params }: { params: { id: string } }) {
- +
- +
- {!account.address && ( -
+ {/* {!account.address && ( +
)} - {account.address && unlockModal && ( -
- -
- )} + */} + {/*
+ +
*/} + {unlockClaimed && ( -
+
- -
)}
diff --git a/src/app/globals.css b/src/app/globals.css index 7328bdf..d2f0ba6 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -75,6 +75,12 @@ } } +@layer components { + .modal { + @apply absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2; + } +} + .a-enter-vr-button { display: none; } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index bf9f753..8930e57 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -4,10 +4,11 @@ import './globals.css' import 'react-toastify/dist/ReactToastify.css' import { cn } from '@/lib/utils' import Providers from '@/lib/providers' -import { config } from '@/lib/wagmi' -import Web3ModalProvider from '@/lib/providers' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' + import Script from 'next/script' import AppKitProvider from '@/lib/providers' +import { ToastContainer } from 'react-toastify' const fontSans = FontSans({ subsets: ['latin'], @@ -72,7 +73,9 @@ export default function RootLayout({ fontSans.variable )} > + {children} + diff --git a/src/app/page.tsx b/src/app/page.tsx index f095565..78e6f46 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,4 +1,4 @@ -"use client"; +'use client' import Link from 'next/link' import LeaderBoard from '@/components/leaderboard' import AvatarLeaderboard from '@/components/avatar-leaderboard' @@ -9,16 +9,7 @@ import { ConnectWallet } from '@/components/connect-wallet' export default function Home() { return (
-
+
Logo @@ -50,25 +41,31 @@ export default function Home() {
-
- -
-
- -
-
WebXR
-
Experience & Interact
-
- Interact with unique AI-powered avatars and brand ambassadors. Buy a phygital and own the avatar. Customize and rise to the Leaderboard. +
+
+
+ +
+
WebXR
+
+ Experience & Interact +
+
+ Interact with unique AI-powered avatars and brand ambassadors. Buy a + phygital and own the avatar. Customize and rise to the Leaderboard.
-
+
-
-
+
+
{/* Background */} - AI Avatar + AI Avatar
@@ -78,7 +75,7 @@ export default function Home() {
- +
diff --git a/src/components/avatar-card.tsx b/src/components/avatar-card.tsx new file mode 100644 index 0000000..1487557 --- /dev/null +++ b/src/components/avatar-card.tsx @@ -0,0 +1,26 @@ +import Link from 'next/link' +import { Avatar } from '@readyplayerme/visage' +import { AvatarType } from '@/types/types' + +const AvatarCard = ({ + phygitalId, + url, +}: { + phygitalId: string + url: string +}) => { + return ( +
+ +
+
+
+ +
+
+ +
+ ) +} + +export default AvatarCard diff --git a/src/components/avatar-leaderboard.js b/src/components/avatar-leaderboard.js deleted file mode 100644 index e5a3a3d..0000000 --- a/src/components/avatar-leaderboard.js +++ /dev/null @@ -1,392 +0,0 @@ -import { useState, useEffect } from 'react' -import { Avatar } from '@readyplayerme/visage' -import Link from 'next/link' - -const baseUri = process.env.NEXT_PUBLIC_URI || 'https://app.myriadflow.com' - -const AvatarLeaderboard = () => { - const [avatars, setAvatars] = useState([]) - const [fantokens, setFantokens] = useState([]) - const [topAvatars, setTopAvatars] = useState([]) - - const fetchData = async () => { - try { - const avatarsResponse = await fetch(`${baseUri}/avatars/all`) - const fantokensResponse = await fetch(`${baseUri}/fantoken/all`) - const avatarsData = await avatarsResponse.json() - const fantokensData = await fantokensResponse.json() - - setAvatars(avatarsData) - setFantokens(fantokensData) - - const avatarTokenCount = avatarsData.reduce((count, avatar) => { - count[avatar.phygital_id] = fantokensData.filter( - (token) => token.phygital_id === avatar.phygital_id - ).length - return count - }, {}) - - const topAvatarsData = Object.entries(avatarTokenCount) - .sort(([, countA], [, countB]) => countB - countA) - .slice(0, 3) - .map(([phygitalId, count]) => { - const avatar = avatarsData.find((a) => a.phygital_id === phygitalId) - return { ...avatar, count } - }) - - setTopAvatars(topAvatarsData) - - console.log(topAvatarsData) - } catch (error) { - console.error('Error fetching data:', error) - } - } - - useEffect(() => { - fetchData() - }, []) - - return ( -
-
- Avatar Leaderboard -
-
-
- This Week's Top performing AI-Powered Brand Ambassadors -
-
- -
- {topAvatars.length >= 3 && ( - <> -
- {/* */} - -
- -
- SILVER -
-
-
- No. tokens: {topAvatars[1].count} -
- - -
- -
- {/* */} - -
- - -
- GOLD -
-
-
- No. tokens: {topAvatars[0].count} -
- - -
- -
- {/* */} - - -
- No. tokens: {topAvatars[2].count} -
- - -
- - )} -
- -
- {/* Left Image */} - Left - - {/* Right Image */} - Right - -
- Rewarding Creators, Owners and Supporters. -
-
- -
-
-
-

Create Profile

-

& Earn Rewards

- -
-
-
- - - -
- ) -} - -export default AvatarLeaderboard diff --git a/src/components/avatar-leaderboard.tsx b/src/components/avatar-leaderboard.tsx new file mode 100644 index 0000000..ca53541 --- /dev/null +++ b/src/components/avatar-leaderboard.tsx @@ -0,0 +1,197 @@ +import { useState, useEffect } from 'react' +import { Avatar } from '@readyplayerme/visage' +import Link from 'next/link' +import { useQueries, useQuery } from '@tanstack/react-query' +import { getAvatars, getFanTokens } from '@/utils/queries' +import { AvatarType, FanTokenType } from '@/types/types' + +const AvatarLeaderboard = () => { + const getTopAvatars = (avatars: AvatarType[], fantokens: FanTokenType[]) => { + const avatarTokenCount = avatars?.reduce((count, avatar) => { + count[avatar.phygital_id] = fantokens.filter( + (token) => token.phygital_id === avatar.phygital_id + ).length + return count + }, {} as Record) + + const topAvatarsData = Object.entries(avatarTokenCount) + .sort(([, countA], [, countB]) => countB - countA) + .slice(0, 3) + .map(([phygitalId, count]) => { + const avatar = avatars.find((a) => a.phygital_id === phygitalId) + return { ...avatar, count } + }) + + return topAvatarsData + } + + const results = useQueries({ + queries: [ + { + queryKey: ['avatars'], + queryFn: getAvatars, + }, + { + queryKey: ['fantokens'], + queryFn: getFanTokens, + }, + ], + }) + + const [avatarsResult, fantokenResults] = results + + const topAvatarsResult = useQuery({ + queryKey: ['topAvatars'], + queryFn: () => getTopAvatars(avatarsResult.data, fantokenResults.data), + }) + + const topAvatars = topAvatarsResult.data + + return ( +
+ {/* Title */} +
+ Avatar Leaderboard +
+ + {/* Top Performing Avatars Section */} + + {topAvatars && ( +
+
+ This Week's Top Performing AI-Powered Brand Ambassadors +
+
+ )} + + {topAvatars && ( +
+ {/* Silver */} +
+ {topAvatars?.[1] && ( + <> + +
+ Silver +
+ SILVER +
+
+
+ No. tokens: {topAvatars?.[1].count} +
+ + + + + )} +
+ + {/* Gold */} +
+ {topAvatars?.[0] && ( + <> + +
+ Gold +
+ GOLD +
+
+
+ No. tokens: {topAvatars?.[0].count} +
+ + + + + )} +
+ + {/* Bronze */} +
+ {topAvatars?.[2] && ( + <> + + Bronze +
+ No. tokens: {topAvatars?.[2].count} +
+ + + + + )} +
+
+ )} + + {/* Background with Trophies */} +
+ Left Trophy + Right Trophy +
+ Rewarding Creators, Owners and Supporters. +
+
+ + {/* Call to Action */} +
+
+
+

+ Create Profile +

+

& Earn Rewards

+ +
+
+
+
+ ) +} + +export default AvatarLeaderboard diff --git a/src/components/avatars.js b/src/components/avatars.js deleted file mode 100644 index cd36593..0000000 --- a/src/components/avatars.js +++ /dev/null @@ -1,39 +0,0 @@ -'use client' -import React, { useEffect, useState } from 'react' -import Link from 'next/link' -import { Avatar } from '@readyplayerme/visage' - -const HotNftCard = ({ nft }) => { - return ( -
- -
-
-
- -
-
- -
- ) -} - -export default HotNftCard diff --git a/src/components/claim-nft-modal.tsx b/src/components/claim-nft-modal.tsx new file mode 100644 index 0000000..4f38c9f --- /dev/null +++ b/src/components/claim-nft-modal.tsx @@ -0,0 +1,69 @@ +import React from 'react' +import Link from 'next/link' +import Image from 'next/image' + +export const ClaimNftModal = ({ + onClose, + brandName, + freeNft, +}: { + onClose: (state: boolean) => void + brandName: string + freeNft: string +}) => { + const handleClick = () => { + onClose(false) + } + + const removePrefix = (uri: string) => { + return uri?.substring(7, uri.length) + } + + return ( + <> +
+
+

+ You Have Claimed Your +
+ Free NFT Fan Token +

+ trophy +
+ +
+ Free NFT Image + +
+

+ By owning this NFT, you show your support to {brandName} and help + them reach higher on the MyriadFlow avatar leaderboard! +

+

+ Rewards are distributed to top 3 avatar creators, owners and + supporters each week. +

+
+ + + +
+
+
+
+ + ) +} diff --git a/src/components/claim-nft-popup.js b/src/components/claim-nft-popup.js deleted file mode 100644 index bb2dac4..0000000 --- a/src/components/claim-nft-popup.js +++ /dev/null @@ -1,186 +0,0 @@ -import React from 'react' -import Link from 'next/link' -import Image from 'next/image' - -export const ClaimNftPopUp = ({ onClose, brandName, freeNft }) => { - const handleClick = () => { - onClose(false) - } - - const removePrefix = (uri) => { - return uri?.substring(7, uri.length) - } - - return ( -
-
-
-
-
- {/* Add any additional content or buttons here */} -
- -
-
-

- You Have Claimed Your Free NFT Fan Token -

- -
- -
-
- Free NFT Image -
-
-

- By owning this NFT, you show your support to {brandName} - and help them reach higher on the MyriadFlow avatar - leaderboard! -

-

- Rewards are distributed to top 3 avatar creators, owners and - supporters each week. -

-
- - View in my assets - - - - Continue Experience - -
-
-
-
-
-
-
-
- ) -} diff --git a/src/components/claim-nft.js b/src/components/claim-nft.js deleted file mode 100644 index 8e25fc6..0000000 --- a/src/components/claim-nft.js +++ /dev/null @@ -1,232 +0,0 @@ -'use client' -import Link from 'next/link' -import { ClaimNftPopUp } from './claim-nft-popup' -import Image from 'next/image' -import { useAccount, useChainId } from 'wagmi' -import { ToastContainer, toast } from 'react-toastify' -import { simulateContract, writeContract } from '@wagmi/core' -import { useState } from 'react' -import { X } from 'lucide-react' -import { ConnectWallet } from './connect-wallet' -import { config } from '@/lib/wagmi' -import reward from '@/lib/reward.json' - -const baseUri = process.env.NEXT_PUBLIC_URI || 'https://app.myriadflow.com' - -export const ClaimNft = ({ - onClose, - freeNft, - brandName, - contractAddress, - chainTypeId, - collectionId, - phygitalName, - phygitalId, -}) => { - const [claimNft, setClaimNft] = useState(false) - const [brandId, setBrandId] = useState('') - const account = useAccount() - - const handleClick = () => { - onClose(false) - } - - const createFanToken = async () => { - console.log('running...') - const abi = reward.abi - const { request } = await simulateContract(config, { - abi, - - address: '0x771C15e87272d6A57900f009Cd833b38dd7869e5', - functionName: 'createFanToken', - args: [String(contractAddress), 1, 1, '0x0', 'www.xyz.com'], - }) - const hash = await writeContract(config, request) - - if (hash) { - const res = await fetch(`${baseUri}/fantoken`, { - method: 'POST', - body: JSON.stringify({ - brand_id: brandId, - collection_id: collectionId, - phygital_id: phygitalId, - phygital_name: phygitalName, - chaintype_id: chainTypeId, - fan_token_id: hash, - }), - }) - - const result = await res.json() - - if (result) { - setClaimNft(true) - } - } - } - - const removePrefix = (uri) => { - return uri?.substring(7, uri.length) - } - - return ( -
- - {!claimNft ? ( -
-
-
-
- -
- -
-
-

- Congratulations! -

-
- -
- - - Free NFT Image - -
- -

- You are eligible to claim a free NFT fan token to show your - support to {brandName} and get a chance to earn weekly - rewards. -

-
-
- { - if (!account.address) { - toast.warning('Connect or Create a wallet') - } else { - createFanToken() - } - }} - > - Claim Free NFT - -
-
- {!account.address && } -
-
-
-
- ) : ( - - )} -
- ) -} diff --git a/src/components/claim-nft.tsx b/src/components/claim-nft.tsx new file mode 100644 index 0000000..2b98d78 --- /dev/null +++ b/src/components/claim-nft.tsx @@ -0,0 +1,141 @@ +'use client' +import Link from 'next/link' +import { ClaimNftModal } from './claim-nft-modal' +import Image from 'next/image' +import { useAccount } from 'wagmi' +import { toast } from 'react-toastify' +import { simulateContract, writeContract } from '@wagmi/core' +import { useState } from 'react' +import { X } from 'lucide-react' +import { ConnectWallet } from './connect-wallet' +import { config } from '@/lib/wagmi' +import reward from '@/lib/reward.json' + +const baseUri = process.env.NEXT_PUBLIC_URI || 'https://app.myriadflow.com' + +export const ClaimNft = ({ + onClose, + freeNft, + brandName, + contractAddress, + chainTypeId, + collectionId, + phygitalName, + phygitalId, +}: { + onClose: (state: boolean) => void + freeNft: string + brandName: string + contractAddress: string + chainTypeId: string + collectionId: string + phygitalName: string + phygitalId: string +}) => { + const [claimNft, setClaimNft] = useState(false) + const [brandId, setBrandId] = useState('') + const account = useAccount() + + const handleClick = () => { + onClose(false) + } + + const createFanToken = async () => { + const abi = reward.abi + const { request } = await simulateContract(config, { + abi, + + address: '0x771C15e87272d6A57900f009Cd833b38dd7869e5', + functionName: 'createFanToken', + args: [String(contractAddress), 1, 1, '0x0', 'www.xyz.com'], + }) + const hash = await writeContract(config, request) + + if (hash) { + const res = await fetch(`${baseUri}/fantoken`, { + method: 'POST', + body: JSON.stringify({ + brand_id: brandId, + collection_id: collectionId, + phygital_id: phygitalId, + phygital_name: phygitalName, + chaintype_id: chainTypeId, + fan_token_id: hash, + }), + }) + + const result = await res.json() + + if (result) { + setClaimNft(true) + } + } + } + + const removePrefix = (uri: string) => { + return uri?.substring(7, uri.length) + } + + return ( + <> + {!claimNft ? ( +
+
+ +
+ +
+
+

+ Congratulations! +

+
+ +
+ trophy image + + Free NFT Image + trophy image +
+ +

+ You are eligible to claim a free NFT fan token to show your + support to {brandName} and get a chance to earn weekly rewards. +

+
+ +
+ +
+ +
+ {!account.address && } +
+
+ ) : ( + + )} + + ) +} diff --git a/src/components/congratulations.js b/src/components/congratulations.js deleted file mode 100644 index d2124c9..0000000 --- a/src/components/congratulations.js +++ /dev/null @@ -1,125 +0,0 @@ -import React from 'react' -import Link from 'next/link' - -const Congratulations = () => { - return ( -
-
-
-
-
- {/* Add any additional content or buttons here */} -
- -
-

- Congratulations! -

-

- You have successfully created your avatar. -

-

- Download your avatar (png) -

-
-
- - Go back to Studio - -
-
-
-
-
- ) -} - -export default page diff --git a/src/components/connect-wallet-modal.js b/src/components/connect-wallet-modal.js deleted file mode 100644 index 5c3964a..0000000 --- a/src/components/connect-wallet-modal.js +++ /dev/null @@ -1,84 +0,0 @@ -import React from 'react' -import Link from 'next/link' -import { ConnectWallet } from './connect-wallet' - -export const ConnectWalletModal = () => { - return ( -
-
-
-
-
- {/* Add any additional content or buttons here */} -
- -
-

- Connect wallet to claim NFT and

unlock the experience -

-
-
- {/* */} - - -
-
-
-
-
- ) -} diff --git a/src/components/connect-wallet-modal.tsx b/src/components/connect-wallet-modal.tsx new file mode 100644 index 0000000..373d54a --- /dev/null +++ b/src/components/connect-wallet-modal.tsx @@ -0,0 +1,15 @@ +import { ConnectWallet } from './connect-wallet' + +export const ConnectWalletModal = () => { + return ( +
+
+ Connect wallet to claim NFT and
unlock the experience +
+ +
+ +
+
+ ) +} diff --git a/src/components/create-wallet.jsx b/src/components/create-wallet.jsx deleted file mode 100644 index fc4d43e..0000000 --- a/src/components/create-wallet.jsx +++ /dev/null @@ -1,92 +0,0 @@ -import React, { useCallback } from 'react' -import { useConnect, useAccount, useDisconnect } from 'wagmi' - -export const CreateWallet = () => { - const { connectors, connect } = useConnect() - const { address } = useAccount() - const { disconnect } = useDisconnect() - - const createWallet = useCallback(() => { - const coinbaseWalletConnector = connectors.find( - (connector) => connector.id === 'coinbaseWalletSDK' - ) - - if (coinbaseWalletConnector) { - connect({ connector: coinbaseWalletConnector }) - } - }, [connectors, connect]) - - return ( - <> - {address ? ( -
-
{address}
- -
- ) : ( - - )} - - ) -} - -const buttonStyles = { - background: 'transparent', - border: '1px solid transparent', - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - paddingInline: '2.5rem', - fontFamily: 'Arial, sans-serif', - fontWeight: 'bold', - fontSize: 12, - backgroundColor: '#0052FF', - borderRadius: 10, - cursor: 'pointer', -} - -const containerStyles = { - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', -} - -const addressStyles = { - backgroundColor: '#F0F0F0', - border: '1px solid #DDD', - borderRadius: 10, - padding: '10px 20px', - fontFamily: 'Arial, sans-serif', - fontWeight: 'bold', - fontSize: 18, - textAlign: 'center', - wordBreak: 'break-all', - flex: 1, -} - -const disconnectButtonStyles = { - marginLeft: 10, - backgroundColor: '#FF5C5C', - color: 'white', - border: 'none', - borderRadius: 10, - padding: '10px', - cursor: 'pointer', - fontWeight: 'bold', -} diff --git a/src/components/footer.js b/src/components/footer.js deleted file mode 100644 index a9bc110..0000000 --- a/src/components/footer.js +++ /dev/null @@ -1,131 +0,0 @@ -import React from 'react'; -import Image from 'next/image'; -import Link from 'next/link'; // Use Link for navigation - -const Footer = () => { - return ( -
-
-
-
- - logo - -

- Revolutionary platform for exploring and launching NFT Xperiences. -

-

- © Copyright 2023 - 2024 MyriadFlow. All rights reserved -

-
- -
-
-
-
-
- - Discord logo - -
-
-
- -
-
-
- - Telegram logo - -
-
-
- -
-
-
- - X logo - -
-
-
- -
-
-
- - Instagram logo - -
-
-
-
-
-
-
-
- ); -}; - -export default Footer; diff --git a/src/components/footer.tsx b/src/components/footer.tsx new file mode 100644 index 0000000..58a05ce --- /dev/null +++ b/src/components/footer.tsx @@ -0,0 +1,74 @@ +import React from 'react' +import Image from 'next/image' +import Link from 'next/link' // Use Link for navigation + +const Footer = () => { + return ( +
+ {/* Brand Section */} +
+
+ + logo + +

+ Revolutionary platform for exploring and launching NFT Xperiences. +

+

+ © Copyright 2023 - 2024 MyriadFlow. All rights reserved +

+
+ + {/* Connect Section */} +
+
+ + Discord logo + +
+
+ + Telegram logo + +
+
+ + X logo + +
+
+ + Instagram logo + +
+
+
+
+ ) +} + +export default Footer diff --git a/src/components/leaderboard.js b/src/components/leaderboard.js deleted file mode 100644 index d0b2362..0000000 --- a/src/components/leaderboard.js +++ /dev/null @@ -1,84 +0,0 @@ -'use client' -import React, { useEffect, useState } from 'react' -import Avatars from './avatars' - -const Leaderboard = () => { - const [avatar, setAvatar] = useState([]) - - const getBrands = async () => { - const baseUri = process.env.NEXT_PUBLIC_URI || 'https://app.myriadflow.com' - - localStorage.setItem( - 'BaseSepoliaChain', - '554b4903-9a06-4031-98f4-48276c427f78' - ) - const chaintype = localStorage.getItem('BaseSepoliaChain') - - const avatar = await fetch( - `${baseUri}/avatars/all/${chaintype} -`, - { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - }, - } - ) - const avatardata = await avatar.json() - // setAvatar(avatardata); - setAvatar([...avatardata].reverse()) - } - - useEffect(() => { - getBrands() - }, []) - - return ( -
-
-
- More than NFTs. -
-
- - {/*
- WebXR Xperiences live soon! -
*/} -
-
Most Recently Launched
-
New on WebXR
-
New Frontier: Be Among the First to Discover the Newest Xperiences Making Their Debut!
-
- -
- {avatar?.slice(0, 12).reverse().map((nft, index) => ( - - ))} -
-
- ) -} - -export default Leaderboard diff --git a/src/components/leaderboard.tsx b/src/components/leaderboard.tsx new file mode 100644 index 0000000..ffa3287 --- /dev/null +++ b/src/components/leaderboard.tsx @@ -0,0 +1,66 @@ +'use client' + +import { useQuery } from '@tanstack/react-query' +import AvatarCard from './avatar-card' +import { getAvatars } from '@/utils/queries' +import { AvatarType } from '@/types/types' + +const Leaderboard = () => { + const chaintype = process.env.NEXT_PUBLIC_BASECHAINTYPE + + const result = useQuery({ + queryKey: ['avatars'], + queryFn: async () => { + const avatars = await getAvatars() + return avatars + .filter((avatar: AvatarType) => avatar.chaintype_id === chaintype) + .reverse() + }, + }) + + const avatars = result.data + + return ( + <> +
+
+ More than NFTs. +
+
+ +
+
+ Most Recently Launched +
+
+ New on WebXR +
+
+ New Frontier: Be Among the First to Discover the Newest Xperiences + Making Their Debut! +
+
+ +
+ {avatars + ?.slice(0, 12) + .reverse() + .map((avatar: AvatarType, index: number) => ( + + ))} +
+ + ) +} + +export default Leaderboard diff --git a/src/components/minted-modal.tsx b/src/components/minted-modal.tsx new file mode 100644 index 0000000..eb66d45 --- /dev/null +++ b/src/components/minted-modal.tsx @@ -0,0 +1,48 @@ +export const MintedModal = ({ + onClose, + phygitalName, +}: { + onClose: (state: boolean) => void + phygitalName: string +}) => { + const handleClick = () => { + onClose(false) + } + + return ( +
+
+
+ trophy +

+ Congratulations! +

+ trophy +
+

+ You have successfully minted {phygitalName} phygital NFT! +

+

+ As the owner of {phygitalName} you are also the owner of this avatar! +

+

+ You can customize the avatar and get a chance to compete against other + avatars for weekly rewards on MyriadFlow leaderboard. +

+
+ +
+ + + +
+
+ ) +} diff --git a/src/components/nfc-mint-popup.js b/src/components/nfc-mint-popup.js deleted file mode 100644 index c47b71e..0000000 --- a/src/components/nfc-mint-popup.js +++ /dev/null @@ -1,161 +0,0 @@ -import React from 'react' -import Link from 'next/link' - -export const NfcMintPopUp = ({ onClose, phygitalName }) => { - const handleClick = () => { - onClose(false) - } - - return ( -
-
-
-
- {/* Add any additional content or buttons here */} -
- -
-
- -

- Congratulations! -

- -
-

- You have successfully minted {phygitalName} phygital NFT! -

-

- As the owner of {phygitalName} you are also the owner of this - avatar! -

-

- You can customize the avatar and get a chance to compete against - other avatars for weekly rewards on MyriadFlow leaderboard. -

-
-
- - View in my assets - - - - Continue Experience - -
-
-
-
- ) -} diff --git a/src/types/types.ts b/src/types/types.ts new file mode 100644 index 0000000..40713cb --- /dev/null +++ b/src/types/types.ts @@ -0,0 +1,23 @@ +export type AvatarType = { + id: string + avatar_id: string + url: string + user_id: string + phygital_id: string + avatar_voice: string + chaintype_id: string + created_at: string + updated_at: string +} + +export type FanTokenType = { + id: string + brand_id: string + collection_id: string + phygital_id: string + created_at: string + updated_at: string + fan_token_id: string + chaintype_id: string + phygital_name: string +} diff --git a/src/utils/queries.ts b/src/utils/queries.ts new file mode 100644 index 0000000..893c8e1 --- /dev/null +++ b/src/utils/queries.ts @@ -0,0 +1,29 @@ +import { useQuery } from '@tanstack/react-query' +import axios from 'axios' + +const baseURI = process.env.NEXT_PUBLIC_URI || 'https://app.myriadflow.com' + +export const getBrands = async () => { + const response = await axios.get(`${baseURI}/brands/all`) + return response.data +} + +export const getPhygital = async (id: string) => { + const response = await axios.get(`${baseURI}/phygitals/${id}`) + return response.data +} + +export const getWebXR = async (id: string) => { + const response = await axios.get(`${baseURI}/webxr/phygital/${id}`) + return response.data +} + +export const getAvatars = async () => { + const response = await axios.get(`${baseURI}/avatars/all`) + return response.data +} + +export const getFanTokens = async () => { + const response = await axios.get(`${baseURI}/fantoken/all`) + return response.data +} diff --git a/tsconfig.json b/tsconfig.json index 01761fb..0a49718 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -29,7 +29,7 @@ ".next/types/**/*.ts", "src/app/[id]/page.tsx", "src/components/create-wallet.jsx", - "src/components/claim-nft.js" + "src/components/claim-nft.tsx" ], "exclude": ["node_modules", "page.tsx"] } diff --git a/yarn.lock b/yarn.lock index 2c1a35c..a764b3d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1319,6 +1319,18 @@ resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.51.21.tgz#a510469c6c30d3de2a8b8798e340169a4b0fd08f" integrity sha512-POQxm42IUp6n89kKWF4IZi18v3fxQWFRolvBA6phNVmA8psdfB1MvDnGacCJdS+EOX12w/CyHM62z//rHmYmvw== +"@tanstack/query-devtools@5.51.16": + version "5.51.16" + resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.51.16.tgz#d855d00e7939c1a442c2e8ae3ad1a5bd603d003b" + integrity sha512-ajwuq4WnkNCMj/Hy3KR8d3RtZ6PSKc1dD2vs2T408MdjgKzQ3klVoL6zDgVO7X+5jlb5zfgcO3thh4ojPhfIaw== + +"@tanstack/react-query-devtools@^5.51.23": + version "5.51.23" + resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.51.23.tgz#2e5428a0ade3b15ec13dd39cb2e833dfa50d580b" + integrity sha512-XpHrdyfUPGULIyJ1K7UvhAcK+KjMJdw4NjmRjryoj3XEgfAU5qU1rz8gIFvGc3gTGT07yIseGo7GEll/ICfJfQ== + dependencies: + "@tanstack/query-devtools" "5.51.16" + "@tanstack/react-query@^5.51.23": version "5.51.23" resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.51.23.tgz#83c223f4cb6054b206de8856b73ca7e41a63ba1f" @@ -2286,6 +2298,15 @@ axios@^1.2.1: form-data "^4.0.0" proxy-from-env "^1.1.0" +axios@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.4.tgz#4c8ded1b43683c8dd362973c393f3ede24052aa2" + integrity sha512-DukmaFRnY6AzAALSH4J2M3k6PkaC+MfaAGdEERRWcC9q3/TWQwLpHR8ZRLKTdQ3aBDL64EdluRDjJqKw+BPZEw== + dependencies: + follow-redirects "^1.15.6" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axobject-query@~3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1"