Skip to content

feat: studio flow with mass minting#831

Merged
Jarsen136 merged 5 commits intomainfrom
feat/studio-flow-main
Mar 6, 2026
Merged

feat: studio flow with mass minting#831
Jarsen136 merged 5 commits intomainfrom
feat/studio-flow-main

Conversation

@Jarsen136
Copy link
Contributor

@Jarsen136 Jarsen136 commented Mar 4, 2026

close chaotic-art/planning#70 (comment)
part of chaotic-art/planning#19

ref: #791

included:
#830
#832
#834

image

Summary by CodeRabbit

  • New Features

    • Studio collection interface: header, sidebar, layout and guarded studio pages
    • Studio-aware Mass Mint page and mass-mint flow with studio context support
  • UI/UX Improvements

    • Collection card actions updated to show View and Manage side-by-side
    • Mass Mint stepper and action bars adapt to studio vs non-studio flows
    • Breadcrumbs and navigation refined for studio pages

* feat: studio mode collection card

* feat: studio page major layout

* chore: item amount
@railway-app
Copy link

railway-app bot commented Mar 4, 2026

This PR was not deployed automatically as @Jarsen136 does not have access to the Railway project.

In order to get automatic PR deploys, please add @Jarsen136 to your workspace on Railway.

@vercel
Copy link

vercel bot commented Mar 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
koda Ready Ready Preview, Comment Mar 6, 2026 2:49pm

@coderabbitai
Copy link

coderabbitai bot commented Mar 4, 2026

📝 Walkthrough

Walkthrough

Adds a Minting Studio feature: new studio layout, header, sidebar, and studio-scoped pages; updates mass-mint flow to support studio context (props, options, dynamic steps); changes card action variant from view-only to studio-mode and updates CollectionCard UI to show View + Manage buttons.

Changes

Cohort / File(s) Summary
Card / Grid
app/components/common/card/CollectionCard.client.vue, app/components/explore/CollectionsGrid.vue, app/pages/[chain]/studio/index.vue
Changed action variant type from 'view-only' to 'studio-mode'; CollectionCard bottom actions reworked to a horizontal flex containing side-by-side View and Manage buttons; updated prop usage in CollectionsGrid and page.
Mass Mint (core)
app/components/massmint/MassMint.vue, app/composables/massmint/useMassMintForm.ts, app/components/massmint/MassMintUploadStep.vue
MassMint gained collectionId and blockchain props and studio-aware computed steps/stepCount; useMassMintForm accepts options (collectionId, blockchain), exposes isStudioContext and syncs studio defaults; upload step action bar simplified (Next button right-aligned).
Studio Layout & Pages
app/layouts/studio-collection.vue, app/pages/[chain]/studio/index.vue, app/pages/[chain]/studio/[collection_id]/index.vue, app/pages/[chain]/studio/[collection_id]/[tab].vue, app/pages/[chain]/studio/[collection_id]/massmint.vue
Added a studio-collection layout that computes collection metadata, tab routing, and a destroy modal; new guarded studio routes and massmint page that pass collection and chain context to MassMint.
Studio UI Components
app/components/studio/StudioHeader.vue, app/components/studio/StudioSidebar.vue
New StudioHeader (breadcrumb/back/close) and StudioSidebar (collection identity, nav items, mass mint link, view/delete actions) components; sidebar exposes props and emits selectTab and deleteCollection.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Page as Studio Page
  participant Layout as Studio Layout
  participant Sidebar as Studio Sidebar
  participant MassMint
  participant Hook as useMassMintForm
  participant API as Server/API

  User->>Page: navigate to /[chain]/studio/[collection_id]/massmint
  Page->>Layout: render with collection context
  Layout->>Sidebar: provide collection props & nav callbacks
  Layout->>MassMint: render with collectionId & blockchain props
  MassMint->>Hook: initialize(useMassMintForm(options)) => isStudioContext
  MassMint->>Hook: fetch collections / setup steps
  Hook->>API: request user collections (blockchain-aware)
  API-->>Hook: return collections
  Hook-->>MassMint: provide state & isStudioContext
  User->>MassMint: interact with stepper (next/goToStep)
  MassMint->>Hook: validate/submit data
  Hook->>API: submit mint payload
  API-->>Hook: confirm
  Hook-->>MassMint: result
  MassMint-->>User: show success/failure
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐇 I hopped into the studio with a tray of mint and dreams,
Buttons side-by-side, and sidebars full of schemes,
Headers guide the path, tabs hum a tidy tune,
Collections bloom by chain beneath a silvery moon,
Hop, click, mint — creators dance in bright routines.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately captures the main feature: introducing a studio flow with mass minting capabilities across multiple components and pages.
Linked Issues check ✅ Passed The changeset implements studio flow infrastructure with mass minting integration, aligning with the Minting Studio issue objectives.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing the studio flow with mass minting: new studio components, pages, layout, type updates, and composable enhancements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/studio-flow-main

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Jarsen136 Jarsen136 changed the title feat: studio flow with mass minting WIP: studio flow with mass minting Mar 4, 2026
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Mar 4, 2026

