Skip to content

Commit 1fb17f4

Browse files
authored
Merge pull request #456 from hypercerts-org/dev
Push to PRD
2 parents 441ea42 + 5d3ee30 commit 1fb17f4

32 files changed

+1541
-3084
lines changed

app/hypercerts/[hypercertId]/page.tsx

Lines changed: 58 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -79,63 +79,69 @@ export default async function HypercertPage({ params, searchParams }: Props) {
7979
defaultValue={defaultAccordionItems}
8080
className="w-full"
8181
>
82-
<AccordionItem value="creator-feed">
83-
{/* creator feed */}
84-
<AccordionTrigger className="uppercase text-sm text-slate-500 font-medium tracking-wider">
85-
CREATOR&apos;S FEED
86-
</AccordionTrigger>
87-
<AccordionContent>
88-
<div className="flex justify-end mb-4">
89-
<CreatorFeedButton
90-
hypercertId={hypercertId}
91-
creatorAddress={hypercert.creator_address!}
92-
disabledForChain={!isCreatorFeedEnabledOnChain}
93-
/>
94-
</div>
95-
<CreatorFeeds hypercertId={hypercertId} />
96-
</AccordionContent>
97-
</AccordionItem>
82+
<div id="creator-feed" className="w-full">
83+
<AccordionItem value="creator-feed">
84+
{/* creator feed */}
85+
<AccordionTrigger className="uppercase text-sm text-slate-500 font-medium tracking-wider">
86+
CREATOR&apos;S FEED
87+
</AccordionTrigger>
88+
<AccordionContent>
89+
<div className="flex justify-end mb-4">
90+
<CreatorFeedButton
91+
hypercertId={hypercertId}
92+
creatorAddress={hypercert.creator_address!}
93+
disabledForChain={!isCreatorFeedEnabledOnChain}
94+
/>
95+
</div>
96+
<CreatorFeeds hypercertId={hypercertId} />
97+
</AccordionContent>
98+
</AccordionItem>
99+
</div>
98100

99101
{/* evaluations */}
100-
<AccordionItem value="evaluations">
101-
<AccordionTrigger className="uppercase text-sm text-slate-500 font-medium tracking-wider">
102-
Evaluations
103-
</AccordionTrigger>
104-
<AccordionContent>
105-
<div className="flex justify-end mb-4">
106-
<EvaluateButton hypercertId={hypercertId} />
107-
</div>
108-
<HypercertEvaluations
109-
hypercertId={hypercertId}
110-
searchParams={searchParams}
111-
disabledForChain={!isEvaluationsEnabledOnChain}
112-
/>
113-
</AccordionContent>
114-
</AccordionItem>
102+
<div id="evaluations" className="w-full">
103+
<AccordionItem value="evaluations">
104+
<AccordionTrigger className="uppercase text-sm text-slate-500 font-medium tracking-wider">
105+
Evaluations
106+
</AccordionTrigger>
107+
<AccordionContent>
108+
<div className="flex justify-end mb-4">
109+
<EvaluateButton hypercertId={hypercertId} />
110+
</div>
111+
<HypercertEvaluations
112+
hypercertId={hypercertId}
113+
searchParams={searchParams}
114+
disabledForChain={!isEvaluationsEnabledOnChain}
115+
/>
116+
</AccordionContent>
117+
</AccordionItem>
118+
</div>
115119

116120
{/* marketplace */}
117-
<AccordionItem value="marketplace-listings">
118-
<AccordionTrigger className="uppercase text-sm text-slate-500 font-medium tracking-wider">
119-
Marketplace
120-
</AccordionTrigger>
121-
<AccordionContent>
122-
<div className="flex justify-end mb-4">
123-
<div className="flex gap-2">
124-
<CurrencyButtons />
125-
<ListForSaleButton
126-
hypercert={hypercert}
127-
disabledForChain={!isMarketplaceListingsEnabledOnChain}
128-
/>
121+
<div id="marketplace-listings" className="w-full">
122+
<AccordionItem value="marketplace-listings">
123+
<AccordionTrigger className="uppercase text-sm text-slate-500 font-medium tracking-wider">
124+
Marketplace
125+
</AccordionTrigger>
126+
<AccordionContent>
127+
<div className="flex justify-end mb-4">
128+
<div className="flex gap-2">
129+
<CurrencyButtons />
130+
<ListForSaleButton
131+
hypercert={hypercert}
132+
disabledForChain={!isMarketplaceListingsEnabledOnChain}
133+
/>
134+
</div>
129135
</div>
130-
</div>
131-
<HypercertListings
132-
hypercertId={hypercertId}
133-
initialHypercert={hypercert}
134-
searchParams={searchParams}
135-
invalidated={false}
136-
/>
137-
</AccordionContent>
138-
</AccordionItem>
136+
<HypercertListings
137+
hypercertId={hypercertId}
138+
initialHypercert={hypercert}
139+
searchParams={searchParams}
140+
invalidated={false}
141+
/>
142+
</AccordionContent>
143+
</AccordionItem>
144+
</div>
139145
</Accordion>
140146
</main>
141147
);

collections/hooks.ts

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useStepProcessDialogContext } from "@/components/global/step-process-di
77
import { useRouter } from "next/navigation";
88
import { isParseableNumber } from "@/lib/isParseableInteger";
99
import { isValidHypercertId } from "@/lib/utils";
10+
import { base64ToBlob } from "@/components/image-uploader";
1011

