deckhearth/components/CardEditorView.js
Randall Stillwell d269bd29c1 feat(design-system): sweep authenticated body-content panels to glass
PR #95/#96 shipped the Liquid Glass foundation (tokens, primitives, gates)
plus Layout shell, modals, landing, auth pages, and form CTAs — but body-
content panels on authenticated pages (admin Card Editor, admin Card
Import, admin Submissions, dashboard, my-cards, settings, scanner panels,
card detail price cards, popovers) were still rendering as flat
var(--bg-secondary) cards. Result: the admin Tools screen and several
core pages looked unchanged after the redesign.

This sweep adds a `.glass-panel` / `.glass-panel-strong` utility
(<GlassSurface tint=mid/high rim=subtle elevation=ambient/pronounced
blur=mid/high> in class form) and applies it across 18 surfaces:

  * Admin Card Editor view, search panel, form (5 sections), preview
  * Admin Card Import navigation + 3 body cards + sync panel
  * Admin Card Submissions list items
  * Dashboard stat cards + empty-state + grid items (5 surfaces)
  * My-cards empty-state CTA card
  * Settings panels (3)
  * Scanner page settings + grid + queue + bulk toolbar + dialog
  * Scanner destination picker + camera status banner + disambiguation
  * Card detail price cards (Current / TCGPlayer / CardKingdom)
  * Permission indicator tooltips
  * Collections page header card
  * Card detail view price cards

Also migrates the lingering admin Card Editor "Card Editor / Card Import"
nav buttons and the "Save Changes" / "Import Cards" / "Run catalog sync"
CTAs to the <Button> primitive (consistent loading + disabled states).

Page header bands (full-bleed strips with border-bottom on dashboard,
my-cards, cards, collections, community/collections, collection/[id])
are intentionally left solid — they're not card-shaped surfaces and
stacking glass-on-glass directly below the already-glass topbar would
muddy the hierarchy.

Tests: lint clean, vitest 104/104, build green. The visual diff
baseline will need refresh because the homepage spec is unaffected
(it targets the unauthenticated landing page) but the dashboard/
admin/scanner surfaces will diff if/when we add baselines for them.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-03 20:44:40 -05:00

96 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import CardEditorForm from './CardEditorForm';
import CardEditorPreview from './CardEditorPreview';
import CardEditorSearchPanel from './CardEditorSearchPanel';
import { Button } from './ui';
export default function CardEditorView({
card,
formData,
handleColorChange,
handleInputChange,
handleSave,
message,
onSearchQueryChange,
router,
saving,
searchLoading,
searchQuery,
searchResults,
selectCard,
showEmptyState,
}) {
return (
<div className="container mx-auto px-6 py-8">
<div className="glass-panel mb-8 p-4 rounded-xl">
<div className="flex items-center justify-between">
<h1 className="text-2xl font-bold" style={{ color: 'var(--text-primary)' }}>
Admin Tools
</h1>
<div className="flex gap-4">
<Button
variant="primary"
onClick={() => router.push('/admin/card-editor')}
leadingIcon={<span aria-hidden="true">🖊</span>}
>
Card Editor
</Button>
<Button
variant="secondary"
onClick={() => router.push('/admin/card-import')}
leadingIcon={<span aria-hidden="true">📥</span>}
>
Card Import
</Button>
</div>
</div>
</div>
<div className="mb-8">
<h2 className="text-3xl font-bold mb-2" style={{ color: 'var(--text-primary)' }}>
Admin Card Editor
</h2>
<p style={{ color: 'var(--text-secondary)' }}>
Search for a card to edit its details, or continue editing the selected card.
</p>
</div>
<CardEditorSearchPanel
searchQuery={searchQuery}
onSearchQueryChange={onSearchQueryChange}
searchLoading={searchLoading}
searchResults={searchResults}
onSelectCard={selectCard}
/>
{card && (
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
<div className="lg:col-span-1">
<CardEditorPreview formData={formData} />
</div>
<div className="lg:col-span-2">
<CardEditorForm
formData={formData}
onInputChange={handleInputChange}
onColorChange={handleColorChange}
onSave={handleSave}
saving={saving}
message={message}
/>
</div>
</div>
)}
{showEmptyState && (
<div className="text-center py-12">
<div className="text-6xl mb-4" aria-hidden="true">🔍</div>
<h2 className="text-2xl font-bold mb-2" style={{ color: 'var(--text-primary)' }}>
Search for a Card to Edit
</h2>
<p style={{ color: 'var(--text-secondary)' }}>
Use the search box above to find a card you want to edit.
</p>
</div>
)}
</div>
);
}