Skip to content

Commit 5bf71ff

Browse files
committed
updated creation pages
1 parent 360e889 commit 5bf71ff

File tree

2 files changed

+359
-74
lines changed
  • apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/assets

2 files changed

+359
-74
lines changed

apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/assets/create-nft/page.tsx

Lines changed: 184 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,46 @@ import {
1515
CheckIcon,
1616
ChevronDownIcon,
1717
ChevronUpIcon,
18+
Loader2,
1819
} from "lucide-react";
1920
import { useState } from "react";
2021
import { useForm } from "react-hook-form";
2122
import * as z from "zod";
22-
import { Fieldset } from "components/contract-components/contract-deploy-form/common";
23-
import { FileInput } from "components/shared/FileInput";
24-
import { BasisPointsInput } from "components/inputs/BasisPointsInput";
25-
import { SolidityInput } from "contract-ui/components/solidity-inputs";
23+
import Link from "next/link";
24+
import Image from "next/image";
25+
import { Card, CardContent } from "@/components/ui/card";
26+
import {
27+
FormField,
28+
FormItem,
29+
FormLabel,
30+
FormControl,
31+
FormMessage,
32+
FormDescription,
33+
} from "@/components/ui/form";
34+
import {
35+
Tooltip,
36+
TooltipContent,
37+
TooltipProvider,
38+
TooltipTrigger,
39+
} from "@/components/ui/tooltip";
2640
import { Form } from "@/components/ui/form";
2741
import { NetworkSelectorButton } from "components/selects/NetworkSelectorButton";
42+
import { useActiveAccount, useSwitchActiveWalletChain } from "thirdweb/react";
43+
import { deployContractfromDeployMetadata } from "thirdweb/deploys";
44+
import { useThirdwebClient } from "@/constants/thirdweb.client";
45+
import { defineChain } from "thirdweb/chains";
46+
import { toast } from "sonner";
47+
import { useDashboardRouter } from "@/lib/DashboardRouter";
48+
import { upload } from "thirdweb/storage";
49+
import { Fieldset } from "components/contract-components/contract-deploy-form/common";
50+
import { FileInput } from "components/shared/FileInput";
51+
import {
52+
Select,
53+
SelectContent,
54+
SelectItem,
55+
SelectTrigger,
56+
SelectValue,
57+
} from "@/components/ui/select";
2858

