diff --git a/public/gold.png b/public/gold.png index 299c7ab..a97ef4f 100644 Binary files a/public/gold.png and b/public/gold.png differ diff --git a/public/silver.png b/public/silver.png index afb515a..78067d7 100644 Binary files a/public/silver.png and b/public/silver.png differ diff --git a/public/star.png b/public/star.png new file mode 100644 index 0000000..2118669 Binary files /dev/null and b/public/star.png differ diff --git a/src/app/page.tsx b/src/app/page.tsx index e8eee32..b18afc3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -3,7 +3,7 @@ import Image from 'next/image' import Link from 'next/link' import MostLoved from '../components/mostLoved' import MostRecently from '../components/mostRecently' -import LeaderBoard from '../components/leaderboard' +import LeaderBoard from "@/components/leaderboard" import HotNFTs from '../components/hotNFTs' import LatestNFTs from '../components/latestNFTs' import Brand from '../components/brand' diff --git a/src/components/leaderboard.js b/src/components/leaderboard.js deleted file mode 100644 index e93cf7d..0000000 --- a/src/components/leaderboard.js +++ /dev/null @@ -1,193 +0,0 @@ -'use client' -import { useState, useEffect } from 'react' -import Link from 'next/link' -import { Avatar } from '@readyplayerme/visage' - -const baseUri = process.env.NEXT_PUBLIC_URI || 'https://app.myriadflow.com' - -const Leaderboard = () => { - 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 -
- -
View All - Arrow -
- -
-
- - {topAvatars.length >= 3 && ( - <> -
- -
- -
- SILVER -
-
-
- No. tokens: {topAvatars[1].count} -
- -
- -
- -
- -
- GOLD -
-
-
- No. tokens: {topAvatars[0].count} -
- -
- -
- -
- -
- -
-
-
- No. tokens: {topAvatars[2].count} -
- -
- - )} -
- -
- Left - Right -
- Rewarding Creators, Owners and Supporters. -
-
-
- ) -} - -export default Leaderboard diff --git a/src/components/leaderboard.tsx b/src/components/leaderboard.tsx new file mode 100644 index 0000000..7fe00e1 --- /dev/null +++ b/src/components/leaderboard.tsx @@ -0,0 +1,267 @@ +'use client' +import { Avatar } from '@readyplayerme/visage' +import Link from 'next/link' +import { useQueries, useQuery } from '@tanstack/react-query' +import { getAvatars, getFanTokens, getPhygitals } from '@/utils/queries' +import { AvatarType, FanTokenType } from '@/types/types' +import Image from 'next/image' +import { getFanMainTokens } from '../utils/queries' +import { useState } from 'react' + +const baseUri = process.env.NEXT_PUBLIC_URI || 'https://app.myriadflow.com' + +const Leaderboard = () => { + const [count, setCount] = useState([]) + + const results = useQueries({ + queries: [ + { + queryKey: ['avatars'], + queryFn: getAvatars, + }, + { + queryKey: ['mainFanTokens'], + queryFn: async () => { + const results = await getFanMainTokens(); + // Count occurrences of each contract address + const addressCount = results.reduce((acc: Record, token: any) => { + const address = token.nftContractAddress; // Use the correct property name here + acc[address] = (acc[address] || 0) + 1; + return acc; + }, {}); + + // Find top 3 addresses with the highest counts + const topThree = Object.entries(addressCount as Record) + .sort(([, countA], [, countB]) => countB - countA) + .slice(0, 3) // Take the top 3 items + .map(([address, count]) => ({ address, count })); // Return only the addresses + + const topThreeAddresses = topThree.map((item: any) => item.address); + const counts = topThree.map((item: any) => item.count); + setCount(counts as number[]); + + const allPhygitals = await getPhygitals(); + + // Filter phygitals by top 3 addresses and extract the ids + const filteredPhygitalIds = allPhygitals + .filter((phygital: any) => { + const match = topThreeAddresses.includes(phygital.contract_address); + return match; + }) + .map((phygital: any) => phygital.id); + + const allAvatars = await getAvatars(); + const matchedAvatars = allAvatars + .filter((avatar: any) => { + const match = filteredPhygitalIds.includes(avatar.phygital_id); + return match; + }) + .map((avatar: any) => avatar); + return matchedAvatars; + }, + }, + { + queryKey: ['fanTokens'], + queryFn: getFanTokens, + }, + + ], + }) + + const [avatarsResult, fanTokenMainResults, fanTokenResults] = results + + // const topAvatarsResult = useQuery({ + // queryKey: ['topAvatars'], + // queryFn: () => getTopAvatars(avatarsResult.data, fanTokenResults.data), + // }) + + const topAvatars = fanTokenMainResults.data + + return ( +
+
+ Avatar Leaderboard +
+
+
+ This Week's Top Performing AI-Powered Brand Ambassadors +
+ +
View All + Arrow +
+ +
+
+ + {topAvatars && ( + <> + {/* Silver */} +
+ {topAvatars?.[1] && ( + <> + +
+ Silver +
+
+
+ star + {count[1] * 100} + star +
+

+ star points +

+
+ + +
+ WEBXR +
+ + + )} +
+
+ + {/* Gold */} +
+ {topAvatars?.[0] && ( + <> + +
+ Gold +
+
+
+ star + {count[0] * 100} + star +
+

+ star points +

+
+ +
+ WEBXR +
+ + + )} +
+
+ + {/* Bronze */} +
+ {topAvatars?.[2] && ( + <> + + Bronze +
+
+ star + {count[2] * 100} + star +
+

+ star points +

+
+ + +
+ WEBXR +
+ + + )} +
+ + )} +
+ +
+ Left + Right +
+ Rewarding Creators, Owners and Supporters. +
+
+
+ ) +} + +export default Leaderboard diff --git a/src/utils/queries.ts b/src/utils/queries.ts new file mode 100644 index 0000000..1aa20cb --- /dev/null +++ b/src/utils/queries.ts @@ -0,0 +1,51 @@ +import { useQuery } from '@tanstack/react-query' +import axios from 'axios' + +export 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 getCollections = async () => { + const response = await axios.get(`${baseURI}/collections/all`) + return response.data +} + +export const getPhygitals = async () => { + const response = await axios.get(`${baseURI}/phygitals/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 +} + +export const getFanMainTokens = async () => { + const response = await axios.get(`${baseURI}/get-mint-fantoken`) + return response.data +} + +export const getProfileByWallet = async (walletAddress: string) => { + const response = await axios.get(`${baseURI}/profile/wallet/${walletAddress}`) + + return response +}