Deploying app with  Cloudflare Pages  Cloudflare Pages

Latest commit: d3bbb3e
Status: ✅  Deploy successful!
Preview URL: https://d87c3997.app-bzd.pages.dev
Branch Preview URL: https://feat-studio-flow-main.app-bzd.pages.dev

View logs

* feat: delete collection on studio page

* feat: studio sidebar adjustment
* feat: delete collection on studio page

* feat: studio sidebar adjustment

* feat: intergrate massmint into studio
@Jarsen136 Jarsen136 marked this pull request as ready for review March 5, 2026 16:12
@Jarsen136 Jarsen136 changed the title WIP: studio flow with mass minting feat: studio flow with mass minting Mar 5, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (3)
app/composables/massmint/useMassMintForm.ts (1)

5-8: Use SupportedChain for the new options chain type.

Line 7 currently uses AssetHubChain; this should follow the repository’s standard chain identifier type.

♻️ Proposed fix
-import type { AssetHubChain } from '~/plugins/sdk.client'
+import type { SupportedChain } from '~/plugins/sdk.client'
@@
 export interface UseMassMintFormOptions {
   collectionId?: string
-  blockchain?: AssetHubChain
+  blockchain?: SupportedChain
 }
@@
   const state = reactive({
     collection: '',
-    blockchain: 'ahp' as AssetHubChain, // Default to Asset Hub Polkadot
+    blockchain: 'ahp' as SupportedChain, // Default to Asset Hub Polkadot
   })