2959
// Form schemas
3060
const collectionInfoSchema = z.object({
@@ -85,18 +115,20 @@ const StepIndicator = ({
85115
);
86116

87117
export default function CreateNFTPage() {
88-
const [step, setStep] = useState<number>(1);
89-
const [collectionInfo, setCollectionInfo] = useState<CollectionInfoValues>();
90-
const [mintSettings, setMintSettings] = useState<MintSettingsValues>({
91-
price: "0.1",
92-
supply: "10000",
93-
initialMint: "1",
94-
royaltyPercentage: "0",
95-
royaltyAddress: "",
96-
collectionType: "new",
97-
platformFeeBps: "250",
98-
});
118+
const [currentStep, setCurrentStep] = useState(1);
119+
const [collectionInfo, setCollectionInfo] =
120+
useState<CollectionInfoValues | null>(null);
121+
const [mintSettings, setMintSettings] = useState<MintSettingsValues | null>(
122+
null
123+
);
99124
const [showRoyaltySettings, setShowRoyaltySettings] = useState(false);
125+
const [isDeploying, setIsDeploying] = useState(false);
126+
const router = useDashboardRouter();
127+
const params = router.params;
128+
const activeAccount = useActiveAccount();
129+
const switchChain = useSwitchActiveWalletChain();
130+
const thirdwebClient = useThirdwebClient();
131+
const connectedAddress = activeAccount?.address;
100132

101133
// Forms
102134
const collectionInfoForm = useForm<CollectionInfoValues>({
@@ -127,17 +159,17 @@ export default function CreateNFTPage() {
127159
// Step handlers
128160
const onCollectionInfoSubmit = (data: CollectionInfoValues) => {
129161
setCollectionInfo(data);
130-
setStep(2);
162+
setCurrentStep(2);
131163
};
132164

133165
const onMintSettingsSubmit = (data: MintSettingsValues) => {
134166
setMintSettings(data);
135-
setStep(3);
167+
setCurrentStep(3);
136168
};
137169

138170
const goBack = () => {
139-
if (step > 1) {
140-
setStep(step - 1);
171+
if (currentStep > 1) {
172+
setCurrentStep(currentStep - 1);
141173
}
142174
};
143175

@@ -151,7 +183,7 @@ export default function CreateNFTPage() {
151183
<div className="w-1/2 flex items-center">
152184
<div
153185
className={`h-0.5 w-full ${
154-
step > 1 ? "bg-primary/20" : "bg-muted"
186+
currentStep > 1 ? "bg-primary/20" : "bg-muted"
155187
}`}
156188
style={{ marginLeft: "25px", marginRight: "25px" }}
157189
/>
@@ -160,16 +192,16 @@ export default function CreateNFTPage() {
160192
<div className="w-1/2 flex items-center">
161193
<div
162194
className={`h-0.5 w-full ${
163-
step > 2 ? "bg-primary/20" : "bg-muted"
195+
currentStep > 2 ? "bg-primary/20" : "bg-muted"
164196
}`}
165197
style={{ marginLeft: "25px", marginRight: "25px" }}
166198
/>
167199
</div>
168200
</div>
169201

170-
<StepIndicator step={1} currentStep={step} label="Basic Info" />
171-
<StepIndicator step={2} currentStep={step} label="Options" />
172-
<StepIndicator step={3} currentStep={step} label="Overview" />
202+
<StepIndicator step={1} currentStep={currentStep} label="Basic Info" />
203+
<StepIndicator step={2} currentStep={currentStep} label="Options" />
204+
<StepIndicator step={3} currentStep={currentStep} label="Overview" />
173205
</div>
174206
</div>
175207
);
@@ -578,7 +610,11 @@ export default function CreateNFTPage() {
578610
<div>
579611
<h3 className="text-lg font-medium mb-4 flex justify-between">
580612
Basic Info
581-
<Button variant="ghost" size="sm" onClick={() => setStep(1)}>
613+
<Button
614+
variant="ghost"
615+
size="sm"
616+
onClick={() => setCurrentStep(1)}
617+
>
582618
Edit
583619
</Button>
584620
</h3>
@@ -641,7 +677,11 @@ export default function CreateNFTPage() {
641677
<div>
642678
<h3 className="text-lg font-medium mb-4 flex justify-between">
643679
Options
644-
<Button variant="ghost" size="sm" onClick={() => setStep(2)}>
680+
<Button
681+
variant="ghost"
682+
size="sm"
683+
onClick={() => setCurrentStep(2)}
684+
>
645685
Edit
646686
</Button>
647687
</h3>
@@ -719,11 +759,19 @@ export default function CreateNFTPage() {
719759
<Button
720760
type="button"
721761
className="bg-primary hover:bg-primary/90"
722-
onClick={() =>
723-
alert("NFT Collection creation would be processed here")
724-
}
762+
onClick={deployNFTCollection}
763+
disabled={isDeploying}
725764
>
726-
Deploy Collection <CheckIcon className="ml-2 h-4 w-4" />
765+
{isDeploying ? (
766+
<>
767+
<Loader2 className="mr-2 h-4 w-4 animate-spin" /> Deploying
768+
Collection...
769+
</>
770+
) : (
771+
<>
772+
Deploy Collection <CheckIcon className="ml-2 h-4 w-4" />
773+
</>
774+
)}
727775
</Button>
728776
</div>
729777
</div>
@@ -733,7 +781,7 @@ export default function CreateNFTPage() {
733781

734782
// Render the appropriate step
735783
const renderCurrentStep = () => {
736-
switch (step) {
784+
switch (currentStep) {
737785
case 1:
738786
return renderStep1();
739787
case 2:
@@ -745,5 +793,110 @@ export default function CreateNFTPage() {
745793
}
746794
};
747795

796+
// Add this after the existing functions
797+
const deployNFTCollection = async () => {
798+
if (!collectionInfo || !mintSettings || !activeAccount || !thirdwebClient) {
799+
toast.error("Missing required information. Please check your inputs.");
800+
return;
801+
}
802+
803+
setIsDeploying(true);
804+
805+
try {
806+
// Make sure we have the necessary URL parts
807+
const pathParts = window.location.pathname.split("/");
808+
const teamSlug = pathParts[2];
809+
const projectSlug = pathParts[3];
810+
811+
if (!teamSlug || !projectSlug) {
812+
throw new Error("Invalid URL structure");
813+
}
814+
815+
console.log("Collection info:", collectionInfo);
816+
console.log("Mint settings:", mintSettings);
817+
818+
// Make sure we have all required collection properties
819+
if (
820+
!collectionInfo.name ||
821+
!collectionInfo.symbol ||
822+
!collectionInfo.chain
823+
) {
824+
throw new Error("Missing required collection information");
825+
}
826+
827+
// Get wallet chain
828+
const chainId = parseInt(collectionInfo.chain, 10);
829+
const walletChain = isNaN(chainId)
830+
? defineChain({ name: collectionInfo.chain.toLowerCase() })
831+
: defineChain({ chainId });
832+
833+
console.log("Using chain:", walletChain);
834+
835+
// Switch network if needed
836+
await switchChain({ chain: walletChain });
837+
838+
// Handle collection image
839+
let imageUri = "";
840+
if (collectionInfo.image) {
841+
try {
842+
const imageFile = await fetch(collectionInfo.image).then((r) =>
843+
r.blob()
844+
);
845+
imageUri = await upload({
846+
client: thirdwebClient,
847+
data: [imageFile],
848+
});
849+
} catch (err) {
850+
console.error("Error uploading image:", err);
851+
}
852+
}
853+
854+
// Prepare initialization parameters
855+
const initializeParams = {
856+
name: collectionInfo.name,
857+
symbol: collectionInfo.symbol,
858+
description: collectionInfo.description || "",
859+
primary_sale_recipient:
860+
mintSettings.royaltyAddress || activeAccount.address,
861+
fee_recipient: mintSettings.royaltyAddress || activeAccount.address,
862+
seller_fee_basis_points:
863+
parseInt(mintSettings.royaltyPercentage || "0") * 100,
864+
};
865+
866+
console.log("Deploying with parameters:", initializeParams);
867+
868+
// Deploy the contract
869+
const contractAddress = await deployContractfromDeployMetadata({
870+
client: thirdwebClient,
871+
signer: activeAccount,
872+
contractMetadata: {
873+
name: collectionInfo.name,
874+
description: collectionInfo.description || "",
875+
image: imageUri,
876+
external_link: "",
877+
},
878+
publishMetadata: {
879+
name: "NFTCollection",
880+
publisherAddress: activeAccount.address,
881+
},
882+
constructorParams: initializeParams,
883+
});
884+
885+
toast.success("NFT Collection deployed successfully!");
886+
887+
// Navigate to the collection's page
888+
router.push(
889+
`/team/${teamSlug}/${projectSlug}/contracts/${contractAddress}`
890+
);
891+
} catch (error) {
892+
console.error("Error deploying NFT collection:", error);
893+
toast.error(
894+
`Failed to deploy NFT collection: ${error instanceof Error ? error.message : "Unknown error"}`
895+
);
896+
} finally {
897+
setIsDeploying(false);
898+
}
899+
};
900+
748901
return <div className="w-full py-8">{renderCurrentStep()}</div>;
749902
}

0 commit comments

Comments
 (0)