HAX
← Back

Steps for Creating a 3D NFT Marketplace on Stacks #06 - Add Minting UI

2025-04-14Fabo Hax

test-it.png

In this tutorial, we’ll walk through how to integrate a functional minting interface into the 4V4 avatar marketplace. This is the form users will interact with to submit metadata and upload their custom .glb 3D avatar models — before any blockchain interaction happens.


🧱 UI Structure

The minting UI lives inside src/app/profile/page.tsx, and includes:

  • A 3D preview of the avatar
  • A form to input avatar metadata
  • File upload for .glb model + image
  • Form state management using React hooks
  • A submit button (non-functional for now)

🎨 Components Used

The interface is built with:

  • Chakra UI (Box, Input, Textarea, VStack, Label, Button)
  • Custom 3D preview via CenterPanel
  • useState for form handling
  • getModelFromDB to load the 3D model from IndexedDB

✍️ What Users Can Do in This Step

  • Upload a .glb avatar file
  • Preview the model in real-time
  • Fill out metadata such as:
    • Name & description
    • Edition & royalties
    • Attributes & properties (JSON or comma-separated)
    • Optional soulbound checkbox
  • Submit the form to trigger client-side logic (no blockchain minting yet)

🧩 Project Context

This code lives in src/app/profile/page.tsx and is part of the profile dashboard where users can mint and view their avatars.


🪄 Step-by-Step Breakdown

1. Model Viewer Integration

At the top of the UI, the uploaded .glb avatar model is displayed using the CenterPanel component.

<CenterPanel
  background={background}
  secondaryColor={secondaryColor}
  modelUrl={modelUrl}
  lightIntensity={lightIntensity}
/>

-This gives the user a real-time preview of the model before minting it.


2. Model and Metadata Upload

The user fills out form fields such as name, description, edition, and royalties, and uploads both a .glb file and an optional image.

<formData.append('file', modelFile);
formData.append('description', description);
formData.append('attributes', JSON.stringify([...]));

All data is packaged into a FormData object and sent to /api/files, which returns a tokenURI that points to the hosted metadata.


🔩 Next Step

In Step #08, we’ll integrate this interface with the Stacks smart contract logic, handle IPFS uploads, and execute the Clarity mint-public function via Hiro Wallet.

➡️ Stay tuned!


Sign Up to Stay Sync:

menu