1112
export interface HyperboardCreateRequest {
1213
chainIds: number[];
@@ -50,6 +51,10 @@ export const useCreateHyperboard = () => {
5051
}
5152

5253
setSteps([
54+
{
55+
id: "Pinning IPFS",
56+
description: "Uploading Background Image to IPFS",
57+
},
5358
{
5459
id: "Awaiting signature",
5560
description: "Awaiting signature",
@@ -61,6 +66,43 @@ export const useCreateHyperboard = () => {
6166
]);
6267

6368
setOpen(true);
69+
70+
let imageUrl = data.backgroundImg;
71+
if (data.backgroundImg) {
72+
setStep("Pinning IPFS", "active");
73+
74+
const formData = new FormData();
75+
const blob = base64ToBlob(data.backgroundImg);
76+
const file = new File([blob], "backgroundImg.jpg", {
77+
type: "image/jpeg",
78+
});
79+
formData.append("files", file);
80+
81+
try {
82+
setStep("Pinning IPFS", "active");
83+
const response = await fetch(`${HYPERCERTS_API_URL_REST}/upload`, {
84+
method: "POST",
85+
body: formData,
86+
});
87+
const result = await response.json();
88+
if (!response.ok) {
89+
throw new Error(result?.data?.message || "Error pinning to IPFS");
90+
}
91+
if (result.success && result.data.results.length > 0) {
92+
imageUrl = `https://${result.data.results[0].cid}.ipfs.w3s.link`;
93+
await setStep("Pinning IPFS", "completed");
94+
}
95+
} catch (error) {
96+
await setStep(
97+
"Pinning IPFS",
98+
"error",
99+
error instanceof Error ? error.message : "Error pinning to IPFS",
100+
);
101+
}
102+
} else {
103+
await setStep("Pinning IPFS", "completed");
104+
}
105+
64106
await setStep("Awaiting signature", "active");
65107
let signature: string;
66108

@@ -141,7 +183,7 @@ export const useCreateHyperboard = () => {
141183
],
142184
borderColor: data.borderColor,
143185
chainIds: [chainId],
144-
backgroundImg: data.backgroundImg,
186+
backgroundImg: imageUrl,
145187
adminAddress: address,
146188
signature: signature,
147189
};
@@ -238,6 +280,10 @@ export const useUpdateHyperboard = () => {
238280
}
239281

240282
setSteps([
283+
{
284+
id: "Pinning IPFS",
285+
description: "Uploading Background Image to IPFS",
286+
},
241287
{
242288
id: "Awaiting signature",
243289
description: "Awaiting signature",
@@ -249,6 +295,39 @@ export const useUpdateHyperboard = () => {
249295
]);
250296

251297
setOpen(true);
298+
let imageUrl: string | undefined;
299+
if (data.backgroundImg) {
300+
await setStep("Pinning IPFS", "active");
301+
302+
const formData = new FormData();
303+
const blob = base64ToBlob(data.backgroundImg);
304+
const file = new File([blob], "backgroundImg.jpg", {
305+
type: "image/jpeg",
306+
});
307+
formData.append("files", file);
308+
309+
try {
310+
const response = await fetch(`${HYPERCERTS_API_URL_REST}/upload`, {
311+
method: "POST",
312+
body: formData,
313+
});
314+
const result = await response.json();
315+
if (!response.ok) {
316+
throw new Error(result?.data?.message || "Error pinning to IPFS");
317+
}
318+
if (result.success && result.data.results.length > 0) {
319+
imageUrl = `https://${result.data.results[0].cid}.ipfs.w3s.link`;
320+
await setStep("Pinning IPFS", "completed");
321+
}
322+
} catch (error) {
323+
await setStep(
324+
"Pinning IPFS",
325+
"error",
326+
error instanceof Error ? error.message : "Error pinning to IPFS",
327+
);
328+
}
329+
}
330+
252331
await setStep("Awaiting signature", "active");
253332
let signature: string;
254333

@@ -332,7 +411,7 @@ export const useUpdateHyperboard = () => {
332411
],
333412
borderColor: data.borderColor,
334413
chainIds: [chainId],
335-
backgroundImg: data.backgroundImg,
414+
backgroundImg: imageUrl,
336415
adminAddress: address,
337416
signature: signature,
338417
};

components/blueprints/buttons.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Button } from "@/components/ui/button";
2+
import { siteConfig } from "@/configs/site";
23
import Link from "next/link";
34
import React from "react";
45

@@ -8,7 +9,7 @@ export const CreateBlueprintButton = () => {
89
className="hover:text-white rounded-sm bg-white text-black border border-slate-300"
910
asChild
1011
>
11-
<Link href="/blueprints/new">Create blueprint</Link>
12+
<Link href={siteConfig.links.createBlueprint}>Create blueprint</Link>
1213
</Button>
1314
);
1415
};

components/collections/buttons.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ import {
1515
} from "@/components/ui/alert-dialog";
1616
import React from "react";
1717
import { useDeleteCollection } from "@/collections/hooks";
18+
import { siteConfig } from "@/configs/site";
1819

1920
export const CreateCollectionButton = () => {
2021
return (
2122
<Button
2223
className="hover:text-white rounded-sm bg-white text-black border border-slate-300"
2324
asChild
2425
>
25-
<Link href="/collections/create">Create collection</Link>
26+
<Link href={siteConfig.links.createCollection}>Create collection</Link>
2627
</Button>
2728
);
2829
};

0 commit comments

Comments
 (0)