One-time migration script processes items, globalItems, and
threadCandidates to extract dominant colors via Sharp. Idempotent,
batched (10 concurrent), with progress logging.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show ImageCropEditor after successful upload when onCropChange
callback is provided. Editor replaces image preview temporarily.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Zoom+pan editor using react-easy-crop with zoom slider, save/cancel
buttons, and dominant color background. Returns crop coordinates
for persistence.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace object-cover on item detail, global item detail, candidate
detail, global items index, and LinkToGlobalItem. Detail pages use
dominant color backgrounds. LinkToGlobalItem uses cover mode for
32px thumbnails.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace object-cover with GearImage across ComparisonTable,
CatalogSearchOverlay (2 instances), and ImageUpload preview.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace object-cover with GearImage for fit-within rendering on
candidate cards and list items.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace object-cover with GearImage component for fit-within rendering.
Add dominantColor and crop props to both card components.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Renders images with object-contain by default (letterbox/pillarbox),
object-cover when cover prop is set, or CSS transform when crop
values are present. Parent container uses dominant color background.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add dominantColor, cropZoom, cropX, cropY to createItemSchema,
createCandidateSchema, and upsertGlobalItemSchema.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Both POST /api/images and POST /api/images/from-url now return
dominantColor in their response body.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
extractDominantColor() resizes image to 1x1 pixel for weighted average
color. Integrated into fetchImageFromUrl to return dominantColor.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Migration adds dominant_color, crop_zoom, crop_x, crop_y to items,
global_items, and thread_candidates. Run db:push to apply.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add dominant_color, crop_zoom, crop_x, crop_y columns to items,
global_items, and thread_candidates tables.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds Profile link to UserMenu dropdown (above Settings), extends /me
endpoint to return user's createdAt for member-since display, and
updates AuthState interface with optional createdAt field.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds /profile route with four sections: profile info (reuses ProfileSection),
account info (email + member since), security (password change/set), and
danger zone (account deletion with typed confirmation). Removes ProfileSection
from settings page per D-01.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Creates /api/account routes with password change (verifies current first),
email update, has-password check, and account deletion with public setup
anonymization. Adds Zod validation schemas and registers routes in index.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements LogtoManagementClient with token caching, password verification,
password update, email update, user deletion, and has-password check.
All methods proxy to Logto Management API via M2M credentials.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Two-row sticky toolbar: search input + view toggle (Row 1), tag/weight/price filter pills (Row 2)
- Tag filter popover with click-outside close via useRef/useEffect
- Weight and price range filter popovers with min/max sliders
- Active filter removable pills + Clear all button
- Grid view uses existing GlobalItemCard, list view uses Link-based GlobalItemListRow
- SkeletonGrid and SkeletonList loading states
- Empty state with context-aware message (query vs no catalog items)
- Search input pre-fills from ?q= URL param, debounces 300ms
- No framer-motion, no manual entry mode, no Add buttons