From 82ee50b03094fbe9d558068263953c0579b91220 Mon Sep 17 00:00:00 2001 From: netpoe Date: Mon, 13 May 2024 16:26:44 -0600 Subject: [PATCH] feat: profile page lists NFTs by wallet --- app/package.json | 1 + app/src/context/evm/ERC721/Erc721Context.tsx | 5 + .../context/evm/ERC721/Erc721Context.types.ts | 11 + .../evm/ERC721/Erc721ContextController.tsx | 51 ++ .../context/evm/ERC721/useErc721Context.tsx | 13 + app/src/hooks/useRoutes/useRoutes.tsx | 56 +- app/src/layouts/home-layout/HomeLayout.tsx | 21 +- .../api/evm/ERC721/get-nfts-by-wallet.ts | 30 + app/src/pages/api/evm/ERC721/types.ts | 11 + app/src/pages/profile/index.tsx | 37 + app/src/providers/moralis/index.ts | 11 + app/src/theme/_mixins.scss | 13 + app/src/ui/fileagent/navbar/Navbar.tsx | 4 + .../ProfileDropdown.module.scss | 5 + .../ProfileDropdown.module.scss.d.ts | 16 + .../profile-dropdown/ProfileDropdown.test.tsx | 13 + .../profile-dropdown/ProfileDropdown.tsx | 20 + .../profile-dropdown/ProfileDropdown.types.ts | 6 + .../collections/Collections.module.scss | 61 ++ .../collections/Collections.module.scss.d.ts | 24 + .../profile/collections/Collections.test.tsx | 13 + .../profile/collections/Collections.tsx | 69 ++ .../profile/collections/Collections.types.ts | 6 + app/src/ui/svpervnder/home/Home.module.scss | 11 +- .../WalletSelectorNavbar.module.scss | 264 ------- .../WalletSelectorNavbar.module.scss.d.ts | 40 -- .../WalletSelectorNavbar.test.tsx | 13 - .../WalletSelectorNavbar.tsx | 48 -- .../WalletSelectorNavbar.types.ts | 7 - app/yarn.lock | 648 +++++++++++++++++- 30 files changed, 1082 insertions(+), 446 deletions(-) create mode 100644 app/src/context/evm/ERC721/Erc721Context.tsx create mode 100644 app/src/context/evm/ERC721/Erc721Context.types.ts create mode 100644 app/src/context/evm/ERC721/Erc721ContextController.tsx create mode 100644 app/src/context/evm/ERC721/useErc721Context.tsx create mode 100644 app/src/pages/api/evm/ERC721/get-nfts-by-wallet.ts create mode 100644 app/src/pages/api/evm/ERC721/types.ts create mode 100644 app/src/pages/profile/index.tsx create mode 100644 app/src/providers/moralis/index.ts create mode 100644 app/src/theme/_mixins.scss create mode 100644 app/src/ui/lease721/navbar/profile-dropdown/ProfileDropdown.module.scss create mode 100644 app/src/ui/lease721/navbar/profile-dropdown/ProfileDropdown.module.scss.d.ts create mode 100644 app/src/ui/lease721/navbar/profile-dropdown/ProfileDropdown.test.tsx create mode 100644 app/src/ui/lease721/navbar/profile-dropdown/ProfileDropdown.tsx create mode 100644 app/src/ui/lease721/navbar/profile-dropdown/ProfileDropdown.types.ts create mode 100644 app/src/ui/lease721/profile/collections/Collections.module.scss create mode 100644 app/src/ui/lease721/profile/collections/Collections.module.scss.d.ts create mode 100644 app/src/ui/lease721/profile/collections/Collections.test.tsx create mode 100644 app/src/ui/lease721/profile/collections/Collections.tsx create mode 100644 app/src/ui/lease721/profile/collections/Collections.types.ts delete mode 100644 app/src/ui/wallet-selector-navbar/WalletSelectorNavbar.module.scss delete mode 100644 app/src/ui/wallet-selector-navbar/WalletSelectorNavbar.module.scss.d.ts delete mode 100644 app/src/ui/wallet-selector-navbar/WalletSelectorNavbar.test.tsx delete mode 100644 app/src/ui/wallet-selector-navbar/WalletSelectorNavbar.tsx delete mode 100644 app/src/ui/wallet-selector-navbar/WalletSelectorNavbar.types.ts diff --git a/app/package.json b/app/package.json index 3dcf2ade..ce1e2a3a 100644 --- a/app/package.json +++ b/app/package.json @@ -38,6 +38,7 @@ "lodash": "^4.17.21", "materialize-css": "^1.0.0-rc.2", "moment": "^2.29.1", + "moralis": "^2.26.1", "next": "^14.2.1", "next-i18next": "^8.2.0", "react": "^18.2.0", diff --git a/app/src/context/evm/ERC721/Erc721Context.tsx b/app/src/context/evm/ERC721/Erc721Context.tsx new file mode 100644 index 00000000..a645cb1a --- /dev/null +++ b/app/src/context/evm/ERC721/Erc721Context.tsx @@ -0,0 +1,5 @@ +import { createContext } from "react"; + +import { Erc721ContextType } from "./Erc721Context.types"; + +export const Erc721Context = createContext(undefined); diff --git a/app/src/context/evm/ERC721/Erc721Context.types.ts b/app/src/context/evm/ERC721/Erc721Context.types.ts new file mode 100644 index 00000000..37876524 --- /dev/null +++ b/app/src/context/evm/ERC721/Erc721Context.types.ts @@ -0,0 +1,11 @@ +import { GetNFTsByWalletResult } from "api/evm/ERC721/types"; +import { ReactNode } from "react"; + +export type Erc721ContextControllerProps = { + children: ReactNode; +}; + +export type Erc721ContextType = { + nftsByWallet: GetNFTsByWalletResult[][]; + getNFTsByWallet: () => Promise; +}; diff --git a/app/src/context/evm/ERC721/Erc721ContextController.tsx b/app/src/context/evm/ERC721/Erc721ContextController.tsx new file mode 100644 index 00000000..c509970a --- /dev/null +++ b/app/src/context/evm/ERC721/Erc721ContextController.tsx @@ -0,0 +1,51 @@ +import React from "react"; +import { useAccount } from "wagmi"; +import axios from "axios"; +import { GetNFTsByWalletRequest, GetNFTsByWalletResult } from "api/evm/ERC721/types"; +import _ from "lodash"; + +import { useRoutes } from "hooks/useRoutes/useRoutes"; + +import { Erc721ContextControllerProps, Erc721ContextType } from "./Erc721Context.types"; +import { Erc721Context } from "./Erc721Context"; + +const groupNFTsByContract = (nfts: GetNFTsByWalletResult[]) => { + const group = _.groupBy(nfts, "tokenAddress"); + + console.log(_.map(group)); + + return _.map(group); +}; + +export const Erc721ContextController = ({ children }: Erc721ContextControllerProps) => { + const [nftsByWallet, setNftsByWallet] = React.useState([]); + + const { address, chainId } = useAccount(); + const routes = useRoutes(); + + const getNFTsByWallet = async () => { + try { + const data: GetNFTsByWalletRequest = { + chainId: chainId!, + walletAddress: address!, + }; + + const result = await axios.post(routes.api.evm.ERC721.getNFTsByWallet(), { + data, + }); + + console.log(result.data); + + setNftsByWallet(groupNFTsByContract(result.data)); + } catch (error) { + console.error(error); + } + }; + + const props: Erc721ContextType = { + getNFTsByWallet, + nftsByWallet, + }; + + return {children}; +}; diff --git a/app/src/context/evm/ERC721/useErc721Context.tsx b/app/src/context/evm/ERC721/useErc721Context.tsx new file mode 100644 index 00000000..8cff50f0 --- /dev/null +++ b/app/src/context/evm/ERC721/useErc721Context.tsx @@ -0,0 +1,13 @@ +import { useContext } from "react"; + +import { Erc721Context } from "./Erc721Context"; + +export const useErc721Context = () => { + const context = useContext(Erc721Context); + + if (context === undefined) { + throw new Error("useErc721Context must be used within a Erc721Context"); + } + + return context; +}; diff --git a/app/src/hooks/useRoutes/useRoutes.tsx b/app/src/hooks/useRoutes/useRoutes.tsx index 3e0f0a88..c2442f66 100644 --- a/app/src/hooks/useRoutes/useRoutes.tsx +++ b/app/src/hooks/useRoutes/useRoutes.tsx @@ -1,43 +1,14 @@ -type RouteMap = { - home: () => string; - market: { - price: (args: { marketId: string }) => string; - }; - api: { - promptWars: { - createGuestAccount: () => string; - create: () => string; - reveal: () => string; - resolve: () => string; - }; - chat: { - dropboxESign: () => string; - openai: { - completionsAPI: () => string; - assistantsAPI: () => string; - }; - googleai: { - completionsAPI: () => string; - }; - }; - }; - dashboard: { - latestTrends: () => string; - promptWars: { - home: () => string; - previousMarkets: () => string; - market: (args: { marketId: string }) => string; - }; - market: (args: { marketId: string }) => string; - }; -}; - -export const routes: RouteMap = { +export const routes = { home: () => `/`, - market: { - price: ({ marketId }) => `/market/price/${marketId}`, + profile: { + index: () => `/profile`, }, api: { + evm: { + ERC721: { + getNFTsByWallet: () => `/api/evm/ERC721/get-nfts-by-wallet`, + }, + }, promptWars: { createGuestAccount: () => `/api/prompt-wars/create-guest-account`, create: () => `/api/prompt-wars/create`, @@ -55,15 +26,6 @@ export const routes: RouteMap = { }, }, }, - dashboard: { - latestTrends: () => `/`, - promptWars: { - home: () => `/`, - previousMarkets: () => `/previous-rounds`, - market: ({ marketId }) => `/${marketId}`, - }, - market: ({ marketId }) => `/market/${marketId}`, - }, }; -export const useRoutes: () => RouteMap = () => routes; +export const useRoutes = () => routes; diff --git a/app/src/layouts/home-layout/HomeLayout.tsx b/app/src/layouts/home-layout/HomeLayout.tsx index 159e58fc..b2b3cd81 100644 --- a/app/src/layouts/home-layout/HomeLayout.tsx +++ b/app/src/layouts/home-layout/HomeLayout.tsx @@ -8,6 +8,7 @@ import { ToastContextController } from "context/toast/ToastContextController"; import { ThemeContextController } from "context/theme/ThemeContextController"; import { EvmWalletSelectorContextController } from "context/evm/wallet-selector/EvmWalletSelectorContextController"; import { Footer } from "ui/footer/Footer"; +import { Erc721ContextController } from "context/evm/ERC721/Erc721ContextController"; import { ChatLayoutProps } from "./HomeLayout.types"; import styles from "./HomeLayout.module.scss"; @@ -27,17 +28,19 @@ export const HomeLayout: React.FC = ({ children }) => { - -