Skip to content

Commit c0047b7

Browse files
authored
Feature/collections qa 2 (#282)
* fix: show fetching indicator correctly * fix: show blueprints overview * fix: revalidate profile when minting from blueprint * fix: revalidate profile when creating blueprint * fix: add invalidation when minting from blueprints * fix: revalidate specificy page to handle dynamic routes * fix: various qa issues * fix: various qa issues
1 parent 269aa85 commit c0047b7

16 files changed

+299
-40
lines changed

app/actions.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ export default async function revalidatePathServerAction(
77
) {
88
if (typeof path === "string") {
99
console.log("revalidating path", path);
10-
revalidatePath(path);
10+
revalidatePath(path, "page");
1111
return;
1212
}
1313

1414
for (const p of path) {
1515
console.log("revalidating path", p);
16-
revalidatePath(p);
16+
revalidatePath(p, "page");
1717
}
1818
}

app/profile/[address]/blueprint-tab-content.tsx

+42-4
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,40 @@
1-
import { Suspense } from "react";
1+
import React, { Suspense } from "react";
22
import { ProfileSubTabKey, subTabs } from "@/app/profile/[address]/tabs";
33
import ExploreListSkeleton from "@/components/explore/explore-list-skeleton";
44
import { SubTabsWithCount } from "@/components/profile/sub-tabs-with-count";
55
import { getBlueprints } from "@/blueprints/getBlueprints";
66
import BlueprintsList from "@/components/blueprints/blueprints-list";
7+
import { CreateBlueprintButton } from "@/components/blueprints/buttons";
8+
import { OwnAccountOnly } from "@/components/own-account-only";
9+
import { BlueprintsTable } from "@/components/blueprints/blueprints-table";
10+
import { BLUEPRINTS_PER_PAGE } from "@/configs/ui";
11+
import Pagination from "@/components/pagination";
712

813
const BlueprintTabContentInner = async ({
914
address,
1015
activeTab,
16+
searchParams,
1117
}: {
1218
address: string;
1319
activeTab: ProfileSubTabKey;
20+
searchParams: Record<string, string>;
1421
}) => {
22+
const currentPage = Number(searchParams?.p) || 1;
23+
1524
const availableBlueprints = await getBlueprints({
1625
filters: { minterAddress: address as `0x${string}`, minted: false },
26+
first: BLUEPRINTS_PER_PAGE,
27+
offset: BLUEPRINTS_PER_PAGE * (currentPage - 1),
1728
});
1829
const mintedBlueprints = await getBlueprints({
1930
filters: { minterAddress: address as `0x${string}`, minted: true },
31+
first: BLUEPRINTS_PER_PAGE,
32+
offset: BLUEPRINTS_PER_PAGE * (currentPage - 1),
33+
});
34+
const blueprintsCreated = await getBlueprints({
35+
filters: { adminAddress: address as `0x${string}` },
36+
first: BLUEPRINTS_PER_PAGE,
37+
offset: BLUEPRINTS_PER_PAGE * (currentPage - 1),
2038
});
2139

2240
const marketplaceSubTabs = subTabs.filter(
@@ -28,8 +46,10 @@ const BlueprintTabContentInner = async ({
2846
> = {
2947
"blueprints-claimable": availableBlueprints?.count ?? 0,
3048
"blueprints-claimed": mintedBlueprints?.count ?? 0,
31-
"blueprints-created": availableBlueprints?.count ?? 0,
49+
"blueprints-created": blueprintsCreated?.count ?? 0,
3250
};
51+
const currentCount =
52+
tabBadgeCounts[activeTab as (typeof subTabs)[number]["key"]];
3353
return (
3454
<section>
3555
<SubTabsWithCount
@@ -38,6 +58,12 @@ const BlueprintTabContentInner = async ({
3858
tabBadgeCounts={tabBadgeCounts}
3959
tabs={marketplaceSubTabs}
4060
/>
61+
62+
<OwnAccountOnly addressToMatch={address}>
63+
<div className="flex justify-end mb-2">
64+
<CreateBlueprintButton />
65+
</div>
66+
</OwnAccountOnly>
4167
{activeTab === "blueprints-claimable" && (
4268
<BlueprintsList blueprints={availableBlueprints?.blueprints || []} />
4369
)}
@@ -47,22 +73,34 @@ const BlueprintTabContentInner = async ({
4773
)}
4874

4975
{activeTab === "blueprints-created" && (
50-
<BlueprintsList blueprints={availableBlueprints?.blueprints || []} />
76+
<BlueprintsTable
77+
blueprints={blueprintsCreated?.blueprints || []}
78+
count={blueprintsCreated?.count}
79+
/>
5180
)}
81+
<div className="mt-5">
82+
<Pagination count={currentCount || 0} pageSize={BLUEPRINTS_PER_PAGE} />
83+
</div>
5284
</section>
5385
);
5486
};
5587

5688
const BlueprintsTabContent = ({
5789
address,
5890
activeTab,
91+
searchParams,
5992
}: {
6093
address: string;
6194
activeTab: ProfileSubTabKey;
95+
searchParams: Record<string, string>;
6296
}) => {
6397
return (
6498
<Suspense fallback={<ExploreListSkeleton length={9} />}>
65-
<BlueprintTabContentInner address={address} activeTab={activeTab} />
99+
<BlueprintTabContentInner
100+
address={address}
101+
activeTab={activeTab}
102+
searchParams={searchParams}
103+
/>
66104
</Suspense>
67105
);
68106
};

app/profile/[address]/collections-tab-content.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { getCollectionsByAdminAddress } from "@/collections/getCollectionsByAdminAddress";
22
import { Suspense } from "react";
33
import { COLLECTIONS_PER_PAGE } from "@/configs/ui";
4-
import CollectionPagination from "@/components/collections/collection-pagination";
4+
import Pagination from "@/components/pagination";
55
import { HyperboardsOverview } from "@/app/profile/[address]/collections-tab-content-inner";
66

77
const CollectionsTabContentInner = async ({
@@ -29,7 +29,7 @@ const CollectionsTabContentInner = async ({
2929
<HyperboardsOverview profileAddress={address} hyperboards={hyperboards} />
3030

3131
<div className="mt-5">
32-
<CollectionPagination collectionsCount={count || 0} />
32+
<Pagination count={count || 0} />
3333
</div>
3434
</div>
3535
);

app/profile/[address]/page.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ export default function ProfilePage({
5252
<BlueprintsTabContent
5353
address={address}
5454
activeTab={tab as ProfileSubTabKey}
55+
searchParams={searchParams}
5556
/>
5657
)}
5758
</section>

app/profile/[address]/tabs.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ export const subTabs = [
99
{ key: "marketplace-listings", triggerLabel: "Listings" },
1010
{ key: "marketplace-bought", triggerLabel: "Bought" },
1111
{ key: "marketplace-sold", triggerLabel: "Sold" },
12-
{ key: "blueprints-claimable", triggerLabel: "Claimable" },
13-
{ key: "blueprints-claimed", triggerLabel: "Claimed" },
14-
{ key: "blueprints-created", triggerLabel: "Created" },
12+
{ key: "blueprints-claimable", triggerLabel: "To be minted" },
13+
{ key: "blueprints-claimed", triggerLabel: "Minted" },
14+
{ key: "blueprints-created", triggerLabel: "Sent" },
1515
] as const;
1616

1717
export type ProfileSubTabKey =

blueprints/getBlueprints.ts

+25-17
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,8 @@ import { HypercertFormValues } from "@/components/hypercert/hypercert-minting-fo
1010

1111
const query = graphql(
1212
`
13-
query Blueprint(
14-
$minter_address: String
15-
$minted: Boolean
16-
$first: Int
17-
$offset: Int
18-
) {
19-
blueprints(
20-
where: {
21-
minter_address: { eq: $minter_address }
22-
minted: { eq: $minted }
23-
}
24-
first: $first
25-
offset: $offset
26-
) {
13+
query Blueprint($where: BlueprintWhereInput, $first: Int, $offset: Int) {
14+
blueprints(where: $where, first: $first, offset: $offset) {
2715
count
2816
data {
2917
...BlueprintFragment
@@ -34,23 +22,43 @@ const query = graphql(
3422
[BlueprintFragment],
3523
);
3624

25+
const buildFilters = (filters: {
26+
minterAddress?: string;
27+
adminAddress?: string;
28+
minted?: boolean;
29+
}) => {
30+
const where: Record<string, unknown> = {};
31+
if (filters.minterAddress) {
32+
where["minter_address"] = { eq: filters.minterAddress };
33+
}
34+
if (filters.adminAddress) {
35+
where["admin_address"] = { eq: filters.adminAddress };
36+
}
37+
if (filters.minted !== undefined) {
38+
where["minted"] = { eq: filters.minted };
39+
}
40+
if (Object.keys(where).length === 0) {
41+
return undefined;
42+
}
43+
return where;
44+
};
45+
3746
export async function getBlueprints({
3847
filters,
3948
first = COLLECTIONS_PER_PAGE,
4049
offset = 0,
4150
}: {
4251
filters: {
4352
minterAddress?: string;
53+
adminAddress?: string;
4454
minted?: boolean;
4555
ids?: number[];
4656
};
4757
first?: number;
4858
offset?: number;
4959
}) {
5060
const res = await request(HYPERCERTS_API_URL_GRAPH, query, {
51-
minter_address: filters.minterAddress,
52-
minted: filters.minted,
53-
ids: filters.ids,
61+
where: buildFilters(filters) as any,
5462
first,
5563
offset,
5664
});

blueprints/hooks/createBlueprint.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export const useCreateBlueprint = () => {
7777
return null;
7878
}
7979

80-
await setStep("Updating blueprint");
80+
await setStep("Creating blueprint");
8181

8282
try {
8383
const { acceptTerms, confirmContributorsPermission, ...form_values } =
@@ -97,19 +97,22 @@ export const useCreateBlueprint = () => {
9797
},
9898
}).then((res) => {
9999
if (!res.ok) {
100-
throw new Error("Error updating blueprint");
100+
throw new Error("Error creating blueprint");
101101
}
102102
});
103103
await setStep("Updating blueprint", "completed");
104-
await revalidatePathServerAction("/blueprints");
104+
await revalidatePathServerAction([
105+
"/blueprints",
106+
`/profile/${address}`,
107+
]);
105108
setTimeout(() => {
106109
setOpen(false);
107110
}, 2000);
108111
} catch (error) {
109112
await setStep(
110-
"Updating blueprint",
113+
"Creating blueprint",
111114
"error",
112-
error instanceof Error ? error.message : "Error updating blueprint",
115+
error instanceof Error ? error.message : "Error creating blueprint",
113116
);
114117
}
115118
},

components/blueprints/blueprints-list.tsx

+4
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@ import { HypercertFormValues } from "@/components/hypercert/hypercert-minting-fo
55
import { Button } from "@/components/ui/button";
66
import Link from "next/link";
77
import { getUnixTime } from "date-fns";
8+
import { EmptySection } from "@/app/profile/[address]/sections";
89

910
export const BlueprintsList = ({
1011
blueprints,
1112
}: {
1213
blueprints: readonly BlueprintFragment[];
1314
}) => {
15+
if (!blueprints.length) {
16+
return <EmptySection />;
17+
}
1418
return (
1519
<div className="grid grid-cols-[repeat(auto-fit,_minmax(270px,_1fr))] gap-4">
1620
{blueprints.map((blueprint, i) => (

0 commit comments

Comments
 (0)