Skip to content

Dashboard: Migrate Claim condition components from chakra to tailwind, UI improvements #7731

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

MananTank
Copy link
Member

@MananTank MananTank commented Jul 27, 2025


PR-Codex overview

This PR primarily focuses on refining the user interface and functionality of the claim conditions forms in the dashboard, enhancing the user experience with improved styles, new components, and better data handling.

Detailed summary

  • Deleted unused CSV files.
  • Updated variant prop in tx-button to include "outline".
  • Enhanced styling in the drop-zone component.
  • Improved text styles in price-preview and claim-conditions components.
  • Replaced CustomFormControl with FormFieldSetup for better form handling.
  • Added new SnapshotDataTable component for displaying CSV data.
  • Introduced downloadable code snippets for CSV examples.
  • Updated ClaimConditionsForm to utilize new UI components and streamline form submission.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Added support for an "outline" button style variant in transaction buttons.
  • Refactor

    • Replaced Chakra UI components with a custom UI library and Tailwind CSS across claim conditions forms and related components.
    • Simplified and reorganized the layout of claim conditions phases, downloadable code blocks, and snapshot upload views for improved clarity and usability.
    • Updated CSV upload and data table experience with enhanced error display and a new code example download feature.
    • Refined input components with improved styling and replaced legacy wrappers with streamlined form field components.
    • Removed admin-only wrappers and simplified access control in relevant components.
  • Style

    • Improved spacing, typography, and overall visual consistency throughout claim conditions and related dashboard components.
    • Enhanced button and input styling for better usability and appearance.
  • Chores

    • Removed unused or redundant components and files related to previous form controls and CSV tables.

@vercel vercel bot temporarily deployed to Preview – docs-v2 July 27, 2025 22:55 Inactive
Copy link

vercel bot commented Jul 27, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
thirdweb-www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 28, 2025 0:15am
4 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Skipped (Inspect) Jul 28, 2025 0:15am
nebula ⬜️ Skipped (Inspect) Jul 28, 2025 0:15am
thirdweb_playground ⬜️ Skipped (Inspect) Jul 28, 2025 0:15am
wallet-ui ⬜️ Skipped (Inspect) Jul 28, 2025 0:15am

Copy link

changeset-bot bot commented Jul 27, 2025

⚠️ No Changeset found

Latest commit: 0c6d75d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel vercel bot temporarily deployed to Preview – nebula July 27, 2025 22:55 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 27, 2025 22:55 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 27, 2025 22:55 Inactive
Copy link
Contributor

coderabbitai bot commented Jul 27, 2025

Walkthrough

This change refactors multiple components in the claim conditions feature of a dashboard application, replacing Chakra UI and react-table with custom UI components and Tailwind CSS. Several form input wrappers are replaced, CSV data table is removed in favor of a new table, and UI structure and styling are modernized throughout. No exported API signatures are changed except for some internal type updates and the removal of deprecated components.

Changes

Cohort / File(s) Change Summary
Claim Conditions Form Inputs Refactor
…/Inputs/ClaimPriceInput.tsx
…/Inputs/ClaimerSelection.tsx
…/Inputs/CreatorInput.tsx
…/Inputs/MaxClaimablePerWalletInput.tsx
…/Inputs/MaxClaimableSupplyInput.tsx
…/Inputs/PhaseNameInput.tsx
…/Inputs/PhaseStartTimeInput.tsx
Replaced Chakra UI CustomFormControl and related layout with FormFieldSetup and Tailwind classes. Updated error handling, input wrappers, and layout for each input. Adjusted helper text and error message logic. No changes to input logic or exported signatures.
Claim Conditions Form & Phase Refactor
…/claim-conditions-form/index.tsx
…/claim-conditions-form/phase.tsx
Refactored main form and phase components to use custom UI library components instead of Chakra UI. Simplified form structure, updated button/menu/alert components, and reorganized phase details and editing controls. Removed admin-only wrappers and unsaved changes tracking. Modernized layout and conditional rendering. No changes to exported signatures.
Form Control/Group Component Removal
…/claim-conditions-form/common.tsx
Deleted CustomFormControl and CustomFormGroup components, removing Chakra UI-based form wrappers in favor of new approach.
CSV Table Refactor
…/snapshot-upload.tsx
…/csv-data-table.tsx
Replaced CsvDataTable (react-table-based, now deleted) with a new SnapshotDataTable using custom table UI and improved error/tooltips. Updated upload UI to use DropZone and new code snippet download. Adjusted layout, error display, and removed unused code.
Quantity Input Refactor
…/quantity-input-with-unlimited.tsx
Refactored to a function component with inline props, updated styling, and button classes. Removed explicit interface. No logic changes.
Price Input Refactor
…/price-input.tsx
Replaced Chakra NumberInput with custom DecimalInput, updated props typing, and simplified structure.
UI/Styling Tweaks
…/claim-conditions.tsx
…/price-preview.tsx
…/drop-zone.tsx
Updated container and heading classes, typography, spacing, and muted text color for improved UI consistency. No logic changes.
Downloadable Code Block Refactor
…/downloadable-code.tsx
Refactored layout: added header with file icon and filename, moved download button into header, updated styling and structure. No logic changes.
Transaction Button Variant
…/tx-button/index.tsx
Added "outline" as allowed variant value in TransactionButtonProps type. No logic changes.
Reset Claim Eligibility Button Refactor
…/reset-claim-eligibility.tsx
Refactored from React.FC to plain function, removed admin-only wrapper, updated button variant, icon, and styling. No logic changes.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant DashboardUI
    participant FormFieldSetup
    participant CustomUIComponents
    participant Backend

    User->>DashboardUI: Opens Claim Conditions Form
    DashboardUI->>FormFieldSetup: Renders input fields (e.g., price, supply, per-wallet)
    User->>FormFieldSetup: Inputs data
    FormFieldSetup->>DashboardUI: Passes validated data
    User->>DashboardUI: Clicks "Add Phase" or "Save"
    DashboardUI->>CustomUIComponents: Triggers dropdowns, alerts, buttons
    DashboardUI->>Backend: Submits claim condition data
    Backend-->>DashboardUI: Returns success/failure
    DashboardUI-->>User: Updates UI with result
Loading
sequenceDiagram
    participant User
    participant SnapshotUpload
    participant DropZone
    participant SnapshotDataTable

    User->>SnapshotUpload: Opens snapshot upload UI
    User->>DropZone: Drags/drops CSV file
    DropZone->>SnapshotUpload: Passes file data
    SnapshotUpload->>SnapshotDataTable: Parses and validates data
    SnapshotDataTable-->>User: Displays table with tooltips for errors
    User->>SnapshotUpload: Clicks reset/remove/next as needed
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

  • Complexity: High. Involves a broad, coordinated refactor across many files, replacing foundational UI components, updating form logic, and removing deprecated code. Reviewers must verify UI/UX consistency, correct error handling, and ensure no regressions in form or upload logic.

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TEAM-0000: Entity not found: Issue - Could not find referenced Issue.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 27fd53c and 0c6d75d.

