diff --git a/.gitignore b/.gitignore index aa0698d8..fa9edf37 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ node_modules package-lock.json -templates/*/move/build \ No newline at end of file +templates/*/move/build +templates/*/build \ No newline at end of file diff --git a/templates/digital-asset-template/frontend/App.tsx b/templates/digital-asset-template/frontend/App.tsx index 3c2f3d98..d50adc0a 100644 --- a/templates/digital-asset-template/frontend/App.tsx +++ b/templates/digital-asset-template/frontend/App.tsx @@ -1,8 +1,8 @@ import { Outlet, RouterProvider, createBrowserRouter } from "react-router-dom"; -import { Mint } from "./pages/Mint"; -import { CreateCollection } from "./pages/CreateCollection"; -import { MyCollections } from "./pages/MyCollections"; +import { Mint } from "@/pages/Mint"; +import { CreateCollection } from "@/pages/CreateCollection"; +import { MyCollections } from "@/pages/MyCollections"; function Layout() { return ( diff --git a/templates/digital-asset-template/frontend/components/Header.tsx b/templates/digital-asset-template/frontend/components/Header.tsx index b24fd839..c2cae95a 100644 --- a/templates/digital-asset-template/frontend/components/Header.tsx +++ b/templates/digital-asset-template/frontend/components/Header.tsx @@ -1,20 +1,16 @@ -import { useMintData } from "@/pages/Mint/hooks/useMintData"; +import { useGetCollectionData } from "@/hooks/useGetCollectionData"; import { useMemo } from "react"; import { Link } from "react-router-dom"; import { WalletSelector } from "./WalletSelector"; import { IS_DEV } from "@/constants"; -import { buttonVariants } from "./ui/button"; +import { buttonVariants } from "@/components/ui/button"; import { config } from "@/config"; export function Header() { - const { data } = useMintData(); + const { data } = useGetCollectionData(); const title = useMemo(() => { - return ( - data?.collection.collection_name ?? - config.defaultCollection?.name ?? - "NFT Collection Launchpad" - ); + return data?.collection.collection_name ?? config.defaultCollection?.name ?? "NFT Collection Launchpad"; }, [data?.collection]); return ( @@ -26,14 +22,10 @@ export function Header() {
{IS_DEV && ( <> - + My Collections - + Create Collection diff --git a/templates/digital-asset-template/frontend/components/LaunchpadHeader.tsx b/templates/digital-asset-template/frontend/components/LaunchpadHeader.tsx index 17c5e4d5..0079da13 100644 --- a/templates/digital-asset-template/frontend/components/LaunchpadHeader.tsx +++ b/templates/digital-asset-template/frontend/components/LaunchpadHeader.tsx @@ -1,8 +1,9 @@ import { Link, useLocation } from "react-router-dom"; -import { WalletSelector } from "./WalletSelector"; -import { buttonVariants } from "./ui/button"; import { FC } from "react"; +import { WalletSelector } from "@/components/WalletSelector"; +import { buttonVariants } from "@/components/ui/button"; + interface LaunchpadHeaderProps { title: string; } @@ -19,15 +20,11 @@ export const LaunchpadHeader: FC = ({ title }) => { Mint Page {location.pathname === "/create-collection" ? ( - + My Collections ) : ( - + Create Collection )} diff --git a/templates/digital-asset-template/frontend/components/UploadSpinner.tsx b/templates/digital-asset-template/frontend/components/UploadSpinner.tsx index 1d58bfd2..073f77a9 100644 --- a/templates/digital-asset-template/frontend/components/UploadSpinner.tsx +++ b/templates/digital-asset-template/frontend/components/UploadSpinner.tsx @@ -1,13 +1,14 @@ -import { cn } from "@/lib/utils"; -import { Spinner } from "./ui/spinner"; import { FC } from "react"; +import { cn } from "@/lib/utils"; +import { Spinner } from "@/components/ui/spinner"; + export const UploadSpinner: FC<{ on: boolean }> = ({ on }) => { return (

Uploading Files...

diff --git a/templates/digital-asset-template/frontend/components/WalletProvider.tsx b/templates/digital-asset-template/frontend/components/WalletProvider.tsx index 132d9e09..df8411ea 100644 --- a/templates/digital-asset-template/frontend/components/WalletProvider.tsx +++ b/templates/digital-asset-template/frontend/components/WalletProvider.tsx @@ -1,6 +1,7 @@ import { PropsWithChildren } from "react"; -import { useToast } from "./ui/use-toast"; import { AptosWalletAdapterProvider } from "@aptos-labs/wallet-adapter-react"; + +import { useToast } from "@/components/ui/use-toast"; import { NETWORK } from "@/constants"; export function WalletProvider({ children }: PropsWithChildren) { diff --git a/templates/digital-asset-template/frontend/components/WalletSelector.tsx b/templates/digital-asset-template/frontend/components/WalletSelector.tsx index b1557eee..37cfba99 100644 --- a/templates/digital-asset-template/frontend/components/WalletSelector.tsx +++ b/templates/digital-asset-template/frontend/components/WalletSelector.tsx @@ -12,26 +12,17 @@ import { import { useLocation } from "react-router-dom"; import { ChevronDown, Copy, LogOut, User } from "lucide-react"; import { useCallback, useState } from "react"; -import { Button } from "./ui/button"; -import { - Collapsible, - CollapsibleContent, - CollapsibleTrigger, -} from "./ui/collapsible"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogTrigger, -} from "./ui/dialog"; + +import { Button } from "@/components/ui/button"; +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; +import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, -} from "./ui/dropdown-menu"; -import { useToast } from "./ui/use-toast"; +} from "@/components/ui/dropdown-menu"; +import { useToast } from "@/components/ui/use-toast"; export function WalletSelector() { const { account, connected, disconnect, wallet } = useWallet(); @@ -60,9 +51,7 @@ export function WalletSelector() { return connected ? ( - + @@ -70,12 +59,7 @@ export function WalletSelector() { {wallet && isAptosConnectWallet(wallet) && ( - + Account @@ -133,11 +117,7 @@ function ConnectWalletDialog({ close }: ConnectWalletDialogProps) {
{aptosConnectWallets.map((wallet) => ( - + ))}
@@ -166,11 +146,7 @@ function ConnectWalletDialog({ close }: ConnectWalletDialogProps) { {moreWallets.map((wallet) => ( - + ))} diff --git a/templates/digital-asset-template/frontend/entry-functions/create_collection.ts b/templates/digital-asset-template/frontend/entry-functions/create_collection.ts new file mode 100644 index 00000000..b4b4cdb2 --- /dev/null +++ b/templates/digital-asset-template/frontend/entry-functions/create_collection.ts @@ -0,0 +1,65 @@ +import { AccountAddressInput } from "@aptos-labs/ts-sdk"; +import { InputTransactionData } from "@aptos-labs/wallet-adapter-react"; + +import { APT_DECIMALS, dateToSeconds, convertAmountFromHumanReadableToOnChain } from "@/utils/helpers"; + +export type CreateCollectionArguments = { + collectionDescription: string; // The collection description + collectionName: string; // The collection name + projectUri: string; // The project URI (i.e https://mydomain.com) + maxSupply: number; // The amount of NFTs in a collection + royaltyPercentage?: number; // The percentage of trading value that collection creator gets when an NFT is sold on marketplaces + preMintAmount?: number; // amount of NFT to pre-mint for myself + allowList?: Array; // addresses in the allow list + allowListStartDate?: Date; // allow list start time (in seconds) + allowListEndDate?: Date; // allow list end time (in seconds) + allowListLimitPerAccount?: number; // mint limit per address in the allow list + allowListFeePerNFT?: number; // mint fee per NFT for the allow list + publicMintStartDate?: Date; // public mint start time (in seconds) + publicMintEndDate?: Date; // public mint end time (in seconds) + publicMintLimitPerAccount: number; // mint limit per address in the public mint + publicMintFeePerNFT?: number; // mint fee per NFT for the public mint, on chain stored in smallest unit of APT (i.e. 1e8 oAPT = 1 APT) +}; + +export const createCollection = (args: CreateCollectionArguments): InputTransactionData => { + const { + collectionDescription, + collectionName, + projectUri, + maxSupply, + royaltyPercentage, + preMintAmount, + allowList, + allowListStartDate, + allowListEndDate, + allowListLimitPerAccount, + allowListFeePerNFT, + publicMintStartDate, + publicMintEndDate, + publicMintLimitPerAccount, + publicMintFeePerNFT, + } = args; + return { + data: { + function: `${import.meta.env.VITE_MODULE_ADDRESS}::launchpad::create_collection`, + typeArguments: [], + functionArguments: [ + collectionDescription, + collectionName, + projectUri, + maxSupply, + royaltyPercentage, + preMintAmount, + allowList, + dateToSeconds(allowListStartDate), + dateToSeconds(allowListEndDate), + allowListLimitPerAccount, + allowListFeePerNFT, + publicMintStartDate ? dateToSeconds(publicMintStartDate) : dateToSeconds(new Date()), + dateToSeconds(publicMintEndDate), + publicMintLimitPerAccount, + publicMintFeePerNFT ? convertAmountFromHumanReadableToOnChain(publicMintFeePerNFT, APT_DECIMALS) : 0, + ], + }, + }; +}; diff --git a/templates/digital-asset-template/frontend/entry-functions/mint_nft.ts b/templates/digital-asset-template/frontend/entry-functions/mint_nft.ts new file mode 100644 index 00000000..cda209f4 --- /dev/null +++ b/templates/digital-asset-template/frontend/entry-functions/mint_nft.ts @@ -0,0 +1,17 @@ +import { InputTransactionData } from "@aptos-labs/wallet-adapter-react"; + +export type MintNftArguments = { + collectionId: string; + amount: number; +}; + +export const mintNFT = (args: MintNftArguments): InputTransactionData => { + const { collectionId, amount } = args; + return { + data: { + function: `${import.meta.env.VITE_MODULE_ADDRESS}::launchpad::mint_nft`, + typeArguments: [], + functionArguments: [collectionId, amount], + }, + }; +}; diff --git a/templates/digital-asset-template/frontend/pages/Mint/hooks/useMintData.ts b/templates/digital-asset-template/frontend/hooks/useGetCollectionData.ts similarity index 97% rename from templates/digital-asset-template/frontend/pages/Mint/hooks/useMintData.ts rename to templates/digital-asset-template/frontend/hooks/useGetCollectionData.ts index c5e0b551..2cb852d7 100644 --- a/templates/digital-asset-template/frontend/pages/Mint/hooks/useMintData.ts +++ b/templates/digital-asset-template/frontend/hooks/useGetCollectionData.ts @@ -1,8 +1,9 @@ +import { AccountAddress } from "@aptos-labs/ts-sdk"; +import { useQuery } from "@tanstack/react-query"; + import { config } from "@/config"; import { MODULE_ADDRESS } from "@/constants"; import { aptosClient } from "@/utils/aptosClient"; -import { AccountAddress } from "@aptos-labs/ts-sdk"; -import { useQuery } from "@tanstack/react-query"; export interface Token { token_name: string; @@ -78,7 +79,7 @@ async function getStartAndEndTime(collection_id: string): Promise<[start: Date, ]; } -export function useMintData(collection_id: string = config.collection_id) { +export function useGetCollectionData(collection_id: string = config.collection_id) { return useQuery({ queryKey: ["app-state", collection_id], refetchInterval: 1000 * 30, diff --git a/templates/digital-asset-template/frontend/hooks/useGetCollections.tsx b/templates/digital-asset-template/frontend/hooks/useGetCollections.tsx index e568e8d1..4ec98e43 100644 --- a/templates/digital-asset-template/frontend/hooks/useGetCollections.tsx +++ b/templates/digital-asset-template/frontend/hooks/useGetCollections.tsx @@ -1,7 +1,8 @@ -import { aptosClient } from "@/utils/aptosClient"; import { AccountAddress, GetCollectionDataResponse } from "@aptos-labs/ts-sdk"; import { useState, useEffect } from "react"; +import { aptosClient } from "@/utils/aptosClient"; + /** * A react hook to get all collections under the current contract. * @@ -10,9 +11,7 @@ import { useState, useEffect } from "react"; * */ export function useGetCollections() { - const [collections, setCollections] = useState< - Array - >([]); + const [collections, setCollections] = useState>([]); useEffect(() => { async function run() { @@ -34,9 +33,7 @@ export function useGetCollections() { const getRegistry = async () => { const registry = await aptosClient().view<[[{ inner: string }]]>({ payload: { - function: `${AccountAddress.from( - import.meta.env.VITE_MODULE_ADDRESS - )}::launchpad::get_registry`, + function: `${AccountAddress.from(import.meta.env.VITE_MODULE_ADDRESS)}::launchpad::get_registry`, }, }); return registry[0]; @@ -51,7 +48,7 @@ const getObjects = async (registry: [{ inner: string }]) => { }); return object.owner_address; - }) + }), ); return objects; }; @@ -66,7 +63,7 @@ const getCollections = async (objects: Array) => { }); return collection; - }) + }), ); return collections; }; diff --git a/templates/digital-asset-template/frontend/main.tsx b/templates/digital-asset-template/frontend/main.tsx index c5e95cb0..a3ba13ab 100644 --- a/templates/digital-asset-template/frontend/main.tsx +++ b/templates/digital-asset-template/frontend/main.tsx @@ -4,10 +4,10 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import React from "react"; import ReactDOM from "react-dom/client"; -import App from "./App"; -import { WalletProvider } from "./components/WalletProvider"; -import { Toaster } from "./components/ui/toaster"; -import { TooltipProvider } from "./components/ui/tooltip"; +import App from "@/App"; +import { WalletProvider } from "@/components/WalletProvider"; +import { Toaster } from "@/components/ui/toaster"; +import { TooltipProvider } from "@/components/ui/tooltip"; const queryClient = new QueryClient(); @@ -21,5 +21,5 @@ ReactDOM.createRoot(document.getElementById("root")!).render( - + , ); diff --git a/templates/digital-asset-template/frontend/pages/CreateCollection.tsx b/templates/digital-asset-template/frontend/pages/CreateCollection.tsx index 1a95644b..4197e749 100644 --- a/templates/digital-asset-template/frontend/pages/CreateCollection.tsx +++ b/templates/digital-asset-template/frontend/pages/CreateCollection.tsx @@ -1,46 +1,52 @@ -import { Button, buttonVariants } from "@/components/ui/button"; -import { Card, CardContent, CardDescription, CardHeader } from "@/components/ui/card"; -import { Input } from "@/components/ui/input"; -import { Label } from "@/components/ui/label"; +// External packages import { useRef, useState } from "react"; import { useWallet } from "@aptos-labs/wallet-adapter-react"; +import { Link, useNavigate } from "react-router-dom"; +// Internal utils import { aptosClient } from "@/utils/aptosClient"; import { uploadCollectionData } from "@/utils/assetsUploader"; -import { APT_DECIMALS, convertAmountFromHumanReadableToOnChain } from "@/utils/helpers"; -import { Link, useNavigate } from "react-router-dom"; - -import { dateToSeconds } from "../utils/helpers"; +// Internal components +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Button, buttonVariants } from "@/components/ui/button"; +import { Card, CardContent, CardDescription, CardHeader } from "@/components/ui/card"; import { LaunchpadHeader } from "@/components/LaunchpadHeader"; import { CREATOR_ADDRESS } from "@/constants"; import { WarningAlert } from "@/components/ui/warning-alert"; import { UploadSpinner } from "@/components/UploadSpinner"; -import { LabeledInput } from "../components/ui/labeled-input"; +import { LabeledInput } from "@/components/ui/labeled-input"; import { DateTimeInput } from "@/components/ui/date-time-input"; import { ConfirmButton } from "@/components/ui/confirm-button"; +// Entry functions +import { createCollection } from "@/entry-functions/create_collection"; export function CreateCollection() { - // Wallet connect providers + // Wallet Adapter provider const aptosWallet = useWallet(); const { account, signAndSubmitTransaction } = useWallet(); - // If we are on Production mode, redierct to the mint page + // If we are on Production mode, redierct to the public mint page const navigate = useNavigate(); if (import.meta.env.PROD) navigate("/", { replace: true }); // Collection data entered by the user on UI - const [royaltyPercentage, setRoyaltyPercentage] = useState(); - const [preMintAmount, setPreMintAmount] = useState(); + const [royaltyPercentage, setRoyaltyPercentage] = useState(); + const [preMintAmount, setPreMintAmount] = useState(); const [publicMintStartDate, setPublicMintStartDate] = useState(); const [publicMintStartTime, setPublicMintStartTime] = useState(); const [publicMintEndDate, setPublicMintEndDate] = useState(); const [publicMintEndTime, setPublicMintEndTime] = useState(); - const [mintLimitPerAccount, setMintLimitPerAccount] = useState(); - const [mintFeePerNFT, setMintFeePerNFT] = useState(); + const [publicMintLimitPerAccount, setPublicMintLimitPerAccount] = useState(1); + const [publicMintFeePerNFT, setPublicMintFeePerNFT] = useState(); const [files, setFiles] = useState(null); + + // Internal state const [isUploading, setIsUploading] = useState(false); + // Local Ref const inputRef = useRef(null); + // On publish mint start date selected const onPublicMintStartTime = (event: React.ChangeEvent) => { const timeValue = event.target.value; setPublicMintStartTime(timeValue); @@ -53,6 +59,7 @@ export function CreateCollection() { setPublicMintStartDate(publicMintStartDate); }; + // On publish mint end date selected const onPublicMintEndTime = (event: React.ChangeEvent) => { const timeValue = event.target.value; setPublicMintEndTime(timeValue); @@ -65,47 +72,50 @@ export function CreateCollection() { setPublicMintEndDate(publicMintEndDate); }; - const createCollection = async () => { + // On create collection button clicked + const onCreateCollection = async () => { try { if (!account) throw new Error("Please connect your wallet"); if (!files) throw new Error("Please upload files"); if (account.address !== CREATOR_ADDRESS) throw new Error("Wrong account"); if (isUploading) throw new Error("Uploading in progress"); + // Set internal isUploading state setIsUploading(true); + // Upload collection files to Irys const { collectionName, collectionDescription, maxSupply, projectUri } = await uploadCollectionData( aptosWallet, files, ); - const response = await signAndSubmitTransaction({ - data: { - function: `${import.meta.env.VITE_MODULE_ADDRESS}::launchpad::create_collection`, - typeArguments: [], - functionArguments: [ - collectionDescription, - collectionName, - projectUri, - maxSupply, - royaltyPercentage, - preMintAmount, // amount of NFT to pre-mint for myself - undefined, // addresses in the allow list - undefined, // allow list start time (in seconds) - undefined, // allow list end time (in seconds) - undefined, // mint limit per address in the allow list - undefined, // mint fee per NFT for the allow list - dateToSeconds(publicMintStartDate), // public mint start time (in seconds) - dateToSeconds(publicMintEndDate), // public mint end time (in seconds) - mintLimitPerAccount, // mint limit per address in the public mint - mintFeePerNFT ? convertAmountFromHumanReadableToOnChain(mintFeePerNFT, APT_DECIMALS) : 0, // mint fee per NFT for the public mint, on chain stored in smallest unit of APT (i.e. 1e8 oAPT = 1 APT) - ], - }, - }); + // Submit a create_collection entry function transaction + const response = await signAndSubmitTransaction( + createCollection({ + collectionDescription, + collectionName, + projectUri, + maxSupply, + royaltyPercentage, + preMintAmount, + allowList: undefined, + allowListStartDate: undefined, + allowListEndDate: undefined, + allowListLimitPerAccount: undefined, + allowListFeePerNFT: undefined, + publicMintStartDate, + publicMintEndDate, + publicMintLimitPerAccount, + publicMintFeePerNFT, + }), + ); + // Wait for the transaction to be commited to chain const committedTransactionResponse = await aptosClient().waitForTransaction({ transactionHash: response.hash, }); + + // Once the transaction has been successfully commited to chain, navigate to the `my-collection` page if (committedTransactionResponse.success) { navigate(`/my-collections`, { replace: true }); } @@ -218,7 +228,7 @@ export function CreateCollection() { tooltip="How many NFTs an individual address is allowed to mint" disabled={isUploading || !account} onChange={(e) => { - setMintLimitPerAccount(parseInt(e.target.value)); + setPublicMintLimitPerAccount(parseInt(e.target.value)); }} /> @@ -228,7 +238,7 @@ export function CreateCollection() { tooltip="The percentage of trading value that collection creator gets when an NFT is sold on marketplaces" disabled={isUploading || !account} onChange={(e) => { - setRoyaltyPercentage(e.target.value); + setRoyaltyPercentage(parseInt(e.target.value)); }} /> @@ -238,7 +248,7 @@ export function CreateCollection() { tooltip="The fee the nft minter is paying the collection creator when they mint an NFT, denominated in APT" disabled={isUploading || !account} onChange={(e) => { - setMintFeePerNFT(Number(e.target.value)); + setPublicMintFeePerNFT(Number(e.target.value)); }} /> @@ -248,16 +258,21 @@ export function CreateCollection() { tooltip="How many NFTs to mint immediately for the creator" disabled={isUploading || !account} onChange={(e) => { - setPreMintAmount(e.target.value); + setPreMintAmount(parseInt(e.target.value)); }} /> diff --git a/templates/digital-asset-template/frontend/pages/Mint/components/BannerSection.tsx b/templates/digital-asset-template/frontend/pages/Mint/components/BannerSection.tsx index 3098cc37..4c3ac682 100644 --- a/templates/digital-asset-template/frontend/pages/Mint/components/BannerSection.tsx +++ b/templates/digital-asset-template/frontend/pages/Mint/components/BannerSection.tsx @@ -1,6 +1,9 @@ +import { useMemo } from "react"; +// Internal components import { Image } from "@/components/ui/image"; +// Internal utils import { cn } from "@/lib/utils"; -import { useMemo } from "react"; +// Internal config import { config } from "@/config"; interface BannerSectionProps { @@ -21,20 +24,9 @@ export const BannerSection: React.FC = ({ className }) => { if (!repeatedImages.length) return null; return ( -
+
{repeatedImages.slice(0, 60).map((image, i) => { - return ( - - ); + return ; })}
); diff --git a/templates/digital-asset-template/frontend/pages/Mint/components/ConnectWalletAlert.tsx b/templates/digital-asset-template/frontend/pages/Mint/components/ConnectWalletAlert.tsx index a2a01812..bc972722 100644 --- a/templates/digital-asset-template/frontend/pages/Mint/components/ConnectWalletAlert.tsx +++ b/templates/digital-asset-template/frontend/pages/Mint/components/ConnectWalletAlert.tsx @@ -1,38 +1,33 @@ -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; -import { config } from "@/config"; -import { AlertOctagon } from "lucide-react"; import { FC } from "react"; +// Internal components +import { WarningAlert } from "@/components/ui/warning-alert"; +// Internal config +import { config } from "@/config"; export const ConnectWalletAlert: FC = () => { if (config.collection_id) return null; return ( -
- - - - Collection ID not set - - - This page is placeholder content, to render your collection: -
    -
  1. - Make sure you have created a collection, click the "My - Collections" button and verify a collection is created. -
  2. -
  3. - Fill in the{" "} - - collection_id - {" "} - field in - - frontend/config.ts - -
  4. -
