feat(dashmint-lab): show mint supply, collapse form when sold out#89
feat(dashmint-lab): show mint supply, collapse form when sold out#89thephez wants to merge 9 commits into
Conversation
Restructure the sign-in screen so the form is the focal point rather than competing with paragraphs of prose. Add an eyebrow + headline hero, lift the form into a card with primary "Sign in" and secondary "Get a testnet identity" buttons, mark sample notes as a preview with muted styling, move the longer explanation into a collapsed `<details>`, and submit on Enter (Shift+Enter for newline). Sample-note copy now teaches identity-ownership, the shared-contract model, and revision-based conflict rejection. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…old out Adds a Supply block to the mint form (X / 100 minted with a progress bar) sourced from sdk.tokens.totalSupply — every mint burns one fixed-supply DashMint token, so minted = SUPPLY − circulating. When the supply is exhausted, the form collapses to just the Supply block and odds table; the name/description fields, token-balance block, mint button, and starter-pack section are hidden so the page reads as intentionally finished instead of broken. The starter-pack button is also disabled when fewer than pack-size mints remain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ter-pack gating Mocks fetchCardsMintedCount with a never-resolving default so existing tests stay in the supply-unknown branch, then adds three cases driving the new behavior: rendered supply count + progress, full-form collapse at 100/100, and starter-pack disabling when fewer than pack-size mints remain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Marketplace price sort: regex now accepts the K/M/B/T/Q suffixes produced by formatCreditsCompact (e.g. "999.9B cr"), with the suffix multiplied back into the parsed base so the descending-order assertion still holds. Mobile drawer: the previous backdrop click at (380, 10) landed inside the sticky mobile top bar, which shares the backdrop's z-index but renders above it due to its own stacking context — the close handler never fired. Moved the click to (360, 400), clearly below the top bar and right of the 208px drawer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Refresh the DashMint token balance whenever the Mint tab becomes active — SessionContext's balance effect only re-runs on login/contract change, so the value could otherwise lag a recent mint until the next page reload. Add a module-level cache keyed by contractId for the supply count so re-entering the Mint tab renders the last known value immediately instead of flashing the "—" placeholder while the refetch is in flight. A failed refetch now keeps the previous value rather than regressing to "—". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Leads with how many cards get minted instead of the abstract "random set," and spells out that the token cost is 1 per card so the math is obvious. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR adds minted card supply tracking to DashMint Lab, displays supply progress with sold-out gating for both single and starter-pack mints, and updates the Dashnote starter's sign-in onboarding experience. The changes include SDK interface extension, supply-query helper, form state management, supply UI rendering, comprehensive component and E2E tests, and sign-in component restructuring with matching CSS styles. ChangesDashMint Lab Supply Tracking
Dashnote Starter SignIn UI
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
example-apps/dashmint-lab/src/App.tsxESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox. example-apps/dashmint-lab/src/components/MintForm.tsxESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox. example-apps/dashmint-lab/src/dash/contractStorage.tsESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
DashMint Lab now calls sdk.tokens.totalSupply to render the mint-supply progress block, so the shared core type needed the matching method declaration. Returns { totalSupply: bigint, tokenId: string } | undefined to match the SDK shape.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
c78cb66 to
6306ba6
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@example-apps/dashmint-lab/src/components/MintForm.tsx`:
- Around line 43-58: The mint UI allows actions when mintedCount is null
(unknown) after a failed initial fetch; update the logic so actions are disabled
while supply is unknown: ensure the fetch in useEffect (using
fetchCardsMintedCount, mintedCountCache, and setMintedCount) sets a definitive
cached fallback or a separate "loading/unknown" flag and change any
action-enabling checks to require mintedCount !== null (or require !isUnknown)
before enabling mint/sold-out gating; apply the same guard to the other
occurrences that reference mintedCount (the blocks around the other noted
locations) so actions remain blocked until a concrete count or cached value is
present.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: adb7696d-6aaa-44eb-91f2-b6cf4e35b44b
📒 Files selected for processing (11)
example-apps/dashmint-lab/public/dashmint-lite.htmlexample-apps/dashmint-lab/src/App.tsxexample-apps/dashmint-lab/src/components/MintForm.tsxexample-apps/dashmint-lab/src/dash/contractStorage.tsexample-apps/dashmint-lab/src/dash/dashMintToken.tsexample-apps/dashmint-lab/src/dash/types.tsexample-apps/dashmint-lab/test/MintForm.test.tsxexample-apps/dashmint-lab/test/e2e/browse.spec.tsexample-apps/dashnote-starter/src/components/SignIn.tsxexample-apps/dashnote-starter/src/styles.csssetupDashClient-core.d.mts
| useEffect(() => { | ||
| if (!session.sdk) return; | ||
| let cancelled = false; | ||
| fetchCardsMintedCount({ sdk: session.sdk, contractId }) | ||
| .then((count) => { | ||
| mintedCountCache.set(contractId, count); | ||
| if (!cancelled) setMintedCount(count); | ||
| }) | ||
| .catch(() => { | ||
| // Keep the previous (possibly cached) value on failure so the UI | ||
| // doesn't regress to "—" just because a refetch hiccuped. | ||
| }); | ||
| return () => { | ||
| cancelled = true; | ||
| }; | ||
| }, [session.sdk, contractId, submitting, mintingPack]); |
There was a problem hiding this comment.
Block mint actions while supply is still unknown.
On a cold load, mintedCount starts as null, and it stays null on the first fetch failure. In that state both actions are still enabled, so users can submit before the sold-out check has resolved. That defeats the new sold-out gating this PR is adding.
Suggested fix
const starterPackTokenCost = BigInt(STARTER_PACK_SIZE);
+const supplyUnknown = mintedCount === null;
async function handleSubmit(e: FormEvent) {
e.preventDefault();
if (!session.sdk || !session.keyManager) return;
- if (submitting || mintingPack || soldOut || hasInsufficientTokensForCard) {
+ if (
+ supplyUnknown ||
+ submitting ||
+ mintingPack ||
+ soldOut ||
+ hasInsufficientTokensForCard
+ ) {
return;
}
setSubmitting(true);
try {
@@
async function handleStarterPack() {
if (!session.sdk || !session.keyManager) return;
if (
+ supplyUnknown ||
submitting ||
mintingPack ||
starterPackSoldOut ||
hasInsufficientTokensForStarterPack
) {
@@
<button
type="submit"
disabled={
+ supplyUnknown ||
submitting ||
mintingPack ||
!name.trim() ||
hasInsufficientTokensForCard
}
@@
<button
type="button"
onClick={handleStarterPack}
disabled={
+ supplyUnknown ||
submitting ||
mintingPack ||
starterPackSoldOut ||
hasInsufficientTokensForStarterPack
}Also applies to: 76-78, 100-105, 240-245, 278-283
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@example-apps/dashmint-lab/src/components/MintForm.tsx` around lines 43 - 58,
The mint UI allows actions when mintedCount is null (unknown) after a failed
initial fetch; update the logic so actions are disabled while supply is unknown:
ensure the fetch in useEffect (using fetchCardsMintedCount, mintedCountCache,
and setMintedCount) sets a definitive cached fallback or a separate
"loading/unknown" flag and change any action-enabling checks to require
mintedCount !== null (or require !isUnknown) before enabling mint/sold-out
gating; apply the same guard to the other occurrences that reference mintedCount
(the blocks around the other noted locations) so actions remain blocked until a
concrete count or cached value is present.
Summary
X / 100 minted+ progress bar) to the Mint page, sourced fromsdk.tokens.totalSupply— every mint burns one fixed-supply DashMint token, so minted = SUPPLY − circulating.formatCreditsCompact, and the mobile-drawer dismiss click moved out from under the sticky top bar.Summary by CodeRabbit
New Features
UI/UX Improvements
Chores