As per coding guidelines **/*.{ts,tsx}: Use SupportedChain type from ~/plugins/sdk.client for chain identifiers.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/composables/massmint/useMassMintForm.ts` around lines 5 - 8, Update the
UseMassMintFormOptions type to use the repository-standard chain identifier:
replace the blockchain property type AssetHubChain with SupportedChain in the
UseMassMintFormOptions interface (symbol: UseMassMintFormOptions, property:
blockchain). Add the appropriate import for SupportedChain from the sdk client
module (symbol: SupportedChain from ~/plugins/sdk.client) and remove or replace
any now-unused AssetHubChain import/usages so the interface and any consumers
use SupportedChain consistently.
app/pages/[chain]/studio/[collection_id]/[tab].vue (1)

4-4: Consider centralizing validTabs into a shared constant.

validTabs is duplicated here and in app/layouts/studio-collection.vue (Line 13 there). A shared source avoids accidental route/UI drift.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/pages/`[chain]/studio/[collection_id]/[tab].vue at line 4, Move the
duplicated const validTabs into a single exported constant in a shared module
(e.g., export const STUDIO_VALID_TABS = ['preview','details','items'] as const)
and replace the local declarations with imports of that constant; update any
type usages (e.g., typeof validTabs[number]) to reference the shared symbol and
adjust imports in both the page component and the studio layout so they use the
same source to prevent drift.
app/layouts/studio-collection.vue (1)

48-53: Sidebar tab navigation is currently non-functional due to empty navItems.

With no active entries, select-tab cannot be used from the sidebar even though tab routes exist. If this is intentionally deferred, I can help add a follow-up issue or wire the three tab items now.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/layouts/studio-collection.vue` around lines 48 - 53, The sidebar is empty
because the navItems array (declared as const navItems: StudioNavItem[]) has no
entries, so the sidebar can't call select-tab; populate navItems with the three
tab objects (ids 'preview', 'details', 'items' — using the same literal ids your
tab routes expect), include user-facing labels ('Preview', 'Details', 'Items')
and the icon strings (e.g., 'i-heroicons:eye', 'i-heroicons-cog-6-tooth',
'i-heroicons-squares-2x2'), and preserve the literal types (use the same 'as
const' pattern used in the commented examples) so the StudioNavItem type and any
select-tab calls resolve correctly; ensure the navItems variable (navItems) is
then used by the sidebar component so select-tab can activate the corresponding
routes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/components/massmint/MassMint.vue`:
- Around line 148-155: The computed stepperMaxStepReached uses canNavigateTo
with hardcoded step indices that assume the non-studio step layout, causing
incorrect gating in studio mode; update the logic to translate the UI step index
into the correct logical step id before calling canNavigateTo (or call a variant
of canNavigateTo that accepts a stepper index and accounts for isStudioMode),
ensure you reference stepperMaxStepReached, canNavigateTo, stepCount and
isStudioMode, and apply the same mapping/fix to the other step-navigation checks
in the same block (the similar logic around the later step checks).

In `@app/components/studio/StudioSidebar.vue`:
- Around line 38-47: The image `@error` handler hides the <img> element but leaves
collectionImage truthy so the UIcon fallback never renders; update the error
handler to mark the component state so the v-else can take over — e.g., set a
reactive flag or clear collectionImage inside the handler (reference the
collectionImage reactive/property and the sanitizeIpfsUrl usage) so that when
the image fails you flip that flag (or set collectionImage = null) and allow the
UIcon fallback to render instead of merely hiding the <img>.

In `@app/layouts/studio-collection.vue`:
- Line 2: The import alias usage in studio-collection.vue is inconsistent with
repo rules: replace any imports using '@/...' with the '~/...' alias (e.g.,
change the import type declaration for StudioNavItem from
'@/components/studio/StudioSidebar.vue' and the other import at line 38 to use
'~/components/studio/StudioSidebar.vue'); update all occurrences in this file so
Vue imports follow the `~/` convention to satisfy the codebase import rule.

In `@app/pages/`[chain]/studio/[collection_id]/index.vue:
- Around line 6-9: The route guard's validate function only checks `chain` and
should also validate `collection_id`; update the `validate: async (route) => {
... }` block to extract `collection_id` from `route.params` and return false
unless `collection_id` is a valid string (e.g. typeof collection_id === 'string'
&& collection_id.trim().length > 0) or matches your project's expected
pattern/validator. Keep the existing `isAssetHubChain(chain)` check and combine
it with the new `collection_id` validation (logical AND) so invalid collection
IDs are rejected before entering downstream logic.

---

Nitpick comments:
In `@app/composables/massmint/useMassMintForm.ts`:
- Around line 5-8: Update the UseMassMintFormOptions type to use the
repository-standard chain identifier: replace the blockchain property type
AssetHubChain with SupportedChain in the UseMassMintFormOptions interface
(symbol: UseMassMintFormOptions, property: blockchain). Add the appropriate
import for SupportedChain from the sdk client module (symbol: SupportedChain
from ~/plugins/sdk.client) and remove or replace any now-unused AssetHubChain
import/usages so the interface and any consumers use SupportedChain
consistently.

In `@app/layouts/studio-collection.vue`:
- Around line 48-53: The sidebar is empty because the navItems array (declared
as const navItems: StudioNavItem[]) has no entries, so the sidebar can't call
select-tab; populate navItems with the three tab objects (ids 'preview',
'details', 'items' — using the same literal ids your tab routes expect), include
user-facing labels ('Preview', 'Details', 'Items') and the icon strings (e.g.,
'i-heroicons:eye', 'i-heroicons-cog-6-tooth', 'i-heroicons-squares-2x2'), and
preserve the literal types (use the same 'as const' pattern used in the
commented examples) so the StudioNavItem type and any select-tab calls resolve
correctly; ensure the navItems variable (navItems) is then used by the sidebar
component so select-tab can activate the corresponding routes.

In `@app/pages/`[chain]/studio/[collection_id]/[tab].vue:
- Line 4: Move the duplicated const validTabs into a single exported constant in
a shared module (e.g., export const STUDIO_VALID_TABS =
['preview','details','items'] as const) and replace the local declarations with
imports of that constant; update any type usages (e.g., typeof
validTabs[number]) to reference the shared symbol and adjust imports in both the
page component and the studio layout so they use the same source to prevent
drift.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f2bbb72e-10df-4139-85c3-f3a5e96ebc4d

📥 Commits

Reviewing files that changed from the base of the PR and between bb08917 and 67cd78f.

📒 Files selected for processing (12)
  • app/components/common/card/CollectionCard.client.vue
  • app/components/explore/CollectionsGrid.vue
  • app/components/massmint/MassMint.vue
  • app/components/massmint/MassMintUploadStep.vue
  • app/components/studio/StudioHeader.vue
  • app/components/studio/StudioSidebar.vue
  • app/composables/massmint/useMassMintForm.ts
  • app/layouts/studio-collection.vue
  • app/pages/[chain]/studio/[collection_id]/[tab].vue
  • app/pages/[chain]/studio/[collection_id]/index.vue
  • app/pages/[chain]/studio/[collection_id]/massmint.vue
  • app/pages/[chain]/studio/index.vue

@Jarsen136 Jarsen136 merged commit f84c6b3 into main Mar 6, 2026
4 of 5 checks passed
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
app/components/massmint/MassMint.vue (1)

96-128: Derive the flow from one config source.

steps and stepConfig now describe the same studio/non-studio flow in parallel, but only stepConfig drives the stepper while steps is only used for stepCount. That duplication is easy to desync on the next step change. Consider keeping a single flow definition and deriving both the UI config and stepCount from it.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/components/massmint/MassMint.vue` around lines 96 - 128, Unify the step
definitions so they come from one computed source instead of duplicating in
steps and stepConfig: create a single computed (e.g., flowDefinition or
baseSteps) that builds the array of step descriptors based on
isStudioContext.value (each entry should include a unique id/title/description
and a label/icon key), then derive steps by mapping that flowDefinition to the
shape currently expected by steps (id/title/description) and derive stepConfig
by mapping the same flowDefinition to StepConfig (label/icon); ensure any uses
of stepCount or stepper read flowDefinition.length so you only maintain one
source of truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/components/studio/StudioSidebar.vue`:
- Around line 14-15: The component uses currentTab to mark active items by
comparing currentTab === item.id, but elsewhere
(app/layouts/studio-collection.vue) currentTab is being set to display labels
like "Preview"/"Details"/"Items", causing mismatches; update the code so
currentTab holds the tab id (route segment) instead of the label (e.g.,
"preview", "details", "items") or change the comparison to use item.label
consistently—specifically adjust where currentTab is computed in
app/layouts/studio-collection.vue to pass the nav item id, and ensure
StudioSidebar.vue (and any checks around lines ~77-81) compares currentTab
against StudioNavItem.id (not label) so active state toggles correctly.

In `@app/pages/`[chain]/studio/[collection_id]/index.vue:
- Around line 1-15: The validate function in massmint.vue must mirror index.vue:
update the validate async (route) => { const { chain, collection_id:
collectionId } = route.params } logic to require typeof chain === 'string' &&
isAssetHubChain(chain) && typeof collectionId === 'string' &&
/^\d+$/.test(collectionId); i.e., add the /^\d+$/.test(collectionId) numeric
check to the existing validate function so routing consistently rejects
non-numeric collection_id values; keep the same isAssetHubChain call and param
destructuring as in index.vue.

---

Nitpick comments:
In `@app/components/massmint/MassMint.vue`:
- Around line 96-128: Unify the step definitions so they come from one computed
source instead of duplicating in steps and stepConfig: create a single computed
(e.g., flowDefinition or baseSteps) that builds the array of step descriptors
based on isStudioContext.value (each entry should include a unique
id/title/description and a label/icon key), then derive steps by mapping that
flowDefinition to the shape currently expected by steps (id/title/description)
and derive stepConfig by mapping the same flowDefinition to StepConfig
(label/icon); ensure any uses of stepCount or stepper read flowDefinition.length
so you only maintain one source of truth.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 83321bce-f3d5-4e2a-876e-b427d06da696

📥 Commits

Reviewing files that changed from the base of the PR and between 67cd78f and d3bbb3e.

📒 Files selected for processing (3)
  • app/components/massmint/MassMint.vue
  • app/components/studio/StudioSidebar.vue
  • app/pages/[chain]/studio/[collection_id]/index.vue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Minting Studio

1 participant