-
-
+
+ + This page is placeholder content, to render your collection: +
    +
  1. + Make sure you have created a collection, click the "My Collections" button and verify a collection is + created. +
  2. +
  3. + Fill in the{" "} + + collection_id + {" "} + field in + + frontend/config.ts + +
  4. +
+
); }; diff --git a/templates/digital-asset-template/frontend/pages/Mint/components/FAQSection.tsx b/templates/digital-asset-template/frontend/pages/Mint/components/FAQSection.tsx index d43d7a76..ae8d9f90 100644 --- a/templates/digital-asset-template/frontend/pages/Mint/components/FAQSection.tsx +++ b/templates/digital-asset-template/frontend/pages/Mint/components/FAQSection.tsx @@ -1,10 +1,7 @@ +// Internal config import { config } from "@/config"; -import { - Accordion, - AccordionContent, - AccordionItem, - AccordionTrigger, -} from "@/components/ui/accordion"; +// Internal components +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion"; interface FAQSectionProps {} diff --git a/templates/digital-asset-template/frontend/pages/Mint/components/HeroSection.tsx b/templates/digital-asset-template/frontend/pages/Mint/components/HeroSection.tsx index 65f9eb2a..87ed1625 100644 --- a/templates/digital-asset-template/frontend/pages/Mint/components/HeroSection.tsx +++ b/templates/digital-asset-template/frontend/pages/Mint/components/HeroSection.tsx @@ -1,30 +1,35 @@ import { FC, FormEvent, useState } from "react"; +import { useWallet } from "@aptos-labs/wallet-adapter-react"; +import { useQueryClient } from "@tanstack/react-query"; +// Internal assets +import Copy from "@/assets/icons/copy.svg"; +import ExternalLink from "@/assets/icons/external-link.svg"; +import Placeholder1 from "@/assets/placeholders/bear-1.png"; +// Internal utils import { truncateAddress } from "@/utils/truncateAddress"; +import { clampNumber } from "@/utils/clampNumber"; +import { formatDate } from "@/utils/formatDate"; +import { aptosClient } from "@/utils/aptosClient"; +// Internal hooks +import { useGetCollectionData } from "@/hooks/useGetCollectionData"; +// Internal components import { Image } from "@/components/ui/image"; import { Card, CardContent } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Button, buttonVariants } from "@/components/ui/button"; -import { clampNumber } from "@/utils/clampNumber"; -import { useMintData } from "../hooks/useMintData"; -import Copy from "@/assets/icons/copy.svg"; -import ExternalLink from "@/assets/icons/external-link.svg"; -import { Socials } from "./Socials"; -import { MODULE_ADDRESS, NETWORK } from "@/constants"; -import { - InputTransactionData, - useWallet, -} from "@aptos-labs/wallet-adapter-react"; -import { aptosClient } from "@/utils/aptosClient"; -import { useQueryClient } from "@tanstack/react-query"; -import Placeholder1 from "@/assets/placeholders/bear-1.png"; -import { config } from "@/config"; -import { formatDate } from "@/utils/formatDate"; import { Progress } from "@/components/ui/progress"; +import { Socials } from "@/pages/Mint/components/Socials"; +// Internal constants +import { NETWORK } from "@/constants"; +// Internal config +import { config } from "@/config"; +// Internal enrty functions +import { mintNFT } from "@/entry-functions/mint_nft"; interface HeroSectionProps {} export const HeroSection: React.FC = () => { - const { data } = useMintData(); + const { data } = useGetCollectionData(); const queryClient = useQueryClient(); const { account, signAndSubmitTransaction } = useWallet(); const [nftCount, setNftCount] = useState(1); @@ -34,14 +39,11 @@ export const HeroSection: React.FC = () => { const mintNft = async (e: FormEvent) => { e.preventDefault(); if (!account || !data?.isMintActive) return; + if (!collection?.collection_id) return; - const transaction: InputTransactionData = { - data: { - function: `${MODULE_ADDRESS}::launchpad::mint_nft`, - functionArguments: [collection?.collection_id, nftCount], - }, - }; - const response = await signAndSubmitTransaction(transaction); + const response = await signAndSubmitTransaction( + mintNFT({ collectionId: collection.collection_id, amount: nftCount }), + ); await aptosClient().waitForTransaction({ transactionHash: response.hash }); queryClient.invalidateQueries(); setNftCount(1); @@ -50,42 +52,28 @@ export const HeroSection: React.FC = () => { return (
-

