From 2bf76ac285a17f3ae72b78e2594297b949df6871 Mon Sep 17 00:00:00 2001 From: namedotget Date: Tue, 7 Jan 2025 16:02:32 -0600 Subject: [PATCH] Reconfigured project pages to use a tableland entry instead of an NFT --- ui/pages/project/[tokenId].tsx | 98 ++++++++++++++++++---------------- ui/pages/project/index.tsx | 97 ++++++++++++++------------------- 2 files changed, 90 insertions(+), 105 deletions(-) diff --git a/ui/pages/project/[tokenId].tsx b/ui/pages/project/[tokenId].tsx index 7d3306d7e..99d2d26ef 100644 --- a/ui/pages/project/[tokenId].tsx +++ b/ui/pages/project/[tokenId].tsx @@ -1,20 +1,22 @@ import { Arbitrum, Sepolia } from '@thirdweb-dev/chains' import { useAddress, useContract, useSDK } from '@thirdweb-dev/react' import ProjectABI from 'const/abis/Project.json' +import ProjectTableABI from 'const/abis/ProjectTable.json' import { CITIZEN_ADDRESSES, HATS_ADDRESS, MOONEY_ADDRESSES, PROJECT_ADDRESSES, + PROJECT_TABLE_ADDRESSES, + TABLELAND_ENDPOINT, } from 'const/config' import { blockedProjects } from 'const/whitelist' import { GetServerSideProps } from 'next' import Image from 'next/image' import Link from 'next/link' import { useContext, useEffect, useState } from 'react' -import toast from 'react-hot-toast' import { useSubHats } from '@/lib/hats/useSubHats' -import useProjectData from '@/lib/project/useProjectData' +import useProjectData, { Project } from '@/lib/project/useProjectData' import ChainContext from '@/lib/thirdweb/chain-context' import { useChainDefault } from '@/lib/thirdweb/hooks/useChainDefault' import { initSDK } from '@/lib/thirdweb/thirdweb' @@ -26,12 +28,19 @@ import Head from '@/components/layout/Head' import { NoticeFooter } from '@/components/layout/NoticeFooter' import SlidingCardMenu from '@/components/layout/SlidingCardMenu' import StandardButton from '@/components/layout/StandardButton' -import Button from '@/components/subscription/Button' import TeamManageMembers from '@/components/subscription/TeamManageMembers' import TeamMembers from '@/components/subscription/TeamMembers' import TeamTreasury from '@/components/subscription/TeamTreasury' -export default function ProjectProfile({ tokenId, nft, imageIpfsLink }: any) { +type ProjectProfileProps = { + tokenId: string + project: Project +} + +export default function ProjectProfile({ + tokenId, + project, +}: ProjectProfileProps) { const sdk = useSDK() const address = useAddress() @@ -50,7 +59,17 @@ export default function ProjectProfile({ tokenId, nft, imageIpfsLink }: any) { MOONEY_ADDRESSES[selectedChain.slug] ) - const { data: MOONEYBalance } = useMOONEYBalance(mooneyContract, nft?.owner) + const [owner, setOwner] = useState('') + + useEffect(() => { + async function getOwner() { + const owner = await projectContract?.call('ownerOf', [tokenId]) + setOwner(owner) + } + if (projectContract) getOwner() + }, [tokenId, projectContract]) + + const { data: MOONEYBalance } = useMOONEYBalance(mooneyContract, owner) const { adminHatId, @@ -62,7 +81,7 @@ export default function ProjectProfile({ tokenId, nft, imageIpfsLink }: any) { totalBudget, MDP, isLoading: isLoadingProjectData, - } = useProjectData(projectContract, hatsContract, nft) + } = useProjectData(projectContract, hatsContract, project) //Hats const hats = useSubHats(selectedChain, adminHatId) @@ -72,14 +91,14 @@ export default function ProjectProfile({ tokenId, nft, imageIpfsLink }: any) { useEffect(() => { async function getNativeBalance() { const provider = sdk?.getProvider() - const balance: any = await provider?.getBalance(nft?.owner as string) + const balance: any = await provider?.getBalance(owner as string) setNativeBalance(+(balance.toString() / 10 ** 18).toFixed(5)) } - if (sdk && nft?.owner) { + if (sdk && owner) { getNativeBalance() } - }, [sdk, nft]) + }, [sdk, project]) useChainDefault() @@ -106,12 +125,12 @@ export default function ProjectProfile({ tokenId, nft, imageIpfsLink }: any) { >
- {nft?.metadata.description ? ( + {project?.description ? (

- {nft?.metadata.description || ''} + {project.description || ''}

) : ( <> @@ -134,9 +153,9 @@ export default function ProjectProfile({ tokenId, nft, imageIpfsLink }: any) { return ( - +
- + {/* Enable when final report editor is ready */} + {/*
- + */}
@@ -265,7 +285,7 @@ export default function ProjectProfile({ tokenId, nft, imageIpfsLink }: any) { {/* Mooney and Voting Power */} {isManager && ( @@ -280,7 +300,7 @@ export default function ProjectProfile({ tokenId, nft, imageIpfsLink }: any) { export const getServerSideProps: GetServerSideProps = async ({ params }) => { const tokenId: any = params?.tokenId - const chain = Sepolia + const chain = process.env.NEXT_PUBLIC_CHAIN === 'mainnet' ? Arbitrum : Sepolia const sdk = initSDK(chain) if (tokenId === undefined) { @@ -289,37 +309,21 @@ export const getServerSideProps: GetServerSideProps = async ({ params }) => { } } - const projectContract = await sdk.getContract( - PROJECT_ADDRESSES[chain.slug], - ProjectABI + const projectTableContract = await sdk.getContract( + PROJECT_TABLE_ADDRESSES[chain.slug], + ProjectTableABI ) + const projectTableName = await projectTableContract?.call('getTableName') - // const nft = await projectContract.erc721.get(tokenId) + const statement = `SELECT * FROM ${projectTableName} WHERE id = ${tokenId}` - const nft = { - metadata: { - name: 'Deprize Development', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', - attributes: [ - { - trait_type: 'active', - value: 'true', - }, - { - trait_type: 'proposalIPFS', - value: - 'ipfs://bafkreifsaljrpcjycsd5fzmpwvo5k2ye7geaeqqcjym4ornafjqwahjmoe', - }, - { - trait_type: 'MDP', - value: '159', - }, - ], - }, - } + const projectsRes = await fetch( + `${TABLELAND_ENDPOINT}?statement=${statement}` + ) + const projects = await projectsRes.json() + const project = projects[0] - if (!nft || blockedProjects.includes(Number(tokenId))) { + if (!project || blockedProjects.includes(Number(tokenId))) { return { notFound: true, } @@ -327,7 +331,7 @@ export const getServerSideProps: GetServerSideProps = async ({ params }) => { return { props: { - nft, + project, tokenId, }, } diff --git a/ui/pages/project/index.tsx b/ui/pages/project/index.tsx index 1cec9b1c8..e139960b5 100644 --- a/ui/pages/project/index.tsx +++ b/ui/pages/project/index.tsx @@ -1,19 +1,23 @@ import { Arbitrum, Sepolia } from '@thirdweb-dev/chains' -import { NFT, useContract } from '@thirdweb-dev/react' +import { useContract } from '@thirdweb-dev/react' import HatsABI from 'const/abis/Hats.json' import ProjectABI from 'const/abis/Project.json' -import TeamABI from 'const/abis/Team.json' -import { HATS_ADDRESS, PROJECT_ADDRESSES, TEAM_ADDRESSES } from 'const/config' +import ProjectTableABI from 'const/abis/ProjectTable.json' +import { + HATS_ADDRESS, + PROJECT_ADDRESSES, + PROJECT_TABLE_ADDRESSES, + TABLELAND_ENDPOINT, +} from 'const/config' import { blockedProjects } from 'const/whitelist' import Image from 'next/image' import { useRouter } from 'next/router' import React, { useState, useEffect, useCallback, useContext } from 'react' +import { Project } from '@/lib/project/useProjectData' import ChainContext from '@/lib/thirdweb/chain-context' import { useChainDefault } from '@/lib/thirdweb/hooks/useChainDefault' import { initSDK } from '@/lib/thirdweb/thirdweb' import { useShallowQueryRoute } from '@/lib/utils/hooks' -import { getAttribute } from '@/lib/utils/nft' -import Card from '@/components/layout/Card' import CardGridContainer from '@/components/layout/CardGridContainer' import CardSkeleton from '@/components/layout/CardSkeleton' import Container from '@/components/layout/Container' @@ -23,11 +27,11 @@ import Head from '@/components/layout/Head' import { NoticeFooter } from '@/components/layout/NoticeFooter' import Search from '@/components/layout/Search' import Tab from '@/components/layout/Tab' -import ProjectCard from '@/components/projects/ProjectCard' +import ProjectCard from '@/components/project/ProjectCard' type NetworkProps = { - activeProjects: NFT[] - inactiveProjects: NFT[] + activeProjects: Project[] + inactiveProjects: Project[] } export default function Projects({ @@ -46,9 +50,9 @@ export default function Projects({ const { contract: hatsContract } = useContract(HATS_ADDRESS, HatsABI) const [input, setInput] = useState('') - function filterBySearch(nfts: NFT[]) { - return nfts.filter((nft) => { - return nft.metadata.name + function filterBySearch(projects: Project[]) { + return projects.filter((project) => { + return project.name ?.toString() .toLowerCase() .includes(input.toLowerCase()) @@ -111,7 +115,7 @@ export default function Projects({ if (tab === 'inactive') setMaxPage(Math.ceil(totalInactiveProjects / 9)) }, [tab, input, activeProjects, inactiveProjects]) - const [cachedNFTs, setCachedNFTs] = useState([]) + const [cachedNFTs, setCachedNFTs] = useState([]) const [pageIdx, setPageIdx] = useState(1) @@ -131,9 +135,12 @@ export default function Projects({ useChainDefault() + const description = + 'Discover active and archived projects advancing our multiplanetary mission. Have an idea? Submit your proposal and help shape the future of space exploration!' + const descriptionSection = (
-
MoonDAO Projects.
+
{description}
@@ -171,7 +178,7 @@ export default function Projects({
@@ -190,11 +197,11 @@ export default function Projects({ {cachedNFTs?.[0] ? ( cachedNFTs ?.slice((pageIdx - 1) * 9, pageIdx * 9) - .map((nft: any, I: number) => { + .map((project: any, I: number) => { return ( @@ -267,57 +274,31 @@ export async function getStaticProps() { const chain = process.env.NEXT_PUBLIC_CHAIN === 'mainnet' ? Arbitrum : Sepolia const sdk = initSDK(chain) - const projectContract = await sdk.getContract( - PROJECT_ADDRESSES[chain.slug], - TeamABI + const projectTableContract = await sdk.getContract( + PROJECT_TABLE_ADDRESSES[chain.slug], + ProjectTableABI + ) + + const projectTableName = await projectTableContract.call('getTableName') + const projectStatement = `SELECT * FROM ${projectTableName}` + const projectsRes = await fetch( + `${TABLELAND_ENDPOINT}?statement=${projectStatement}` ) - const totalProjects = await projectContract.call('totalSupply') + const projects = await projectsRes.json() const activeProjects = [] const inactiveProjects = [] - for (let i = 0; i < totalProjects; i++) { + for (let i = 0; i < projects.length; i++) { if (!blockedProjects.includes(i)) { - const project = await projectContract.erc721.get(i) - - const active = getAttribute( - project.metadata.attributes as any[], - 'active' - )?.value - if (active === '0') { - inactiveProjects.push(project) - } else if (active === '1' || active) { - activeProjects.push(project) + const active = projects[i].active + if (!active || active === 0) { + inactiveProjects.push(projects[i]) + } else if (active === 1) { + activeProjects.push(projects[i]) } } } - const nft = { - metadata: { - name: 'Deprize Development', - tokenId: 0, - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.', - attributes: [ - { - trait_type: 'active', - value: 'true', - }, - { - trait_type: 'proposalIPFS', - value: - 'ipfs://bafkreifsaljrpcjycsd5fzmpwvo5k2ye7geaeqqcjym4ornafjqwahjmoe', - }, - { - trait_type: 'MDP', - value: '159', - }, - ], - }, - } - - activeProjects.push(nft) - inactiveProjects.push(nft) - return { props: { activeProjects: activeProjects.reverse(),