diff --git a/app/hypercerts/[hypercertId]/page.tsx b/app/hypercerts/[hypercertId]/page.tsx index 8113c966..30363de6 100644 --- a/app/hypercerts/[hypercertId]/page.tsx +++ b/app/hypercerts/[hypercertId]/page.tsx @@ -1,4 +1,3 @@ -import { Metadata, ResolvingMetadata } from "next"; import { Fragment, Suspense } from "react"; import { CurrencyButtons } from "@/components/currency-buttons"; @@ -20,34 +19,6 @@ import { getOrders } from "@/marketplace/getOpenOrders"; import Image from "next/image"; import MutationButtons from "@/components/hypercert/mutation-buttons"; -type Props = { - params: { hypercertId: string }; - searchParams: { [key: string]: string | string[] | undefined }; -}; - -export async function generateMetadata( - { params }: Props, - parent: ResolvingMetadata, -): Promise { - const { hypercertId } = params; - - const hypercert = await getHypercert(hypercertId); - - // optionally access and extend (rather than replace) parent metadata - const previousImages = (await parent).openGraph?.images || []; - return { - title: hypercert?.metadata?.name || "Untitled Hypercert", - description: hypercert?.metadata?.description || "", - openGraph: { - images: [ - `/api/hypercerts/${hypercertId}/image`, - "/hypercerts-opengraph.jpg", - ...previousImages, - ], - }, - }; -} - async function HypercertPageInner({ params, }: { diff --git a/app/profile/[address]/blueprint-tab-content.tsx b/app/profile/[address]/blueprint-tab-content.client.tsx similarity index 54% rename from app/profile/[address]/blueprint-tab-content.tsx rename to app/profile/[address]/blueprint-tab-content.client.tsx index 56c05886..1afbc631 100644 --- a/app/profile/[address]/blueprint-tab-content.tsx +++ b/app/profile/[address]/blueprint-tab-content.client.tsx @@ -1,55 +1,39 @@ -import React, { Suspense } from "react"; +"use client"; + import { ProfileSubTabKey, subTabs } from "@/app/profile/[address]/tabs"; -import ExploreListSkeleton from "@/components/explore/explore-list-skeleton"; import { SubTabsWithCount } from "@/components/profile/sub-tabs-with-count"; -import { getBlueprints } from "@/blueprints/getBlueprints"; import BlueprintsList from "@/components/blueprints/blueprints-list"; import { CreateBlueprintButton } from "@/components/blueprints/buttons"; import { OwnAccountOnly } from "@/components/own-account-only"; import { BlueprintsTable } from "@/components/blueprints/blueprints-table"; -import { BLUEPRINTS_PER_PAGE } from "@/configs/ui"; import Pagination from "@/components/pagination"; +import { BLUEPRINTS_PER_PAGE } from "@/configs/ui"; -const BlueprintTabContentInner = async ({ +export default function BlueprintsTabContentInner({ address, activeTab, searchParams, + availableBlueprints, + mintedBlueprints, + blueprintsCreated, }: { address: string; activeTab: ProfileSubTabKey; searchParams: Record; -}) => { - const currentPage = Number(searchParams?.p) || 1; - - const availableBlueprints = await getBlueprints({ - filters: { minterAddress: address as `0x${string}`, minted: false }, - first: BLUEPRINTS_PER_PAGE, - offset: BLUEPRINTS_PER_PAGE * (currentPage - 1), - }); - const mintedBlueprints = await getBlueprints({ - filters: { minterAddress: address as `0x${string}`, minted: true }, - first: BLUEPRINTS_PER_PAGE, - offset: BLUEPRINTS_PER_PAGE * (currentPage - 1), - }); - const blueprintsCreated = await getBlueprints({ - filters: { adminAddress: address as `0x${string}` }, - first: BLUEPRINTS_PER_PAGE, - offset: BLUEPRINTS_PER_PAGE * (currentPage - 1), - }); - + availableBlueprints: any; + mintedBlueprints: any; + blueprintsCreated: any; +}) { const marketplaceSubTabs = subTabs.filter( (tab) => tab.key.split("-")[0] === "blueprints", ); - const tabBadgeCounts: Partial< - Record<(typeof subTabs)[number]["key"], number> - > = { + const tabBadgeCounts = { "blueprints-claimable": availableBlueprints?.count ?? 0, "blueprints-claimed": mintedBlueprints?.count ?? 0, "blueprints-created": blueprintsCreated?.count ?? 0, }; - const currentCount = - tabBadgeCounts[activeTab as (typeof subTabs)[number]["key"]]; + return (
+ {activeTab === "blueprints-claimable" && ( )} @@ -78,35 +63,19 @@ const BlueprintTabContentInner = async ({ count={blueprintsCreated?.count} /> )} - {currentCount !== 0 && ( + + {(availableBlueprints?.count || + mintedBlueprints?.count || + blueprintsCreated?.count) && (
)}
); -}; - -const BlueprintsTabContent = ({ - address, - activeTab, - searchParams, -}: { - address: string; - activeTab: ProfileSubTabKey; - searchParams: Record; -}) => { - return ( - }> - - - ); -}; -export { BlueprintsTabContent }; +} diff --git a/app/profile/[address]/blueprint-tab-content.server.tsx b/app/profile/[address]/blueprint-tab-content.server.tsx new file mode 100644 index 00000000..54d2ff27 --- /dev/null +++ b/app/profile/[address]/blueprint-tab-content.server.tsx @@ -0,0 +1,51 @@ +import { Suspense } from "react"; +import { ProfileSubTabKey } from "@/app/profile/[address]/tabs"; +import BlueprintsTabContentInner from "./blueprint-tab-content.client"; +import { getBlueprints } from "@/blueprints/getBlueprints"; +import ExploreListSkeleton from "@/components/explore/explore-list-skeleton"; +import { BLUEPRINTS_PER_PAGE } from "@/configs/ui"; + +export default async function BlueprintsTabContent({ + address, + activeTab, + searchParams, +}: { + address: string; + activeTab: ProfileSubTabKey; + searchParams: Record; +}) { + const currentPage = Number(searchParams?.p) || 1; + + // Fetch data server-side + const [availableBlueprints, mintedBlueprints, blueprintsCreated] = + await Promise.all([ + getBlueprints({ + filters: { minterAddress: address as `0x${string}`, minted: false }, + first: BLUEPRINTS_PER_PAGE, + offset: BLUEPRINTS_PER_PAGE * (currentPage - 1), + }), + getBlueprints({ + filters: { minterAddress: address as `0x${string}`, minted: true }, + first: BLUEPRINTS_PER_PAGE, + offset: BLUEPRINTS_PER_PAGE * (currentPage - 1), + }), + getBlueprints({ + filters: { adminAddress: address as `0x${string}` }, + first: BLUEPRINTS_PER_PAGE, + offset: BLUEPRINTS_PER_PAGE * (currentPage - 1), + }), + ]); + + return ( + }> + + + ); +} diff --git a/app/profile/[address]/collections-tab-content-inner.tsx b/app/profile/[address]/collections-tab-content-inner.tsx deleted file mode 100644 index 9354357a..00000000 --- a/app/profile/[address]/collections-tab-content-inner.tsx +++ /dev/null @@ -1,53 +0,0 @@ -"use client"; - -import { EmptySection } from "@/app/profile/[address]/sections"; -import { HyperboardRow } from "@/components/hyperboard/hyperboard-row"; -import { CreateCollectionButton } from "@/components/collections/buttons"; -import { HyperboardFragment } from "@/collections/hyperboard.fragment"; -import { useAccount } from "wagmi"; - -export const HyperboardsOverview = ({ - profileAddress, - hyperboards, -}: { - profileAddress: string; - hyperboards: readonly HyperboardFragment[]; -}) => { - const { address } = useAccount(); - const isOwnProfile = address === profileAddress; - if (!hyperboards?.length) { - return ( -
- {isOwnProfile && ( -
- -
- )} - -
- ); - } - - return ( -
- {isOwnProfile && ( -
- -
- )} -
- {hyperboards.map((hyperboard) => ( - - ))} -
-
- ); -}; diff --git a/app/profile/[address]/collections-tab-content.client.tsx b/app/profile/[address]/collections-tab-content.client.tsx new file mode 100644 index 00000000..20c847c8 --- /dev/null +++ b/app/profile/[address]/collections-tab-content.client.tsx @@ -0,0 +1,54 @@ +"use client"; + +import Pagination from "@/components/pagination"; +import { HyperboardRow } from "@/components/hyperboard/hyperboard-row"; +import { CreateCollectionButton } from "@/components/collections/buttons"; +import { EmptySection } from "@/app/profile/[address]/sections"; +import { HyperboardFragment } from "@/collections/hyperboard.fragment"; +import { useAccount } from "wagmi"; + +export default function CollectionsTabContent({ + address, + hyperboards, + count, +}: { + address: string; + hyperboards: readonly HyperboardFragment[]; + count: number; +}) { + const { address: loggedInAddress } = useAccount(); + const isOwnProfile = loggedInAddress === address; + + return ( +
+ {isOwnProfile && ( +
+ +
+ )} + {hyperboards.length === 0 ? ( + + ) : ( +
+ {hyperboards.map((hyperboard) => ( + + ))} +
+ )} + + {count > 0 && ( +
+ +
+ )} +
+ ); +} diff --git a/app/profile/[address]/collections-tab-content.server.tsx b/app/profile/[address]/collections-tab-content.server.tsx new file mode 100644 index 00000000..d602db95 --- /dev/null +++ b/app/profile/[address]/collections-tab-content.server.tsx @@ -0,0 +1,37 @@ +import { Suspense } from "react"; +import { getCollectionsByAdminAddress } from "@/collections/getCollectionsByAdminAddress"; +import { COLLECTIONS_PER_PAGE } from "@/configs/ui"; +import CollectionsTabContent from "./collections-tab-content.client"; +import CollectionsTabSkeleton from "@/components/profile/collections-tab-skeleton"; + +export default async function CollectionsTabContentServer({ + address, + searchParams, +}: { + address: string; + searchParams: Record; +}) { + const currentPage = Number(searchParams?.p) || 1; + + // Fetch data server-side + const result = await getCollectionsByAdminAddress({ + adminAddress: address, + first: COLLECTIONS_PER_PAGE, + offset: COLLECTIONS_PER_PAGE * (currentPage - 1), + }); + + if (!result) return null; + + const { hyperboards, count } = result; + + // Render client component with fetched data + return ( + }> + + + ); +} diff --git a/app/profile/[address]/collections-tab-content.tsx b/app/profile/[address]/collections-tab-content.tsx deleted file mode 100644 index 58dee3cd..00000000 --- a/app/profile/[address]/collections-tab-content.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { getCollectionsByAdminAddress } from "@/collections/getCollectionsByAdminAddress"; -import { Suspense } from "react"; -import { COLLECTIONS_PER_PAGE } from "@/configs/ui"; -import Pagination from "@/components/pagination"; -import { HyperboardsOverview } from "@/app/profile/[address]/collections-tab-content-inner"; - -const CollectionsTabContentInner = async ({ - address, - searchParams, -}: { - address: string; - searchParams: Record; -}) => { - const currentPage = Number(searchParams?.p) || 1; - const result = await getCollectionsByAdminAddress({ - adminAddress: address, - first: COLLECTIONS_PER_PAGE, - offset: COLLECTIONS_PER_PAGE * (currentPage - 1), - }); - - if (!result) { - return null; - } - - const { hyperboards, count } = result; - - return ( -
- - -
- -
-
- ); -}; - -const CollectionsTabContent = ({ - address, - searchParams, -}: { - address: string; - searchParams: Record; -}) => { - return ( - Loading...}> - - - ); -}; -export { CollectionsTabContent }; diff --git a/app/profile/[address]/hypercerts-tab-content.client.tsx b/app/profile/[address]/hypercerts-tab-content.client.tsx new file mode 100644 index 00000000..52beb059 --- /dev/null +++ b/app/profile/[address]/hypercerts-tab-content.client.tsx @@ -0,0 +1,94 @@ +"use client"; + +import { ProfileSubTabKey, subTabs } from "@/app/profile/[address]/tabs"; +import { SubTabsWithCount } from "@/components/profile/sub-tabs-with-count"; +import HypercertWindow from "@/components/hypercert/hypercert-window"; +import { EmptySection } from "@/app/profile/[address]/sections"; +import { AllowListRecord } from "@/allowlists/getAllowListRecordsForAddressByClaimed"; +import UnclaimedHypercertsListContent from "@/components/profile/unclaimed-hypercerts-list-content"; + +export default function HypercertsTabContentInner({ + address, + activeTab, + createdHypercerts, + ownedHypercerts, + claimableHypercerts, +}: { + address: string; + activeTab: ProfileSubTabKey; + createdHypercerts?: { data: any[]; count: number }; + ownedHypercerts?: { data: any[]; count: number }; + claimableHypercerts?: { hypercert: any; record: AllowListRecord }[]; +}) { + const showCreatedHypercerts = !!( + createdHypercerts && createdHypercerts?.data?.length > 0 + ); + const showOwnedHypercerts = !!( + ownedHypercerts && ownedHypercerts?.data?.length > 0 + ); + const showClaimableHypercerts = !!( + claimableHypercerts && claimableHypercerts?.length > 0 + ); + + const tabBadgeCounts = { + "hypercerts-created": createdHypercerts?.count ?? 0, + "hypercerts-owned": ownedHypercerts?.count ?? 0, + "hypercerts-claimable": claimableHypercerts?.length ?? 0, + }; + + return ( +
+ tab.key.startsWith("hypercerts"))} + /> + + {activeTab === "hypercerts-owned" && + (showOwnedHypercerts ? ( +
+ {ownedHypercerts.data.map((hypercert) => ( + + ))} +
+ ) : ( +
+ +
+ ))} + + {activeTab === "hypercerts-created" && + (showCreatedHypercerts ? ( +
+ {createdHypercerts.data.map((hypercert) => ( + + ))} +
+ ) : ( +
+ +
+ ))} + + {activeTab === "hypercerts-claimable" && + (showClaimableHypercerts ? ( + + ) : ( +
+ +
+ ))} +
+ ); +} diff --git a/app/profile/[address]/hypercerts-tab-content.server.tsx b/app/profile/[address]/hypercerts-tab-content.server.tsx new file mode 100644 index 00000000..03be9511 --- /dev/null +++ b/app/profile/[address]/hypercerts-tab-content.server.tsx @@ -0,0 +1,55 @@ +import { Suspense } from "react"; +import { ProfileSubTabKey } from "@/app/profile/[address]/tabs"; +import ExploreListSkeleton from "@/components/explore/explore-list-skeleton"; +import HypercertsTabContentInner from "./hypercerts-tab-content.client"; +import { getHypercertsByCreator } from "@/hypercerts/getHypercertsByCreator"; +import { getHypercertsByOwner } from "@/hypercerts/getHypercertsByOwner"; +import { getAllowListRecordsForAddressByClaimed } from "@/allowlists/getAllowListRecordsForAddressByClaimed"; +import { getHypercert } from "@/hypercerts/getHypercert"; +import { InfoSection } from "@/app/profile/[address]/sections"; + +export const HypercertsTabContent = async ({ + address, + activeTab, +}: { + address: string; + activeTab: ProfileSubTabKey; +}) => { + // Fetch data server-side + const [createdHypercerts, ownedHypercerts, claimableRecords] = + await Promise.all([ + getHypercertsByCreator({ creatorAddress: address }), + getHypercertsByOwner({ ownerAddress: address }), + getAllowListRecordsForAddressByClaimed(address, false), + ]); + + if (!claimableRecords || claimableRecords?.data?.length === 0) { + return No unclaimed hypercerts; + } + + const claimableHypercerts = await Promise.all( + claimableRecords.data.map(async (record) => { + if (!record.hypercert_id) return []; + return [ + { + hypercert: await getHypercert(record.hypercert_id), + record, + }, + ]; + }), + ); + + const _claimableHypercerts = claimableHypercerts.flat(); + + return ( + }> + + + ); +}; diff --git a/app/profile/[address]/hypercerts-tab-content.tsx b/app/profile/[address]/hypercerts-tab-content.tsx deleted file mode 100644 index 043d1493..00000000 --- a/app/profile/[address]/hypercerts-tab-content.tsx +++ /dev/null @@ -1,124 +0,0 @@ -import { getHypercertsByCreator } from "@/hypercerts/getHypercertsByCreator"; -import { getAllowListRecordsForAddressByClaimed } from "@/allowlists/getAllowListRecordsForAddressByClaimed"; -import HypercertWindow from "@/components/hypercert/hypercert-window"; -import { EmptySection } from "@/app/profile/[address]/sections"; -import UnclaimedHypercertsList from "@/components/profile/unclaimed-hypercerts-list"; -import { Suspense } from "react"; -import ExploreListSkeleton from "@/components/explore/explore-list-skeleton"; -import { ProfileSubTabKey, subTabs } from "@/app/profile/[address]/tabs"; -import { SubTabsWithCount } from "@/components/profile/sub-tabs-with-count"; -import { getHypercertsByOwner } from "@/hypercerts/getHypercertsByOwner"; - -const HypercertsTabContentInner = async ({ - address, - activeTab, -}: { - address: string; - activeTab: ProfileSubTabKey; -}) => { - const createdHypercerts = await getHypercertsByCreator({ - creatorAddress: address, - }); - - const ownedHypercerts = await getHypercertsByOwner({ - ownerAddress: address, - }); - - const claimableHypercerts = await getAllowListRecordsForAddressByClaimed( - address, - false, - ); - - const showCreatedHypercerts = - createdHypercerts?.data && createdHypercerts.data.length > 0; - const showOwnedHypercerts = - ownedHypercerts?.data && ownedHypercerts.data.length > 0; - const showClaimableHypercerts = - claimableHypercerts?.data && claimableHypercerts.data.length > 0; - const hypercertSubTabs = subTabs.filter( - (tab) => tab.key.split("-")[0] === "hypercerts", - ); - - const tabBadgeCounts: Partial< - Record<(typeof subTabs)[number]["key"], number> - > = { - "hypercerts-created": createdHypercerts?.count ?? 0, - "hypercerts-owned": ownedHypercerts?.count ?? 0, - "hypercerts-claimable": claimableHypercerts?.count ?? 0, - }; - - return ( -
- - - {activeTab === "hypercerts-owned" && - (showOwnedHypercerts ? ( -
- {ownedHypercerts.data.map((hypercert) => { - return ( - - ); - })} -
- ) : ( -
- -
- ))} - - {activeTab === "hypercerts-created" && - (showCreatedHypercerts ? ( -
- {createdHypercerts.data.map((hypercert) => { - return ( - - ); - })} -
- ) : ( -
- -
- ))} - - {activeTab === "hypercerts-claimable" && - (showClaimableHypercerts ? ( - - ) : ( -
- -
- ))} -
- ); -}; - -const HypercertsTabContent = ({ - address, - activeTab, -}: { - address: string; - activeTab: ProfileSubTabKey; -}) => { - return ( - }> - - - ); -}; -export { HypercertsTabContent }; diff --git a/app/profile/[address]/marketplace-tab-content.client.tsx b/app/profile/[address]/marketplace-tab-content.client.tsx new file mode 100644 index 00000000..b2b23efd --- /dev/null +++ b/app/profile/[address]/marketplace-tab-content.client.tsx @@ -0,0 +1,59 @@ +"use client"; + +import { ProfileSubTabKey, subTabs } from "@/app/profile/[address]/tabs"; +import { SubTabsWithCount } from "@/components/profile/sub-tabs-with-count"; +import UserListingsList from "@/components/marketplace/user-listings-list"; +import UserDealsList from "@/components/marketplace/user-deals-list"; +import { CurrencyButtons } from "@/components/currency-buttons"; + +export default function MarketplaceTabContentInner({ + address, + activeTab, + orders, + buys, + sells, +}: { + address: string; + activeTab: ProfileSubTabKey; + orders: any[]; + buys: any[]; + sells: any[]; +}) { + const marketplaceSubTabs = subTabs.filter( + (tab) => tab.key.split("-")[0] === "marketplace", + ); + + const tabBadgeCounts = { + "marketplace-listings": orders.length, + "marketplace-bought": buys.length, + "marketplace-sold": sells.length, + }; + + return ( +
+
+ + {activeTab === "marketplace-listings" && } +
+ + {activeTab === "marketplace-listings" && ( +
+ +
+ )} + + {activeTab === "marketplace-bought" && ( + + )} + + {activeTab === "marketplace-sold" && ( + + )} +
+ ); +} diff --git a/app/profile/[address]/marketplace-tab-content.server.tsx b/app/profile/[address]/marketplace-tab-content.server.tsx new file mode 100644 index 00000000..c9eb015e --- /dev/null +++ b/app/profile/[address]/marketplace-tab-content.server.tsx @@ -0,0 +1,32 @@ +import { Suspense } from "react"; +import { ProfileSubTabKey } from "@/app/profile/[address]/tabs"; +import MarketplaceTabContentInner from "./marketplace-tab-content.client"; +import { getOrders } from "@/marketplace/getOpenOrders"; +import { getDealsForAddress } from "@/marketplace/getDealsForAddress"; +import MarketplaceTabSkeleton from "@/components/profile/marketplace-tab-skeleton"; + +export default async function MarketplaceTabContent({ + address, + activeTab, +}: { + address: string; + activeTab: ProfileSubTabKey; +}) { + const orders = await getOrders({ + filter: { signer: address as `0x${string}` }, + }); + const deals = await getDealsForAddress(address); + const { buys, sells } = deals || {}; + + return ( + }> + + + ); +} diff --git a/app/profile/[address]/marketplace-tab-content.tsx b/app/profile/[address]/marketplace-tab-content.tsx deleted file mode 100644 index 5bc11524..00000000 --- a/app/profile/[address]/marketplace-tab-content.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { Suspense } from "react"; -import UserListingsList from "@/components/marketplace/user-listings-list"; -import { getOrders } from "@/marketplace/getOpenOrders"; -import { ProfileSubTabKey, subTabs } from "@/app/profile/[address]/tabs"; -import { getDealsForAddress } from "@/marketplace/getDealsForAddress"; -import UserDealsList from "@/components/marketplace/user-deals-list"; -import ExploreListSkeleton from "@/components/explore/explore-list-skeleton"; -import { SubTabsWithCount } from "@/components/profile/sub-tabs-with-count"; -import { CurrencyButtons } from "@/components/currency-buttons"; - -const MarketplaceTabContentInner = async ({ - address, - activeTab, -}: { - address: string; - activeTab: ProfileSubTabKey; -}) => { - const orders = await getOrders({ - filter: { signer: address as `0x${string}` }, - }); - - const deals = await getDealsForAddress(address); - const { buys, sells } = deals || {}; - - const marketplaceSubTabs = subTabs.filter( - (tab) => tab.key.split("-")[0] === "marketplace", - ); - - const tabBadgeCounts: Partial< - Record<(typeof subTabs)[number]["key"], number> - > = { - "marketplace-listings": orders?.count ?? 0, - "marketplace-bought": buys?.count ?? 0, - "marketplace-sold": sells?.count ?? 0, - }; - return ( -
- - {activeTab === "marketplace-listings" && ( - Loading...}> -
- -
- -
- )} - - {activeTab === "marketplace-bought" && ( - Loading...}> - - - )} - - {activeTab === "marketplace-sold" && ( - Loading...}> - - - )} -
- ); -}; - -const MarketplaceTabContent = ({ - address, - activeTab, -}: { - address: string; - activeTab: ProfileSubTabKey; -}) => { - return ( - }> - - - ); -}; -export { MarketplaceTabContent }; diff --git a/app/profile/[address]/page.tsx b/app/profile/[address]/page.tsx index 0ceaac68..ad27ede6 100644 --- a/app/profile/[address]/page.tsx +++ b/app/profile/[address]/page.tsx @@ -1,13 +1,14 @@ +import { Suspense } from "react"; import { ProfileSubTabKey, ProfileTabSection, } from "@/app/profile/[address]/tabs"; - import EthAddress from "@/components/eth-address"; -import { HypercertsTabContent } from "@/app/profile/[address]/hypercerts-tab-content"; -import { CollectionsTabContent } from "@/app/profile/[address]/collections-tab-content"; -import { MarketplaceTabContent } from "@/app/profile/[address]/marketplace-tab-content"; -import { BlueprintsTabContent } from "@/app/profile/[address]/blueprint-tab-content"; +import MarketplaceTabContent from "@/app/profile/[address]/marketplace-tab-content.server"; +import BlueprintsTabContent from "@/app/profile/[address]/blueprint-tab-content.server"; +import TabContentSkeleton from "@/components/tab-content-skeleton"; +import { HypercertsTabContent } from "@/app/profile/[address]/hypercerts-tab-content.server"; +import CollectionsTabContent from "@/app/profile/[address]/collections-tab-content.server"; export default function ProfilePage({ params, @@ -17,8 +18,8 @@ export default function ProfilePage({ searchParams: Record; }) { const address = params.address; - const tab = searchParams?.tab || "hypercerts-owned"; - const mainTab = tab?.split("-")[0] ?? "hypercerts"; + const tab = (searchParams?.tab || "hypercerts-owned") as ProfileSubTabKey; + const mainTab = tab.split("-")[0]; return (
@@ -30,31 +31,27 @@ export default function ProfilePage({
- {(tab === undefined || mainTab === "hypercerts") && ( - - )} - {mainTab === "collections" && ( - - )} - {mainTab === "marketplace" && ( - - )} - {mainTab === "blueprints" && ( - - )} + }> + {mainTab === "hypercerts" && ( + + )} + {mainTab === "collections" && ( + + )} + {mainTab === "marketplace" && ( + + )} + {mainTab === "blueprints" && ( + + )} +
); diff --git a/app/profile/[address]/tabs.tsx b/app/profile/[address]/tabs.tsx index ad039621..abe71563 100644 --- a/app/profile/[address]/tabs.tsx +++ b/app/profile/[address]/tabs.tsx @@ -1,6 +1,8 @@ +"use client"; + import { Separator } from "@/components/ui/separator"; import { cn } from "@/lib/utils"; -import Link from "next/link"; +import { useRouter } from "next/navigation"; export const subTabs = [ { key: "hypercerts-owned", triggerLabel: "Owned" }, @@ -19,63 +21,65 @@ export type ProfileSubTabKey = | "collections" | "marketplace-orders"; -const mainTabs: { - prefix: string; - triggerLabel: string; - defaultSubTabKey: ProfileSubTabKey; -}[] = [ +const mainTabs = [ { prefix: "hypercerts", triggerLabel: "Hypercerts", - defaultSubTabKey: "hypercerts-created", + defaultSubTabKey: "hypercerts-created" as ProfileSubTabKey, }, { prefix: "collections", triggerLabel: "Collections", - defaultSubTabKey: "collections", + defaultSubTabKey: "collections" as ProfileSubTabKey, }, { prefix: "marketplace", triggerLabel: "Marketplace", - defaultSubTabKey: "marketplace-listings", + defaultSubTabKey: "marketplace-listings" as ProfileSubTabKey, }, { prefix: "blueprints", triggerLabel: "Blueprints", - defaultSubTabKey: "blueprints-claimable", + defaultSubTabKey: "blueprints-claimable" as ProfileSubTabKey, }, ]; export const createTabRoute = (address: string, tabKey: ProfileSubTabKey) => `/profile/${address}?tab=${tabKey}`; -const ProfileTabSection = ({ - address, - active = "hypercerts-created", -}: { +interface ProfileTabSectionProps { address: string; - active: string; -}) => { + active: ProfileSubTabKey; +} + +export const ProfileTabSection = ({ + address, + active, +}: ProfileTabSectionProps) => { + const router = useRouter(); const tabPrefix = active.split("-")[0]; + + const handleTabClick = (tabKey: ProfileSubTabKey) => { + router.push(createTabRoute(address, tabKey)); + }; + return (
{mainTabs.map(({ defaultSubTabKey, prefix, triggerLabel }) => ( - - - + ))}
); }; - -export { ProfileTabSection }; diff --git a/components/collections/buttons.tsx b/components/collections/buttons.tsx index d64f2d67..f79c52e6 100644 --- a/components/collections/buttons.tsx +++ b/components/collections/buttons.tsx @@ -18,12 +18,12 @@ import { useDeleteCollection } from "@/collections/hooks"; export const CreateCollectionButton = () => { return ( - + Create collection + ); }; @@ -33,12 +33,12 @@ export const EditCollectionButton = ({ collectionId: string; }) => { return ( - + Edit + ); }; @@ -50,13 +50,8 @@ export const DeleteCollectionButton = ({ const { mutateAsync: deleteCollection } = useDeleteCollection(); return ( - - + + Delete diff --git a/components/hyperboard/hyperboard-container.tsx b/components/hyperboard/hyperboard-container.tsx new file mode 100644 index 00000000..255677dc --- /dev/null +++ b/components/hyperboard/hyperboard-container.tsx @@ -0,0 +1,22 @@ +import Script from "next/script"; + +export const HyperboardWidgetContainer = ({ + hyperboardId, +}: { + hyperboardId: string; +}) => { + return ( +
+