- {collection?.collection_name ?? config.defaultCollection?.name} -

+

{collection?.collection_name ?? config.defaultCollection?.name}

-

- {collection?.description ?? config.defaultCollection?.description} -

+

{collection?.description ?? config.defaultCollection?.description}

-
+ className="flex flex-col md:flex-row gap-4 md:justify-between items-start md:items-center flex-wrap" + > + - setNftCount(parseInt(e.currentTarget.value, 10)) - } + onChange={(e) => setNftCount(parseInt(e.currentTarget.value, 10))} /> -
@@ -94,25 +82,21 @@ export const HeroSection: React.FC = () => {

{clampNumber(totalMinted)} / {clampNumber(maxSupply)} Minted

- +
-

- Collection Address -

+

Collection Address

@@ -126,18 +110,14 @@ export const HeroSection: React.FC = () => {
)} - {data?.endDate && - new Date() < data.endDate && - !data.isMintInfinite && ( -
-

Minting ends

-

{formatDate(data.endDate)}

-
- )} - - {data?.endDate && new Date() > data.endDate && ( -

Minting has ended

+ {data?.endDate && new Date() < data.endDate && !data.isMintInfinite && ( +
+

Minting ends

+

{formatDate(data.endDate)}

+
)} + + {data?.endDate && new Date() > data.endDate &&

Minting has ended

}
@@ -155,10 +135,7 @@ const AddressButton: FC<{ address: string }> = ({ address }) => { } return ( -