Commit graph

121 commits

Author SHA1 Message Date
Jan-Henrik Bruhn
271229c200 fix: Correct center pattern button calculation for Konva pivot points
The center pattern function was using the old calculation that didn't account for Konva's offsetX/offsetY pivot points. Since the pattern's center is now its pivot point, centering at the origin is simply {x: 0, y: 0}.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 21:49:33 +01:00
Jan-Henrik Bruhn
a97439da7b fix: Refactor KonvaComponents and remove unused rotation code
Moved KonvaComponents.tsx into PatternCanvas subfolder for better organization and removed the unused RotationHandle component (143 lines) that was replaced by Konva's native Transformer. Updated import paths accordingly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 21:37:34 +01:00
Jan-Henrik Bruhn
469c08d45b feature: Create unified PatternLayer component to eliminate duplication
Unified three separate layer implementations into single PatternLayer component:

**PatternLayer.tsx (156 lines)**
- Handles both interactive (original) and locked (uploaded) pattern rendering
- Props-driven configuration for dragging, rotation, transformer
- Includes CurrentPosition indicator for uploaded patterns
- Memoized stitches and center calculations for performance
- Single source of truth for pattern rendering logic

**Benefits:**
- Eliminated ~140 lines of duplicated layer code
- Reduced PatternCanvas from 388 to 271 lines (-117 lines, -30%)
- Consistent rendering behavior across pattern states
- Easier to maintain and test pattern rendering
- Cleaner component composition in PatternCanvas

**Removed from PatternCanvas:**
- Original pattern layer implementation (74 lines)
- Uploaded pattern layer implementation (33 lines)
- Current position layer implementation (26 lines)
- Duplicate Group, Transformer, Stitches setup
- Redundant center calculations and stitch conversions

**Complete refactoring impact (All Phases):**
- Original: 786 lines in single monolithic file
- After Phase 4: 271 lines main + hooks + components
- **Total reduction: -515 lines (-65%)**

File structure now:
- PatternCanvas.tsx: 271 lines (orchestration)
- PatternLayer.tsx: 156 lines (rendering)
- useCanvasViewport.ts: 166 lines (viewport)
- usePatternTransform.ts: 179 lines (transform)
- 3 display components + 3 utilities

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 21:29:24 +01:00
Jan-Henrik Bruhn
99d32f9029 feature: Extract canvas state management into custom React hooks
Create two specialized custom hooks for PatternCanvas:

**useCanvasViewport (166 lines)**
- Manages canvas zoom, pan, and container resize
- Handles wheel zoom and button zoom operations
- Tracks container size with ResizeObserver
- Calculates initial scale when pattern changes
- Returns: stagePos, stageScale, containerSize, zoom handlers

**usePatternTransform (179 lines)**
- Manages pattern position, rotation, and transform state
- Handles drag and transform end events
- Syncs local state with global pattern store
- Manages transformer attachment/detachment
- Returns: offsets, rotation, refs, event handlers

Benefits:
- Reduced PatternCanvas from 608 to 388 lines (-220 lines, -36%)
- Better separation of concerns (viewport vs pattern transform)
- Reusable hooks for other canvas components
- Easier to test state management logic in isolation
- Cleaner component with focused responsibility

Combined refactoring impact (Phase 1+2+3):
- Original: 786 lines in single file
- After Phase 3: 388 lines main + hooks + components
- Total reduction: -398 lines (-51%)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 21:24:46 +01:00
Jan-Henrik Bruhn
b008fd3aa8 feature: Extract PatternCanvas display components into reusable modules
Extract three complex inline components into separate files:
- ThreadLegend: Thread color display with metadata (52 lines extracted)
- PatternPositionIndicator: Position/rotation display with locked state (49 lines extracted)
- ZoomControls: Zoom and pan control buttons (41 lines extracted)

Benefits:
- Reduced PatternCanvas.tsx from 730 to 608 lines (-122 lines)
- Cleaner component separation and reusability
- Better testability for individual UI components
- Removed unused icon imports (PlusIcon, MinusIcon, etc.)
- Single responsibility per component

Total refactoring impact (Phase 1+2):
- Before: 786 lines in single file
- After: 608 lines main + 3 focused components
- Reduction: -178 lines of complex inline code

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 21:19:20 +01:00
Jan-Henrik Bruhn
07275fa75a feature: Refactor PatternCanvas with utility functions and folder structure
Extract duplicate code into reusable utilities:
- calculatePatternCenter(): Eliminates 6x duplication of center calculations
- convertPenStitchesToPesFormat(): Eliminates 3x duplication of stitch conversion
- calculateZoomToPoint(): Eliminates 2x duplication of zoom math

Reorganize into subfolder:
- Created src/components/PatternCanvas/ directory
- Moved PatternCanvas.tsx into subfolder
- Added index.ts for clean imports
- All utilities in patternCanvasHelpers.ts

Benefits:
- Reduced ~50+ lines of duplicated code
- Single source of truth for common operations
- Easier to test and maintain
- Better code organization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 21:15:05 +01:00
Jan-Henrik Bruhn
d813c22df5 feature: Add pattern rotation with Konva Transformer
Implement comprehensive pattern rotation functionality:
- Use Konva Transformer for native rotation UI with visual handles
- Apply rotation transformation at upload time to stitch coordinates
- Two-layer preview system: original (draggable/rotatable) and uploaded (locked)
- Automatic position compensation for center shifts after rotation
- PEN encoding/decoding with proper bounds calculation from decoded stitches
- Comprehensive unit tests for rotation math and PEN round-trip
- Restore original unrotated pattern on delete

The rotation is applied by transforming stitch coordinates around the pattern's
geometric center, then re-encoding to PEN format. Position adjustments compensate
for center shifts caused by PEN encoder rounding to maintain visual alignment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-25 21:06:48 +01:00
Jan-Henrik Bruhn
ea879640a2
Merge pull request #26 from jhbruhn/fix/skeleton-fixes
Some checks failed
Build, Test, and Lint / Build, Test, and Lint (push) Has been cancelled
Draft Release / Draft Release (push) Has been cancelled
Draft Release / Build Web App (push) Has been cancelled
Draft Release / Build Release - macos-latest (push) Has been cancelled
Draft Release / Build Release - ubuntu-latest (push) Has been cancelled
Draft Release / Build Release - windows-latest (push) Has been cancelled
Draft Release / Upload to GitHub Release (push) Has been cancelled
Fix: skeleton fixes and upload button disable logic
2025-12-22 12:06:00 +01:00
Jan-Henrik Bruhn
943f117191 style: Apply linter auto-fixes
Add missing semicolons and adjust line breaks per ESLint rules.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 12:03:49 +01:00
Jan-Henrik Bruhn
5aa4e15922 fix: Improve destructive Alert variant styling
Update the destructive variant to use proper danger colors (light red background with dark red text in light mode, dark red background with light text in dark mode) instead of the previous white background with red text.

This allows semantic use of variant="destructive" throughout the app without custom styling overrides.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 12:00:54 +01:00
Jan-Henrik Bruhn
4593b66356 fix: Restore correct destructive variant colors
Swap destructive and destructive-foreground colors back to correct values. The previous commit accidentally reversed them, causing error states to show white background with red text instead of red background with white text.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 11:59:02 +01:00
Jan-Henrik Bruhn
469d9860de fix: Apply chart/catalogNumber duplicate detection to all components
Extend the duplicate detection logic from PatternCanvas to ProgressMonitor and PatternInfo. Now all components only show the chart field when it differs from catalogNumber, preventing redundant information display.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 11:54:30 +01:00
Jan-Henrik Bruhn
6e38ba855c fix: Prevent button activation during post-upload state synchronization
Fix the Choose File button remaining clickable during the brief window between upload completion and pattern info retrieval. The issue was that labels don't support the disabled attribute, so when using asChild with a label, the disabled state was ignored.

Changes:
- Only use asChild when button is enabled (labels can't be disabled)
- Keep input and button disabled conditions synchronized
- Add uploadProgress check to prevent re-enabling before patternUploaded is true

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 11:52:18 +01:00
Jan-Henrik Bruhn
b995eb898e fix: Update PatternInfoSkeleton to match actual PatternInfo layout
Replace generic key-value skeleton with a proper representation that matches the actual PatternInfo component structure:
- Three-column grid for Size, Stitches, and Colors stats
- Separator line between sections
- Color swatches row with circular placeholders

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-22 11:11:47 +01:00
Jan-Henrik Bruhn
9337fdf347 fix: Adjust shadcn config 2025-12-22 11:07:20 +01:00
Jan-Henrik Bruhn
69eb7c9986 feature: Add RGB color matching for Brother thread identification
Enhances the Brother color mapping to support exact RGB color matching in
addition to catalog number matching. This follows the logic from the
BrotherColor.FromColor method in the App codebase.

Changes:
- Added optional RGB matching to enhanceThreadWithBrotherColor function
- RGB matching is enabled by default but can be disabled via options
- Enhanced logging to show breakdown of matches (catalog vs RGB)
- Matching priority: catalog number first, then RGB (both exact match only)

Example: A thread with RGB(255,255,255) will now match Brother color "WHITE"
(code 001) even if the catalog number is missing or doesn't match.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 20:52:32 +01:00
Jan-Henrik Bruhn
32e96d7709 feature: Add Brother thread color mapping to PES importer
This commit incorporates the Brother thread color mapping from the App codebase
into the web application. When importing PES files, thread colors are now
automatically enhanced with official Brother Embroidery thread information
including proper color names and chart codes.

Changes:
- Added BrotherColor.json database with 56 Brother embroidery thread colors
- Created brotherColors utility module with mapping functions that replicate
  the logic from Asura.Core.Models.EmbroideryUtil.GetThreadColorListFromPesx
- Enhanced PES importer client to map thread catalog numbers to Brother colors
- Updated PatternCanvas to avoid showing duplicate chart/catalog information
  when they are the same (common for Brother colors)

The mapping logic performs exact color code matching (e.g., "001", "843") and
preserves original thread data when no Brother match is found.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 20:37:32 +01:00
Jan-Henrik Bruhn
d2bcf603b3 fix: Correct total time calculation and add detailed logging
Fix bug where total pattern time only included blocks up to current position,
and add comprehensive step-by-step logging for analysis.

Bug Fix:
- Separate total time calculation from elapsed time calculation
- Total time now correctly sums ALL color blocks regardless of current position
- Previously broke early when finding current position, missing remaining blocks

Logging Added:
- Step 1: Log calculation of total time across all blocks
- Step 2: Log calculation of elapsed time based on current stitch position
- Detailed per-block logging showing stitch counts, time conversions, and cumulative values
- Final result summary with total, elapsed, and remaining minutes

This allows proper analysis of the Brother PP1 timing formula:
((stitchCount - 1) * 150ms + 3000ms) / 60000, rounded up to minutes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 13:48:19 +01:00
Jan-Henrik Bruhn
a0cb6d1822 fix: Prevent PatternCanvas overflow on small screens
Replace fixed height values with flexbox sizing to prevent canvas overflow
when the window height is constrained.

Changes:
- Replace h-[400px] sm:h-[500px] lg:flex-1 with flex-1 on all screen sizes
- Add min-h-0 to CardContent and canvas container for proper flex shrinking
- Canvas now properly respects card boundaries on all screen sizes

The flex-1 min-h-0 pattern ensures the canvas takes available space without
overflowing its parent card, regardless of viewport size.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 13:32:13 +01:00
Jan-Henrik Bruhn
a077dea68e feature: Replace connection indicator with shadcn StatusIndicator
Replace the custom connection indicator dots with the shadcn StatusIndicator
component for better visual consistency and state indication.

Changes:
- Install status-indicator component from 8starlabs shadcn registry
- Add getStatusIndicatorState() helper to map MachineStateCategory to StatusIndicator states
- Replace connection indicator divs with StatusIndicator component in AppHeader
- Connection indicator now shows state-dependent colors:
  - Green (active): Connected and ready, sewing, or complete
  - Yellow (fixing): Connected and waiting for user action
  - Red (down): Connected but interrupted or in error state
  - Gray (idle): Disconnected
- Remove unused color prop from StatusIndicator component

The StatusIndicator provides animated visual feedback for different machine
states, making it easier for users to understand the current system status at
a glance.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 13:29:27 +01:00
Jan-Henrik Bruhn
4992c33bf1 feature: Migrate ProgressMonitor color blocks to shadcn ScrollArea
Replace custom scrollable div implementation with shadcn ScrollArea component
for the color blocks list in ProgressMonitor. This improves code maintainability
and provides consistent styling across the application.

Changes:
- Install @radix-ui/react-scroll-area via shadcn CLI
- Add scroll-area.tsx component with proper @/ path alias
- Replace custom scrollable div with ScrollArea wrapper
- Remove manual scroll handling:
  - Removed showGradient state and useState import
  - Removed colorBlocksScrollRef ref
  - Removed handleColorBlocksScroll function
  - Removed resize listener useEffect
  - Removed gradient overlay div
- Fix ScrollArea height constraint with lg:h-0 for proper flexbox scrolling
- Simplify component structure with 50+ fewer lines of scroll handling code

The ScrollArea component provides better accessibility and consistent scrollbar
styling while eliminating the need for manual scroll position tracking.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 13:20:12 +01:00
Jan-Henrik Bruhn
8ad8d7c773 fix: tw animate css 2025-12-21 00:24:04 +01:00
Jan-Henrik Bruhn
8b6eb593d9 feature: Add shadcn Tooltips to AppHeader for better UX
- Migrated serial number tooltip from native title to shadcn Tooltip
  - Shows formatted machine details (serial, MAC, total stitches, service count)
  - Better multi-line formatting with proper spacing

- Added tooltip to machine status badge
  - Shows state description explaining current status

- Added tooltip to auto-refresh spinner
  - Shows "Auto-refreshing machine status"

- Removed redundant title attributes
  - Disconnect button already has clear label
  - Error button has Popover for details

Benefits:
- Consistent tooltip styling across the app
- Better accessibility with ARIA attributes
- Improved readability with proper formatting
- Better positioning and animations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 00:16:52 +01:00
Jan-Henrik Bruhn
e1a64e9459 fix: Filter out error code 0xDD from error display
- Exclude machine error code 0xDD (221 decimal) from error popover
- This error code is non-critical and should not be displayed to users
- Maintains all other error codes and messages

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 00:09:53 +01:00
Jan-Henrik Bruhn
0e84f7ebe5 fix: Add eslint ignore for shadcn component utility exports
- Added eslint-disable-next-line for react-refresh/only-export-components
- Badge and Button components export utility functions (badgeVariants, buttonVariants)
- These utilities are required by shadcn pattern for variant composition
- Suppressing warning is appropriate since this is intentional design

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 00:07:56 +01:00
Jan-Henrik Bruhn
5849a1e854 feature: Migrate ErrorPopover to shadcn Popover component
- Migrated ErrorPopover to use shadcn PopoverContent
  - Removed forwardRef wrapper (handled by shadcn internally)
  - Replaced custom absolute positioning with PopoverContent component
  - Used cn() utility for cleaner className management
  - Maintained all styling with info/danger color variants

- Updated AppHeader to use Popover pattern
  - Replaced manual state management (showErrorPopover/setErrorPopover)
  - Removed refs and click-outside detection useEffect
  - Wrapped error button in Popover component with PopoverTrigger
  - Simplified code by removing 30+ lines of manual popover handling

Benefits:
- Better keyboard navigation and accessibility (built into Radix UI)
- Automatic focus management and ARIA attributes
- Cleaner, more maintainable code
- Consistent with other shadcn components in the app

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 00:06:38 +01:00
Jan-Henrik Bruhn
621de91bc8 fix: Improve theme color definitions and dark mode styling
- Fixed CSS variable format by wrapping HSL values in hsl() function
- Removed double hsl() wrapping in @theme section (now uses var() directly)
- Switched dark mode card background to OKLCH for better perceptual uniformity
- Improved dark mode border visibility (17.5% → 37.5% lightness)
- Improved dark mode input visibility (17.5% → 47.5% lightness)
- Changed app background from gray-300 to gray-100 for cleaner appearance
- Enhanced PatternCanvasPlaceholder to match PatternCanvas styling with icon and description

These changes ensure shadcn components use colors correctly and improve overall dark mode readability.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-21 00:02:22 +01:00
Jan-Henrik Bruhn
1820bcde77 feature: Migrate ConfirmDialog and BluetoothDevicePicker to shadcn dialogs
- Migrated ConfirmDialog to use shadcn AlertDialog component
  - Replaced custom modal structure with AlertDialogContent, AlertDialogHeader, AlertDialogFooter
  - Used AlertDialogAction and AlertDialogCancel for buttons
  - Maintained danger/warning variant support with border-top styling
  - Simplified code by removing manual escape key handling (built into AlertDialog)

- Migrated BluetoothDevicePicker to use shadcn Dialog component
  - Replaced custom modal structure with DialogContent, DialogHeader, DialogFooter
  - Used shadcn Button components with outline variant for device selection
  - Maintained scanning state UI with loading spinner in DialogDescription
  - Simplified code by removing manual escape key handling (built into Dialog)
  - Disabled close button for better UX during device selection

Both migrations maintain the same external API and functionality while significantly reducing code complexity.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 23:13:09 +01:00
Jan-Henrik Bruhn
3ca5edf4dc fix: Run prettier formatting on all components
- Applied prettier auto-formatting to all component and utility files
- Fixed semicolons, commas, and indentation throughout codebase
- No functional changes, only code style improvements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 23:03:38 +01:00
Jan-Henrik Bruhn
7cf4a5de17 feature: Migrate PatternCanvas to shadcn/ui and rename placeholder
- Migrated PatternCanvas component to use shadcn Card components (Card, CardHeader, CardTitle, CardDescription, CardContent)
- Replaced custom zoom control buttons with shadcn Button component using outline variant and icon size
- Renamed PatternPreviewPlaceholder to PatternCanvasPlaceholder for consistency
- Updated all imports and references in App.tsx
- Maintained all existing functionality including Konva canvas rendering, zoom controls, and pattern positioning

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:12:40 +01:00
Jan-Henrik Bruhn
bb066d7775 feature: Migrate PatternPreviewPlaceholder to shadcn Card
Migrated PatternPreviewPlaceholder component to use shadcn Card, CardHeader, and CardTitle components for consistent styling with other card-based components.

Changes:
- Replaced outer div with shadcn Card component
- Migrated header to use CardHeader and CardTitle
- Wrapped content in CardContent
- Applied consistent Card padding (p-0 gap-0)
- Maintained header border separator styling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:05:13 +01:00
Jan-Henrik Bruhn
93cca6d2d0 feature: Migrate ProgressMonitor to shadcn/ui and improve styling
Migrated ProgressMonitor component to use shadcn Card, Button, and Progress components. Removed redundant state visual indicator section that duplicated information already shown by progress bars, color blocks, and action buttons. Changed active thread block styling from vibrant accent colors to muted grays for better visual hierarchy.

Changes:
- Replaced outer div with shadcn Card component
- Migrated header to use CardHeader with CardTitle and CardDescription
- Replaced custom progress bars with shadcn Progress components
- Migrated all action buttons (Resume Sewing, Start Sewing, Start Mask Trace) to shadcn Button
- Removed redundant state visual indicator section (Ready/Active/Complete status)
- Removed unused imports (getStateVisualInfo and related icons)
- Applied consistent Card padding (p-0 gap-0, explicit CardHeader and CardContent padding)
- Changed active thread block from accent colors to muted grays (border, background, icon, progress bar)
- Removed violet border override on active color swatch

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 20:01:25 +01:00
Jan-Henrik Bruhn
054524cb5e feature: Enhance PatternInfo with Tooltip and improve card layouts
Added shadcn Tooltip component for interactive pattern information. Wrapped all PatternInfo stat boxes and color swatches in tooltips with detailed metadata and explanations. Migrated PatternSummaryCard to use CardHeader/CardTitle/CardDescription for better semantic structure. Fixed Card component spacing issues across all cards.

Changes:
- Installed and added shadcn Tooltip component
- Added tooltips to Size, Stitches, and Colors stat boxes with explanatory text
- Wrapped color swatches in Tooltips with detailed thread information
- Added Separator between pattern stats and colors sections
- Migrated PatternSummaryCard to use CardHeader with semantic title/description
- Fixed Card gap-0 on all cards (FileUpload, PatternSummaryCard, ConnectionPrompt)
- Added explicit padding to PatternSummaryCard: CardHeader (p-4 pb-3) and CardContent (px-4 pt-0 pb-4)
- Updated components.json to use src/ paths instead of @/ aliases to fix shadcn install location

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 19:52:16 +01:00
Jan-Henrik Bruhn
2544504933 feature: Update ConnectionPrompt to use shadcn Card component
Migrated ConnectionPrompt to use shadcn/ui Card and CardContent components for consistency with other card-based components (FileUpload, PatternSummaryCard). Maintains the same visual appearance while using the unified Card system.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 19:41:17 +01:00
Jan-Henrik Bruhn
ed3950b5d0 feature: Migrate FileUpload to shadcn/ui and fix dark mode
Migrated FileUpload component to use shadcn/ui Card, Button, Alert, and Progress components. Updated dark mode CSS variables to use media query approach for automatic system theme detection. Fixed Card component padding and button styling for better visual consistency.

Changes:
- Replaced custom div with shadcn Card and CardContent components
- Migrated buttons to shadcn Button component with outline variant for Choose File
- Replaced custom alerts with shadcn Alert components
- Replaced custom progress bars with shadcn Progress component
- Fixed Card padding by adding p-0 to Card and rounded-lg to CardContent
- Changed dark mode from .dark class to @media (prefers-color-scheme: dark)
- Fixed primary-foreground color in dark mode for proper white text contrast

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 19:38:27 +01:00
Jan-Henrik Bruhn
bd80e95004 feature: Migrate SkeletonLoader and PatternSummaryCard to shadcn/ui
- Replace SkeletonLoader with shadcn Skeleton component
- Simplify gradient animation to use shadcn's built-in pulse
- Migrate PatternSummaryCard to shadcn Card and Button
- Replace custom delete button with shadcn Button (outline variant)
- Use Loader2 from lucide-react for loading spinner

Code reduction:
- SkeletonLoader: Removed 8 lines of custom gradient classes
- Delete button: ~70% reduction (200+ char className → cleaner Button)
- Card wrapper: Semantic Card structure vs verbose div classes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 15:44:51 +01:00
Jan-Henrik Bruhn
365b0c7ae3 feature: Migrate AppHeader buttons and badges to shadcn/ui
- Replace Disconnect button with shadcn Button (outline variant)
- Replace status badge with shadcn Badge component
- Replace error button with shadcn Button (destructive variant)
- Use cn() helper for conditional className composition
- Preserve glass morphism effects and custom styling

Code reduction:
- Disconnect button: ~40% reduction
- Status badge: ~30% reduction
- Error button: ~60% reduction

Improved maintainability with semantic component usage and cleaner code structure.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 15:41:33 +01:00
Jan-Henrik Bruhn
08532d0b01 feature: Add shadcn/ui component library and migrate ConnectionPrompt
- Initialize shadcn/ui with cssVariables and path aliases
- Install core components: Button, Alert, Badge, Card, Dialog, etc.
- Configure Tailwind v4 theme integration with shadcn color system
- Migrate ConnectionPrompt to use shadcn Button and Alert components
- Add cursor-pointer to button variants for better UX
- Remove unused MachineConnection.tsx component

Code reduction: 87% in ConnectionPrompt button (150+ char className → 20 char)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-20 15:33:02 +01:00
Jan-Henrik Bruhn
a253901fb4 fix: run linter
Some checks are pending
Build, Test, and Lint / Build, Test, and Lint (push) Waiting to run
Draft Release / Draft Release (push) Waiting to run
Draft Release / Build Web App (push) Blocked by required conditions
Draft Release / Build Release - macos-latest (push) Blocked by required conditions
Draft Release / Build Release - ubuntu-latest (push) Blocked by required conditions
Draft Release / Build Release - windows-latest (push) Blocked by required conditions
Draft Release / Upload to GitHub Release (push) Blocked by required conditions
2025-12-18 11:39:22 +01:00
Jan-Henrik Bruhn
a4fc959eb1 fix: slightly shorten homing message 2025-12-18 11:27:58 +01:00
Jan-Henrik Bruhn
7c2172f52c fix: Remove unused src/assets directory
The src/assets directory only contained a react.svg file that was not referenced anywhere in the codebase. This appears to be leftover boilerplate from the project initialization.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-18 11:26:25 +01:00
Jan-Henrik Bruhn
6b3752cfc2 fix: Remove unused pyodideLoader file
The pyodideLoader was superseded by the worker-based pattern converter (client.ts and worker.ts) which runs Pyodide in a background thread. This legacy code is no longer referenced anywhere in the codebase.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-18 10:21:54 +01:00
Jan-Henrik Bruhn
ab9b22b9b8 feature: Implement unified semantic color system with Tailwind v4
- Define semantic color theme in App.css using @theme directive
  - Primary (blue), Success (green), Warning (amber), Danger (red)
  - Info (cyan), Accent (purple), Secondary (orange), Tertiary (teal)
  - Semantic colors reference Tailwind color variables via var()
  - Media query-based dark mode for canvas colors
- Migrate all 16 components from direct Tailwind colors to semantic names
- Create cssVariables.ts utility for Konva canvas color access
- Update KonvaComponents to use CSS variables dynamically
- Replace @apply with CSS variables in index.css for v4 compatibility
- Remove unused designTokens.ts file
- Improve light mode contrast with gray-300 app background
- Adjust canvas and info box backgrounds to gray-200

Benefits:
- Easy theme customization by updating App.css @theme block
- Consistent semantic naming across all components
- Proper dark mode support via media queries
- No visual regressions, all colors maintained

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 21:43:36 +01:00
Jan-Henrik Bruhn
38afe33826 style: Apply linter formatting to useMachineStore
Auto-formatted by linter:
- Single quotes → double quotes
- Line wrapping for better readability

No logic changes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 12:27:34 +01:00
Jan-Henrik Bruhn
a6868ae5ec chore: Remove unused useBrotherMachine hook
This hook was replaced by useMachineStore (Zustand) and is no longer
used anywhere in the codebase. All functionality has been migrated to
the centralized machine store.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 12:26:49 +01:00
Jan-Henrik Bruhn
bc46fe0015 fix: Calculate time correctly per color block using Brother formula
Implemented proper time calculation matching the Brother app algorithm:
- 150ms per stitch + 3000ms startup time per color block
- Calculate total and elapsed time by summing across color blocks
- This fixes the "999 seconds" issue by calculating time accurately

Created timeCalculation utility with:
- convertStitchesToMinutes: Convert stitches to minutes using PP1 formula
- calculatePatternTime: Calculate total/elapsed time per color blocks

Updated ProgressMonitor to show:
- Total Time (calculated from all color blocks)
- Elapsed Time / Total Time (based on current stitch position)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 12:19:24 +01:00
Jan-Henrik Bruhn
f2d05c2714 fix: Fall back to PEN stitch count when machine reports 0 total stitches
When the machine reports 0 total stitches in patternInfo, fall back to
using the PEN data stitch count (penStitches.stitches.length) for UI
display. This ensures progress percentage and stitch counts display
correctly even when the machine hasn't fully initialized pattern info.

Updated ProgressMonitor to use derived totalStitches value that prefers
patternInfo.totalStitches but falls back to PEN data when needed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 12:14:41 +01:00
Jan-Henrik Bruhn
467eb9df95 refactor: Derive patternUploaded from patternInfo instead of syncing state
Removed redundant patternUploaded state from PatternStore and replaced
it with a derived selector usePatternUploaded() in MachineStore that
computes it from patternInfo !== null.

This eliminates duplicate state, removes the need for synchronization
logic, and ensures a single source of truth for pattern upload status.

Updated all components (App, LeftSidebar, FileUpload, PatternCanvas,
WorkflowStepper) to use the derived selector.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 11:25:26 +01:00
Jan-Henrik Bruhn
c81930d1b7 refactor: Break down App.tsx into focused subcomponents
Extracted App.tsx (469 lines → 91 lines) into 5 new components:
- ErrorPopover: Displays error details with solutions (84 lines)
- AppHeader: Machine status, workflow stepper, errors (207 lines)
- ConnectionPrompt: Connect button or browser warning (67 lines)
- LeftSidebar: Conditional rendering of controls (42 lines)
- PatternPreviewPlaceholder: Empty state for preview (46 lines)

This improves code organization, maintainability, and reusability.
Each component now has a single, clear responsibility.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 11:16:59 +01:00
Jan-Henrik Bruhn
e07d6b9a6f refactor: Extract PatternInfo component to eliminate duplication
Created shared PatternInfo component for displaying pattern statistics
(size, stitch count, colors) used in both FileUpload and PatternSummaryCard.
Reduces code duplication and ensures consistency across the UI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-17 00:23:56 +01:00