⛔ Files ignored due to path filters (3)
  • apps/dashboard/public/assets/examples/snapshot-with-maxclaimable.csv is excluded by !**/*.csv
  • apps/dashboard/public/assets/examples/snapshot-with-overrides.csv is excluded by !**/*.csv
  • apps/dashboard/public/assets/examples/snapshot.csv is excluded by !**/*.csv
📒 Files selected for processing (20)
  • apps/dashboard/src/@/components/blocks/code/downloadable-code.tsx (2 hunks)
  • apps/dashboard/src/@/components/blocks/drop-zone/drop-zone.tsx (1 hunks)
  • apps/dashboard/src/@/components/tx-button/index.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimPriceInput.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimerSelection.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/CreatorInput.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimablePerWalletInput.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimableSupplyInput.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseNameInput.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseStartTimeInput.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/common.tsx (0 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx (12 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/phase.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-input.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-preview.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/quantity-input-with-unlimited.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/snapshot-upload.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/csv-data-table.tsx (0 hunks)
💤 Files with no reviewable changes (2)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/common.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/csv-data-table.tsx
🚧 Files skipped from review as they are similar to previous changes (18)
  • apps/dashboard/src/@/components/blocks/drop-zone/drop-zone.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions.tsx
  • apps/dashboard/src/@/components/tx-button/index.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseNameInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimablePerWalletInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-preview.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseStartTimeInput.tsx
  • apps/dashboard/src/@/components/blocks/code/downloadable-code.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimableSupplyInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimPriceInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimerSelection.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/quantity-input-with-unlimited.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-input.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/snapshot-upload.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/CreatorInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/phase.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Size
  • GitHub Check: Unit Tests
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 07-28-dashboard_migrate_claim_condition_components_from_chakra_to_tailwind

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@MananTank MananTank marked this pull request as ready for review July 27, 2025 22:55
@github-actions github-actions bot added the Dashboard Involves changes to the Dashboard. label Jul 27, 2025
@MananTank MananTank requested review from a team as code owners July 27, 2025 22:55
Copy link
Member Author

MananTank commented Jul 27, 2025


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@graphite-app graphite-app bot changed the base branch from 07-28-dashboard_migrate_marketplace_contract_pages_from_chakra_to_tailwind to graphite-base/7731 July 27, 2025 22:57
Copy link

codecov bot commented Jul 27, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.18%. Comparing base (11d9f3e) to head (0c6d75d).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7731   +/-   ##
=======================================
  Coverage   56.18%   56.18%           
=======================================
  Files         908      908           
  Lines       58236    58236           
  Branches     4200     4200           
=======================================
  Hits        32718    32718           
  Misses      25410    25410           
  Partials      108      108           
Flag Coverage Δ
packages 56.18% <ø> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

github-actions bot commented Jul 27, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 63.33 KB (0%) 1.3 s (0%) 299 ms (+145.76% 🔺) 1.6 s
thirdweb (cjs) 353.15 KB (0%) 7.1 s (0%) 1.1 s (+6.09% 🔺) 8.1 s
thirdweb (minimal + tree-shaking) 5.7 KB (0%) 114 ms (0%) 88 ms (+1127.49% 🔺) 202 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 42 ms (+1436.95% 🔺) 52 ms
thirdweb/react (minimal + tree-shaking) 19.24 KB (0%) 385 ms (0%) 97 ms (+507.4% 🔺) 481 ms

@graphite-app graphite-app bot force-pushed the graphite-base/7731 branch from cf24ca7 to 11d9f3e Compare July 27, 2025 23:05
@graphite-app graphite-app bot force-pushed the 07-28-dashboard_migrate_claim_condition_components_from_chakra_to_tailwind branch from 2fb0eed to 49f2d70 Compare July 27, 2025 23:05
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 27, 2025 23:05 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 27, 2025 23:05 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 27, 2025 23:05 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 27, 2025 23:05 Inactive
@graphite-app graphite-app bot changed the base branch from graphite-base/7731 to main July 27, 2025 23:06
@graphite-app graphite-app bot force-pushed the 07-28-dashboard_migrate_claim_condition_components_from_chakra_to_tailwind branch from 49f2d70 to 27fd53c Compare July 27, 2025 23:06
@vercel vercel bot temporarily deployed to Preview – nebula July 27, 2025 23:06 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 27, 2025 23:06 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 27, 2025 23:06 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 27, 2025 23:06 Inactive
@MananTank MananTank changed the title Dashboard: Migrate Claim condition components from chakra to tailwind Dashboard: Migrate Claim condition components from chakra to tailwind, UI improvements Jul 27, 2025
Copy link
Contributor

@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: 0

🔭 Outside diff range comments (5)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/CreatorInput.tsx (1)

1-46: Add 'use client' directive and className prop for consistency.

This component uses client-side hooks (useActiveAccount, useClaimConditionsFormContext) but is missing the required 'use client'; directive. Additionally, consider exposing a className prop on the root element for external style overrides.

+'use client';
+
 import { useActiveAccount } from "thirdweb/react";
 import { FormFieldSetup } from "@/components/blocks/FormFieldSetup";
 import { Input } from "@/components/ui/input";
 import { useClaimConditionsFormContext } from "../index";

 /**
  * Display the creator address
  */

 interface CreatorInputProps {
   creatorAddress: string;
+  className?: string;
 }

 export const CreatorInput: React.FC<CreatorInputProps> = ({
   creatorAddress,
+  className,
 }) => {

Apply this to the FormFieldSetup wrapper:

 return (
   <FormFieldSetup
+    className={className}
     isRequired={false}
     errorMessage={undefined}
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimablePerWalletInput.tsx (1)

1-71: Add 'use client' directive for client component.

This component uses client-side hooks and context but is missing the required 'use client'; directive at the top of the file.

+'use client';
+
 import { FormFieldSetup } from "@/components/blocks/FormFieldSetup";
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimableSupplyInput.tsx (1)

1-51: Add 'use client' directive for client component.

This component uses client-side hooks and form context but is missing the required 'use client'; directive.

+'use client';
+
 import { FormFieldSetup } from "@/components/blocks/FormFieldSetup";
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseStartTimeInput.tsx (1)

1-37: Add 'use client' directive for client component.

This component uses client-side form context and hooks but is missing the required 'use client'; directive.

+'use client';
+
 import { FormFieldSetup } from "@/components/blocks/FormFieldSetup";
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimPriceInput.tsx (1)

1-54: Add 'use client' directive for client component.

This component uses client-side form context and hooks but is missing the required 'use client'; directive.

+'use client';
+
 import { NATIVE_TOKEN_ADDRESS } from "thirdweb";
🧹 Nitpick comments (2)
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/phase.tsx (1)

1-1: Verify date-fns import for tree-shaking.

Consider using a more specific import path for better tree-shaking:

-import { formatDate } from "date-fns";
+import { formatDate } from "date-fns/formatDate";
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx (1)

388-398: Consider centralizing error handling logic.

The error handling could be improved by extracting the ZodError handling into a utility function:

} catch (error) {
  console.error(error);

  if (error instanceof ZodError) {
-   error.errors.forEach((e) => {
-     const path = `phases.${e.path.join(".")}`;
-     // biome-ignore lint/suspicious/noExplicitAny: FIXME
-     form.setError(path as any, e);
-   });
+   handleZodFormErrors(error, form, "phases");
  } else {
    saveClaimPhaseNotification.onError(error);
  }
}

This would make the error handling more reusable and remove the need for the any type assertion.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 11d9f3e and 27fd53c.

⛔ Files ignored due to path filters (3)
  • apps/dashboard/public/assets/examples/snapshot-with-maxclaimable.csv is excluded by !**/*.csv
  • apps/dashboard/public/assets/examples/snapshot-with-overrides.csv is excluded by !**/*.csv
  • apps/dashboard/public/assets/examples/snapshot.csv is excluded by !**/*.csv
📒 Files selected for processing (20)
  • apps/dashboard/src/@/components/blocks/code/downloadable-code.tsx (2 hunks)
  • apps/dashboard/src/@/components/blocks/drop-zone/drop-zone.tsx (1 hunks)
  • apps/dashboard/src/@/components/tx-button/index.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimPriceInput.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimerSelection.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/CreatorInput.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimablePerWalletInput.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimableSupplyInput.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseNameInput.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseStartTimeInput.tsx (3 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/common.tsx (0 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx (12 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/phase.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-input.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-preview.tsx (1 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/quantity-input-with-unlimited.tsx (4 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx (2 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/snapshot-upload.tsx (5 hunks)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/csv-data-table.tsx (0 hunks)
💤 Files with no reviewable changes (2)
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/csv-data-table.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/common.tsx
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose

Files:

  • apps/dashboard/src/@/components/blocks/drop-zone/drop-zone.tsx
  • apps/dashboard/src/@/components/tx-button/index.tsx
  • apps/dashboard/src/@/components/blocks/code/downloadable-code.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-preview.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseNameInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimableSupplyInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/quantity-input-with-unlimited.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseStartTimeInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimPriceInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimablePerWalletInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-input.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/CreatorInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimerSelection.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/phase.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/snapshot-upload.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • apps/dashboard/src/@/components/blocks/drop-zone/drop-zone.tsx
  • apps/dashboard/src/@/components/tx-button/index.tsx
  • apps/dashboard/src/@/components/blocks/code/downloadable-code.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-preview.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseNameInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimableSupplyInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/quantity-input-with-unlimited.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseStartTimeInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimPriceInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimablePerWalletInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-input.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/CreatorInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimerSelection.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/phase.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/snapshot-upload.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class logic
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components (Node edge): Start files with import "server-only";
Client Components (browser): Begin files with 'use client';
Always call getAuthToken() to retrieve JWT from cookies on server side
Use Authorization: Bearer header – never embed tokens in URLs
Return typed results (e.g., Project[], User[]) – avoid any
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stable queryKeys for React Query cache hits
Configure staleTime/cacheTime in React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never import posthog-js in server components

Files:

  • apps/dashboard/src/@/components/blocks/drop-zone/drop-zone.tsx
  • apps/dashboard/src/@/components/tx-button/index.tsx
  • apps/dashboard/src/@/components/blocks/code/downloadable-code.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-preview.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseNameInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimableSupplyInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/quantity-input-with-unlimited.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseStartTimeInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimPriceInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimablePerWalletInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-input.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/CreatorInput.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimerSelection.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/phase.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/snapshot-upload.tsx
  • apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Surface breaking changes prominently in PR descriptions
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: `Button`, `Input`, `Select`, `Tabs`, `Card`, `Sidebar`, `Separator`, `Badge`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Tailwind CSS is the styling system – avoid inline styles or CSS modules.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with `cn` from `@/lib/utils` to keep conditional logic readable.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Stick to design-tokens: background (`bg-card`), borders (`border-border`), muted text (`text-muted-foreground`) etc.
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use Tailwind CSS only – no inline styles or CSS modules
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under `@/components/ui/*` – e.g. `import { Button } from "@/components/ui/button"`.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Combine class names via `cn`, expose `className` prop if useful.
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Never hard-code colors – always go through Tailwind variables.
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/settings/shared-settings-page.tsx:29-39
Timestamp: 2025-05-27T20:10:47.245Z
Learning: MananTank prefers adding error handling (try-catch) directly inside utility functions like `shouldRenderNewPublicPage` rather than requiring callers to wrap the function calls in try-catch blocks. This centralizes error handling and benefits all callers automatically.
apps/dashboard/src/@/components/blocks/drop-zone/drop-zone.tsx (13)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Spacing utilities (px-*, py-*, gap-*) are preferred over custom margins.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Use the container class with a max-w-7xl cap for page width consistency.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Add className to the root element of every component for external overrides.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Stick to design-tokens: background (bg-card), borders (border-border), muted text (text-muted-foreground) etc.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Tailwind CSS is the styling system – avoid inline styles or CSS modules.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use Tailwind CSS only – no inline styles or CSS modules

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Surface breaking changes prominently in PR descriptions

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard//components//index.ts : Group related components in their own folder and expose a single barrel index.ts where necessary.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Combine class names via cn, expose className prop if useful.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use cn() from @/lib/utils for conditional class logic

Learnt from: MananTank
PR: #7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/components/webhook-metrics.tsx:40-40
Timestamp: 2025-07-02T20:04:53.982Z
Learning: The Spinner component imported from "@/components/ui/Spinner/Spinner" in the dashboard accepts a className prop, not a size prop. The correct usage is , not . The component defaults to "size-4" if no className is provided.

apps/dashboard/src/@/components/tx-button/index.tsx (12)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Stick to design-tokens: background (bg-card), borders (border-border), muted text (text-muted-foreground) etc.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Never hard-code colors – always go through Tailwind variables.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use Tailwind CSS only – no inline styles or CSS modules

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Add className to the root element of every component for external overrides.

Learnt from: MananTank
PR: #7227
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/OpenEditionMetadata.tsx:26-26
Timestamp: 2025-05-30T17:14:25.332Z
Learning: The ModuleCardUIProps interface already includes a client prop of type ThirdwebClient, so when components use Omit<ModuleCardUIProps, "children" | "updateButton">, they inherit the client prop without needing to add it explicitly.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to packages/thirdweb/src/wallets/** : EIP-1193, EIP-5792, EIP-7702 standard support in wallet modules

apps/dashboard/src/@/components/blocks/code/downloadable-code.tsx (17)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.{tsx,jsx} : Place the file close to its feature: feature/components/MyComponent.tsx.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Layouts should reuse SidebarLayout / FullWidthSidebarLayout (@/components/blocks/SidebarLayout).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.{tsx,jsx} : Name files after the component in PascalCase; append .client.tsx when interactive.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard//components//index.ts : Group related components in their own folder and expose a single barrel index.ts where necessary.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/layout.tsx : Building layout shells (layout.tsx) and top-level pages that mainly assemble data.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Client Components (browser): Begin files with 'use client';

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: saminacodes
PR: #7543
File: apps/portal/src/app/pay/page.mdx:4-4
Timestamp: 2025-07-07T21:21:47.488Z
Learning: In the thirdweb-dev/js repository, lucide-react icons must be imported with the "Icon" suffix (e.g., ExternalLinkIcon, RocketIcon) as required by the new linting rule, contrary to the typical lucide-react convention of importing without the suffix.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Icons come from lucide-react or the project-specific …/icons exports – never embed raw SVG.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.client.tsx : Client components must start with 'use client'; before imports.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Components that listen to user events, animations or live updates.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under @/components/ui/* – e.g. import { Button } from "@/components/ui/button".

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : When you need access to browser APIs (localStorage, window, IntersectionObserver etc.).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Accept a typed props object and export a named function (export function MyComponent()).

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-preview.tsx (10)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: jnsdls
PR: #7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Stick to design-tokens: background (bg-card), borders (border-border), muted text (text-muted-foreground) etc.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use cn() from @/lib/utils for conditional class logic

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : For notices & skeletons rely on AnnouncementBanner, GenericLoadingPage, EmptyStateCard.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Add className to the root element of every component for external overrides.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions.tsx (13)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Use the container class with a max-w-7xl cap for page width consistency.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Spacing utilities (px-*, py-*, gap-*) are preferred over custom margins.

Learnt from: jnsdls
PR: #7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use cn() from @/lib/utils for conditional class logic

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Add className to the root element of every component for external overrides.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Stick to design-tokens: background (bg-card), borders (border-border), muted text (text-muted-foreground) etc.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Combine class names via cn, expose className prop if useful.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : For notices & skeletons rely on AnnouncementBanner, GenericLoadingPage, EmptyStateCard.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/form.ts:25-42
Timestamp: 2025-06-10T00:46:00.514Z
Learning: In NFT creation functions, the setClaimConditions function signatures are intentionally different between ERC721 and ERC1155. ERC721 setClaimConditions accepts the full CreateNFTFormValues, while ERC1155 setClaimConditions accepts a custom object with nftCollectionInfo and nftBatch parameters because it processes batches differently than the entire form data.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/layout.tsx : Building layout shells (layout.tsx) and top-level pages that mainly assemble data.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseNameInput.tsx (12)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.{tsx,jsx} : Name files after the component in PascalCase; append .client.tsx when interactive.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Add className to the root element of every component for external overrides.

Learnt from: arcoraven
PR: #7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like aria-label and role in its TypeScript interface, causing compilation errors when added.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Combine class names via cn, expose className prop if useful.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/SocialUrls.tsx:24-25
Timestamp: 2025-06-10T15:59:29.585Z
Learning: In the SocialUrlsFieldset component in React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends WithSocialUrls, the type assertion as unknown as UseFormReturn<WithSocialUrls> is the preferred approach rather than trying to use as keyof T, because useFieldArray needs specific type information about the array field structure.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/attributes.tsx:24-25
Timestamp: 2025-06-10T00:49:12.707Z
Learning: In React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends a specific interface, it's often necessary to use type assertions like as unknown as UseFormReturn<WithAttributes> rather than trying to use as keyof T. The type assertion approach works better because useFieldArray needs specific type information about the array field structure, and the generic constraint ensures the field exists safely.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimableSupplyInput.tsx (13)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: arcoraven
PR: #7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like aria-label and role in its TypeScript interface, causing compilation errors when added.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.client.tsx : Client components must start with 'use client'; before imports.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Add className to the root element of every component for external overrides.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Use the container class with a max-w-7xl cap for page width consistency.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/SocialUrls.tsx:24-25
Timestamp: 2025-06-10T15:59:29.585Z
Learning: In the SocialUrlsFieldset component in React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends WithSocialUrls, the type assertion as unknown as UseFormReturn<WithSocialUrls> is the preferred approach rather than trying to use as keyof T, because useFieldArray needs specific type information about the array field structure.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/attributes.tsx:24-25
Timestamp: 2025-06-10T00:49:12.707Z
Learning: In React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends a specific interface, it's often necessary to use type assertions like as unknown as UseFormReturn<WithAttributes> rather than trying to use as keyof T. The type assertion approach works better because useFieldArray needs specific type information about the array field structure, and the generic constraint ensures the field exists safely.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/form.ts:25-42
Timestamp: 2025-06-10T00:46:00.514Z
Learning: In NFT creation functions, the setClaimConditions function signatures are intentionally different between ERC721 and ERC1155. ERC721 setClaimConditions accepts the full CreateNFTFormValues, while ERC1155 setClaimConditions accepts a custom object with nftCollectionInfo and nftBatch parameters because it processes batches differently than the entire form data.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/quantity-input-with-unlimited.tsx (13)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Accept a typed props object and export a named function (export function MyComponent()).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: jnsdls
PR: #7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Components that listen to user events, animations or live updates.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to **/*.{ts,tsx} : Limit each file to one stateless, single-responsibility function for clarity

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under @/components/ui/* – e.g. import { Button } from "@/components/ui/button".

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Keep components pure; fetch data outside (server component or hook) and pass it down via props.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Local state or effects live inside; data fetching happens in hooks.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseStartTimeInput.tsx (12)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.client.tsx : Client components must start with 'use client'; before imports.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Client Components (browser): Begin files with 'use client';

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under @/components/ui/* – e.g. import { Button } from "@/components/ui/button".

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Components that listen to user events, animations or live updates.

Learnt from: arcoraven
PR: #7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like aria-label and role in its TypeScript interface, causing compilation errors when added.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/SocialUrls.tsx:24-25
Timestamp: 2025-06-10T15:59:29.585Z
Learning: In the SocialUrlsFieldset component in React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends WithSocialUrls, the type assertion as unknown as UseFormReturn<WithSocialUrls> is the preferred approach rather than trying to use as keyof T, because useFieldArray needs specific type information about the array field structure.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/attributes.tsx:24-25
Timestamp: 2025-06-10T00:49:12.707Z
Learning: In React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends a specific interface, it's often necessary to use type assertions like as unknown as UseFormReturn<WithAttributes> rather than trying to use as keyof T. The type assertion approach works better because useFieldArray needs specific type information about the array field structure, and the generic constraint ensures the field exists safely.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimPriceInput.tsx (13)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: jnsdls
PR: #7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Tailwind CSS is the styling system – avoid inline styles or CSS modules.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: arcoraven
PR: #7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like aria-label and role in its TypeScript interface, causing compilation errors when added.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Layouts should reuse SidebarLayout / FullWidthSidebarLayout (@/components/blocks/SidebarLayout).

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/SocialUrls.tsx:24-25
Timestamp: 2025-06-10T15:59:29.585Z
Learning: In the SocialUrlsFieldset component in React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends WithSocialUrls, the type assertion as unknown as UseFormReturn<WithSocialUrls> is the preferred approach rather than trying to use as keyof T, because useFieldArray needs specific type information about the array field structure.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/attributes.tsx:24-25
Timestamp: 2025-06-10T00:49:12.707Z
Learning: In React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends a specific interface, it's often necessary to use type assertions like as unknown as UseFormReturn<WithAttributes> rather than trying to use as keyof T. The type assertion approach works better because useFieldArray needs specific type information about the array field structure, and the generic constraint ensures the field exists safely.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/form.ts:25-42
Timestamp: 2025-06-10T00:46:00.514Z
Learning: In NFT creation functions, the setClaimConditions function signatures are intentionally different between ERC721 and ERC1155. ERC721 setClaimConditions accepts the full CreateNFTFormValues, while ERC1155 setClaimConditions accepts a custom object with nftCollectionInfo and nftBatch parameters because it processes batches differently than the entire form data.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimablePerWalletInput.tsx (14)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Use the container class with a max-w-7xl cap for page width consistency.

Learnt from: arcoraven
PR: #7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like aria-label and role in its TypeScript interface, causing compilation errors when added.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Add className to the root element of every component for external overrides.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Stick to design-tokens: background (bg-card), borders (border-border), muted text (text-muted-foreground) etc.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/SocialUrls.tsx:24-25
Timestamp: 2025-06-10T15:59:29.585Z
Learning: In the SocialUrlsFieldset component in React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends WithSocialUrls, the type assertion as unknown as UseFormReturn<WithSocialUrls> is the preferred approach rather than trying to use as keyof T, because useFieldArray needs specific type information about the array field structure.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under @/components/ui/* – e.g. import { Button } from "@/components/ui/button".

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/attributes.tsx:24-25
Timestamp: 2025-06-10T00:49:12.707Z
Learning: In React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends a specific interface, it's often necessary to use type assertions like as unknown as UseFormReturn<WithAttributes> rather than trying to use as keyof T. The type assertion approach works better because useFieldArray needs specific type information about the array field structure, and the generic constraint ensures the field exists safely.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Prefer API routes or server actions to keep tokens secret; the browser only sees relative paths.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx (18)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Accept a typed props object and export a named function (export function MyComponent()).

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.{tsx,jsx} : Name files after the component in PascalCase; append .client.tsx when interactive.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Components that listen to user events, animations or live updates.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Use cn() from @/lib/utils for conditional class logic

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Anything that consumes hooks from @tanstack/react-query or thirdweb SDKs.

Learnt from: MananTank
PR: #7227
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/OpenEditionMetadata.tsx:26-26
Timestamp: 2025-05-30T17:14:25.332Z
Learning: The ModuleCardUIProps interface already includes a client prop of type ThirdwebClient, so when components use Omit<ModuleCardUIProps, "children" | "updateButton">, they inherit the client prop without needing to add it explicitly.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Icons come from lucide-react or the project-specific …/icons exports – never embed raw SVG.

Learnt from: arcoraven
PR: #7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like aria-label and role in its TypeScript interface, causing compilation errors when added.

Learnt from: MananTank
PR: #7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/erc20.tsx:15-17
Timestamp: 2025-05-27T19:54:55.885Z
Learning: The fetchDashboardContractMetadata function from "@3rdweb-sdk/react/hooks/useDashboardContractMetadata" has internal error handlers for all promises and cannot throw errors, so external error handling is not needed when calling this function.

Learnt from: saminacodes
PR: #7543
File: apps/portal/src/app/pay/page.mdx:4-4
Timestamp: 2025-07-07T21:21:47.488Z
Learning: In the thirdweb-dev/js repository, lucide-react icons must be imported with the "Icon" suffix (e.g., ExternalLinkIcon, RocketIcon) as required by the new linting rule, contrary to the typical lucide-react convention of importing without the suffix.

Learnt from: MananTank
PR: #7152
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/tokens/shared-page.tsx:41-48
Timestamp: 2025-05-26T16:28:50.772Z
Learning: The projectMeta prop is not required for the server-rendered ContractTokensPage component in the tokens shared page, unlike some other shared pages where it's needed for consistency.

Learnt from: MananTank
PR: #7434
File: apps/dashboard/src/app/(app)/team///contract/[chain]/[contractAddress]/components/project-selector.tsx:62-76
Timestamp: 2025-06-24T21:38:03.155Z
Learning: In the project-selector.tsx component for contract imports, the addToProject.mutate() call is intentionally not awaited (fire-and-forget pattern) to allow immediate navigation to the contract page while the import happens in the background. This is a deliberate design choice to prioritize user experience.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-input.tsx (10)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under @/components/ui/* – e.g. import { Button } from "@/components/ui/button".

Learnt from: arcoraven
PR: #7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like aria-label and role in its TypeScript interface, causing compilation errors when added.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Components that listen to user events, animations or live updates.

Learnt from: MananTank
PR: #7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts:49-49
Timestamp: 2025-05-27T19:55:25.056Z
Learning: In the ERC20 public pages token price data hook (useTokenPriceData.ts), direct array access on json.data[0] without optional chaining is intentionally correct and should not be changed to use safety checks.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Stick to design-tokens: background (bg-card), borders (border-border), muted text (text-muted-foreground) etc.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/CreatorInput.tsx (13)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/form.ts:25-42
Timestamp: 2025-06-10T00:46:00.514Z
Learning: In NFT creation functions, the setClaimConditions function signatures are intentionally different between ERC721 and ERC1155. ERC721 setClaimConditions accepts the full CreateNFTFormValues, while ERC1155 setClaimConditions accepts a custom object with nftCollectionInfo and nftBatch parameters because it processes batches differently than the entire form data.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: arcoraven
PR: #7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like aria-label and role in its TypeScript interface, causing compilation errors when added.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/SocialUrls.tsx:24-25
Timestamp: 2025-06-10T15:59:29.585Z
Learning: In the SocialUrlsFieldset component in React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends WithSocialUrls, the type assertion as unknown as UseFormReturn<WithSocialUrls> is the preferred approach rather than trying to use as keyof T, because useFieldArray needs specific type information about the array field structure.

Learnt from: MananTank
PR: #7356
File: apps/nebula/src/app/not-found.tsx:1-1
Timestamp: 2025-06-17T18:30:52.976Z
Learning: In the thirdweb/js project, the React namespace is available for type annotations (like React.FC) without needing to explicitly import React. This is project-specific configuration that differs from typical TypeScript/React setups.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/attributes.tsx:24-25
Timestamp: 2025-06-10T00:49:12.707Z
Learning: In React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends a specific interface, it's often necessary to use type assertions like as unknown as UseFormReturn<WithAttributes> rather than trying to use as keyof T. The type assertion approach works better because useFieldArray needs specific type information about the array field structure, and the generic constraint ensures the field exists safely.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Anything that consumes hooks from @tanstack/react-query or thirdweb SDKs.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under @/components/ui/* – e.g. import { Button } from "@/components/ui/button".

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimerSelection.tsx (13)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: arcoraven
PR: #7505
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx:186-204
Timestamp: 2025-07-10T10:18:33.238Z
Learning: The ThirdwebBarChart component in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/webhooks/analytics/components/WebhookAnalyticsCharts.tsx does not accept standard accessibility props like aria-label and role in its TypeScript interface, causing compilation errors when added.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Components that listen to user events, animations or live updates.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under @/components/ui/* – e.g. import { Button } from "@/components/ui/button".

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : For notices & skeletons rely on AnnouncementBanner, GenericLoadingPage, EmptyStateCard.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/SocialUrls.tsx:24-25
Timestamp: 2025-06-10T15:59:29.585Z
Learning: In the SocialUrlsFieldset component in React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends WithSocialUrls, the type assertion as unknown as UseFormReturn<WithSocialUrls> is the preferred approach rather than trying to use as keyof T, because useFieldArray needs specific type information about the array field structure.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/attributes.tsx:24-25
Timestamp: 2025-06-10T00:49:12.707Z
Learning: In React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends a specific interface, it's often necessary to use type assertions like as unknown as UseFormReturn<WithAttributes> rather than trying to use as keyof T. The type assertion approach works better because useFieldArray needs specific type information about the array field structure, and the generic constraint ensures the field exists safely.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/form.ts:25-42
Timestamp: 2025-06-10T00:46:00.514Z
Learning: In NFT creation functions, the setClaimConditions function signatures are intentionally different between ERC721 and ERC1155. ERC721 setClaimConditions accepts the full CreateNFTFormValues, while ERC1155 setClaimConditions accepts a custom object with nftCollectionInfo and nftBatch parameters because it processes batches differently than the entire form data.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/phase.tsx (15)

Learnt from: jnsdls
PR: #7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/layout.tsx : Building layout shells (layout.tsx) and top-level pages that mainly assemble data.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : For notices & skeletons rely on AnnouncementBanner, GenericLoadingPage, EmptyStateCard.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Components that listen to user events, animations or live updates.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Layouts should reuse SidebarLayout / FullWidthSidebarLayout (@/components/blocks/SidebarLayout).

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{tsx} : Expose className prop on root element of components for overrides

Learnt from: saminacodes
PR: #7543
File: apps/portal/src/app/pay/page.mdx:4-4
Timestamp: 2025-07-07T21:21:47.488Z
Learning: In the thirdweb-dev/js repository, lucide-react icons must be imported with the "Icon" suffix (e.g., ExternalLinkIcon, RocketIcon) as required by the new linting rule, contrary to the typical lucide-react convention of importing without the suffix.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Icons come from lucide-react or the project-specific …/icons exports – never embed raw SVG.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under @/components/ui/* – e.g. import { Button } from "@/components/ui/button".

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Anything that consumes hooks from @tanstack/react-query or thirdweb SDKs.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/snapshot-upload.tsx (21)

Learnt from: jnsdls
PR: #7188
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx:15-15
Timestamp: 2025-05-29T00:46:09.063Z
Learning: In the accounts component at apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/accounts/components/accounts-count.tsx, the 3-column grid layout (md:grid-cols-3) is intentionally maintained even when rendering only one StatCard, as part of the design structure for this component.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : For notices & skeletons rely on AnnouncementBanner, GenericLoadingPage, EmptyStateCard.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Components that listen to user events, animations or live updates.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.{tsx,jsx} : Place the file close to its feature: feature/components/MyComponent.tsx.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.{tsx,jsx} : Name files after the component in PascalCase; append .client.tsx when interactive.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Icons come from lucide-react or the project-specific …/icons exports – never embed raw SVG.

Learnt from: saminacodes
PR: #7543
File: apps/portal/src/app/pay/page.mdx:4-4
Timestamp: 2025-07-07T21:21:47.488Z
Learning: In the thirdweb-dev/js repository, lucide-react icons must be imported with the "Icon" suffix (e.g., ExternalLinkIcon, RocketIcon) as required by the new linting rule, contrary to the typical lucide-react convention of importing without the suffix.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Anything that consumes hooks from @tanstack/react-query or thirdweb SDKs.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under @/components/ui/* – e.g. import { Button } from "@/components/ui/button".

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.client.tsx : Client components must start with 'use client'; before imports.

Learnt from: MananTank
PR: #7356
File: apps/nebula/src/app/not-found.tsx:1-1
Timestamp: 2025-06-17T18:30:52.976Z
Learning: In the thirdweb/js project, the React namespace is available for type annotations (like React.FC) without needing to explicitly import React. This is project-specific configuration that differs from typical TypeScript/React setups.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Client Components (browser): Begin files with 'use client';

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/layout.tsx : Building layout shells (layout.tsx) and top-level pages that mainly assemble data.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Keep components pure; fetch data outside (server component or hook) and pass it down via props.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/form.ts:12-14
Timestamp: 2025-06-10T00:55:19.140Z
Learning: The NFT collection form (nftCollectionInfoFormSchema) in apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/form.ts is intentionally designed to only allow File uploads for the image field, not hosted URLs. The schema correctly uses z.instanceof(File).optional() to restrict image inputs to uploaded files only.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Pages requiring fast transitions where data is prefetched on the client.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx (20)

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Reuse core UI primitives; avoid re-implementing buttons, cards, modals.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Prefer composable primitives over custom markup: Button, Input, Select, Tabs, Card, Sidebar, Separator, Badge.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (useState, useEffect, React Query, wallet hooks).

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Merge class names with cn from @/lib/utils to keep conditional logic readable.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Always import from the central UI library under @/components/ui/* – e.g. import { Button } from "@/components/ui/button".

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : For notices & skeletons rely on AnnouncementBanner, GenericLoadingPage, EmptyStateCard.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Icons come from lucide-react or the project-specific …/icons exports – never embed raw SVG.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Tailwind CSS is the styling system – avoid inline styles or CSS modules.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Use NavLink (@/components/ui/NavLink) for internal navigation so active states are handled automatically.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/components/*.client.tsx : Client components must start with 'use client'; before imports.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Client Components (browser): Begin files with 'use client';

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : When you need access to browser APIs (localStorage, window, IntersectionObserver etc.).

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Components that listen to user events, animations or live updates.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Anything that consumes hooks from @tanstack/react-query or thirdweb SDKs.

Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Server Components (Node edge): Start files with import "server-only";

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/_common/SocialUrls.tsx:24-25
Timestamp: 2025-06-10T15:59:29.585Z
Learning: In the SocialUrlsFieldset component in React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends WithSocialUrls, the type assertion as unknown as UseFormReturn<WithSocialUrls> is the preferred approach rather than trying to use as keyof T, because useFieldArray needs specific type information about the array field structure.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/upload-nfts/single-upload/attributes.tsx:24-25
Timestamp: 2025-06-10T00:49:12.707Z
Learning: In React Hook Form with TypeScript generics, when using useFieldArray with a generic form type T that extends a specific interface, it's often necessary to use type assertions like as unknown as UseFormReturn<WithAttributes> rather than trying to use as keyof T. The type assertion approach works better because useFieldArray needs specific type information about the array field structure, and the generic constraint ensures the field exists safely.

Learnt from: MananTank
PR: #7315
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/assets/create/nft/form.ts:25-42
Timestamp: 2025-06-10T00:46:00.514Z
Learning: In NFT creation functions, the setClaimConditions function signatures are intentionally different between ERC721 and ERC1155. ERC721 setClaimConditions accepts the full CreateNFTFormValues, while ERC1155 setClaimConditions accepts a custom object with nftCollectionInfo and nftBatch parameters because it processes batches differently than the entire form data.

Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/layout.tsx : Building layout shells (layout.tsx) and top-level pages that mainly assemble data.

🔇 Additional comments (36)
apps/dashboard/src/@/components/blocks/drop-zone/drop-zone.tsx (1)

29-29: LGTM! Consistent spacing improvement.

The addition of px-4 horizontal padding aligns with the design system guidelines for using spacing utilities and improves the visual consistency of the drop zone component.

apps/dashboard/src/@/components/blocks/code/downloadable-code.tsx (2)

2-2: Good addition of FileTextIcon import.

The FileTextIcon import follows the established pattern for lucide-react icons and supports the improved header design.


13-42: Excellent refactoring with improved layout structure.

The component restructuring creates a clear separation between header and content, replacing absolute positioning with proper flexbox layout. The implementation correctly:

  • Uses design tokens (bg-card, border, text-muted-foreground)
  • Follows spacing utilities with proper padding classes
  • Maintains UI primitive usage (Button with proper variants)
  • Creates semantic structure with file icon and download button in header

This aligns perfectly with the dashboard guidelines for composable primitives and Tailwind CSS usage.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/snapshot-upload.tsx (10)

1-6: Proper icon imports with correct suffix convention.

The lucide-react icon imports correctly follow the established pattern with "Icon" suffix as required by the project's linting rules.


8-9: Good integration of refactored UI components.

The imports of DownloadableCode and DropZone components align with the broader UI migration effort and follow proper import patterns from the blocks directory.


19-27: Proper UI primitive imports from central library.

The Table component imports correctly follow the established pattern of importing from @/components/ui/* as specified in the coding guidelines.


58-122: Excellent custom table implementation replacing react-table.

The new SnapshotDataTable component is well-structured and follows all established guidelines:

  • Uses proper UI primitives from @/components/ui/table
  • Implements clear validation feedback with tooltips and error states
  • Follows design token conventions (text-red-500, proper spacing)
  • Provides semantic column structure with appropriate conditional rendering
  • Handles edge cases (ZERO_ADDRESS, unlimited values, default states)

This replacement of react-table with a custom implementation reduces complexity while maintaining functionality.


163-163: Consistent spacing utility usage.

The space-y-6 class follows the established pattern of using Tailwind spacing utilities instead of custom margins.


166-201: Well-structured button layout with proper UI primitives.

The button section demonstrates excellent use of:

  • Proper flexbox layout (flex justify-end gap-3)
  • Design tokens (border-t border-dashed)
  • UI primitive usage (Button with variants and proper sizing)
  • Semantic icon usage with consistent sizing (size-4)
  • Conditional rendering based on validation state

204-219: Improved DropZone integration with better UX.

The DropZone implementation provides clear user feedback with proper error states and consistent styling. The conditional title and description enhance usability.


221-304: Enhanced documentation section with improved component usage.

The requirements section shows excellent improvements:

  • Proper semantic structure with <p> elements
  • Integration of refactored DownloadableCode component
  • Clear information hierarchy
  • Consistent text styling with design tokens

325-327: Proper modal sizing and layout improvements.

The SheetContent styling updates (!w-full !max-w-4xl) and header spacing (mb-3) improve the modal's usability and visual consistency.


335-348: Clean CSV example data organization.

The template literals for CSV examples are well-organized and provide clear examples for users to understand the expected format.

apps/dashboard/src/@/components/tx-button/index.tsx (1)

31-31: LGTM! Clean addition of new button variant.

The addition of the "outline" variant to the TransactionButton component is well-implemented and maintains backward compatibility while extending styling options.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx (2)

13-25: LGTM! Good migration to function declaration with inline props.

The conversion from React.FC with a separate interface to a function component with inline typed props follows modern React patterns and improves readability.


70-103: Confirm AdminOnly guard and transactionCount update in claim-conditions reset

Please double-check the following in apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/reset-claim-eligibility.tsx:

  • The <AdminOnly> wrapper was removed here—ensure that the parent route (…/claim-conditions/page.tsx or its layout) still enforces admin-only access.
  • transactionCount is now undefined (previously 1) and matches the change in claim-conditions-form/index.tsx. Verify this doesn’t break button padding or the tooltip logic when displaying transaction counts.
apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions.tsx (1)

23-31: LGTM! Improved layout and typography with Tailwind utilities.

The changes enhance the visual hierarchy and spacing:

  • space-y-5 provides better semantic vertical spacing than flex gap
  • Increased heading size (text-2xl) improves visual hierarchy
  • Reduced margin and removed trailing period improve text flow

These updates align well with the Tailwind CSS migration and design system guidelines.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseNameInput.tsx (1)

1-1: LGTM! Clean migration from CustomFormControl to FormFieldSetup.

The refactor successfully replaces the Chakra UI-based CustomFormControl with the new FormFieldSetup component. The explicit error handling setup (isRequired={false}, errorMessage={undefined}) and width constraint (max-w-xs) improve both functionality and layout consistency.

This change aligns with the broader migration strategy across claim condition input components.

Also applies to: 15-31

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-preview.tsx (1)

27-41: LGTM! Improved styling hierarchy and consistency.

The styling updates effectively enhance the component's visual presentation:

  • space-y-0.5 provides better spacing control than global muted text
  • Heading uses text-foreground and font-medium for improved readability and hierarchy
  • Consistent text-muted-foreground text-sm styling for both free and paid price displays

These changes align with the Tailwind CSS migration and design system guidelines while maintaining all existing functionality.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/CreatorInput.tsx (1)

25-43: LGTM: Clean migration to FormFieldSetup.

The migration from CustomFormControl to FormFieldSetup is implemented correctly, with proper error handling and Tailwind CSS classes. The input remains appropriately disabled and read-only for the creator address display.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimablePerWalletInput.tsx (1)

26-68: LGTM: Excellent migration with improved link component.

The migration to FormFieldSetup is well-executed with proper error handling. The switch from Next.js Link to the custom UnderlineLink component aligns well with the UI migration strategy and maintains consistent styling.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/MaxClaimableSupplyInput.tsx (1)

24-48: LGTM: Clean and consistent migration.

The migration to FormFieldSetup is implemented correctly with proper error handling and maintains the same component functionality. The pattern is consistent with other input components in this refactor.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/PhaseStartTimeInput.tsx (1)

13-34: LGTM: Proper datetime input migration.

The migration to FormFieldSetup and custom Input component is well-implemented. The datetime-local input type with proper date formatting and Tailwind styling maintains good UX while following the new UI patterns.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimPriceInput.tsx (1)

20-51: LGTM: Excellent layout migration with proper responsive design.

The migration from Chakra UI layout components to Tailwind CSS is well-executed. Good use of the cn utility for class management and proper responsive flex layout (flex-col md:flex-row). The component structure is clean and maintains proper form functionality.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/price-input.tsx (1)

1-28: LGTM! Clean migration from Chakra UI to custom components.

The refactor correctly replaces Chakra UI's NumberInput with the custom DecimalInput component while preserving the original validation logic.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/quantity-input-with-unlimited.tsx (3)

5-20: LGTM! Proper migration to named function export.

The refactoring from arrow function to named export function with inline props aligns with the coding guidelines.


46-46: Good use of design tokens and responsive constraints.

The container styling properly uses design system tokens (bg-background, border-border) and adds a sensible max-width constraint.


65-65: Consistent button styling with design system.

The button styling correctly uses design tokens (text-muted-foreground) and maintains proper hover states.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/Inputs/ClaimerSelection.tsx (3)

89-97: Proper migration to FormFieldSetup component.

The replacement of CustomFormControl with FormFieldSetup maintains consistent form field handling across the claim conditions form.


101-117: Good use of UI primitives for select functionality.

The custom Select components provide better styling control and consistency compared to native HTML select.


134-140: Excellent use of cn() for conditional styling.

The conditional class logic is clean and follows the coding guidelines for using cn() from @/lib/utils.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/phase.tsx (2)

45-46: Good use of DynamicHeight for smooth transitions.

The wrapper provides a better user experience with animated height changes.


139-167: Well-structured footer with improved button organization.

The footer layout with conditional admin buttons and consistent styling improves usability and maintains proper access control.

apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx (3)

1-1: Correct placement of client directive.

The "use client" directive is properly placed before imports as required for client components.


4-8: Proper icon imports following naming convention.

All lucide-react icons correctly use the "Icon" suffix as required by the linting rules.


521-533: Excellent migration to custom Alert components.

The Alert component properly uses design tokens and provides clear visual hierarchy with icons and structured content.

Copy link
Contributor

graphite-app bot commented Jul 28, 2025

Merge activity

…, UI improvements (#7731)

<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on enhancing the user interface and functionality of the claim conditions forms in the dashboard application. It includes updates to component structures, styling improvements, and the introduction of new features for better user experience.

### Detailed summary
- Removed unused CSV files from the assets.
- Updated `variant` prop in `tx-button` to include "outline".
- Adjusted styles in `drop-zone` for improved layout.
- Enhanced text styles in `price-preview` and `claim-conditions` components.
- Replaced `CustomFormControl` with `FormFieldSetup` for better form handling.
- Added new components for displaying and managing claim conditions.
- Improved error handling and user feedback in various input components.
- Refactored `ClaimPriceInput` and other input components to streamline functionality.
- Introduced a new `SnapshotDataTable` for better display of CSV data.
- Enhanced snapshot upload functionality with clearer requirements and examples.

> ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}`

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

* **New Features**
  * Added support for an "outline" button style variant in transaction buttons.

* **Refactor**
  * Replaced Chakra UI components with a custom UI library and Tailwind CSS across claim conditions forms and related components.
  * Simplified and reorganized the layout of claim conditions phases, downloadable code blocks, and snapshot upload views for improved clarity and usability.
  * Updated CSV upload and data table experience with enhanced error display and a new code example download feature.

* **Style**
  * Improved spacing, typography, and overall visual consistency throughout claim conditions and related dashboard components.

* **Chores**
  * Removed unused or redundant components and files related to previous form controls and CSV tables.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@graphite-app graphite-app bot force-pushed the 07-28-dashboard_migrate_claim_condition_components_from_chakra_to_tailwind branch from 27fd53c to 0c6d75d Compare July 28, 2025 00:06
@vercel vercel bot temporarily deployed to Preview – docs-v2 July 28, 2025 00:06 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui July 28, 2025 00:06 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula July 28, 2025 00:06 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground July 28, 2025 00:06 Inactive
@graphite-app graphite-app bot merged commit 0c6d75d into main Jul 28, 2025
25 checks passed
@graphite-app graphite-app bot deleted the 07-28-dashboard_migrate_claim_condition_components_from_chakra_to_tailwind branch July 28, 2025 00:16
@vercel vercel bot temporarily deployed to Production – nebula July 28, 2025 00:16 Inactive
@vercel vercel bot temporarily deployed to Production – docs-v2 July 28, 2025 00:16 Inactive
@vercel vercel bot temporarily deployed to Production – wallet-ui July 28, 2025 00:16 Inactive
@vercel vercel bot temporarily deployed to Production – thirdweb_playground July 28, 2025 00:16 Inactive
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Dashboard Involves changes to the Dashboard.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants