- {((pesData.bounds.maxX - pesData.bounds.minX) / 10).toFixed(1)} x{' '}
- {((pesData.bounds.maxY - pesData.bounds.minY) / 10).toFixed(1)} mm
-
void;
+ canDelete: boolean;
+ isDeleting: boolean;
+}
+
+export function PatternSummaryCard({
+ pesData,
+ fileName,
+ onDeletePattern,
+ canDelete,
+ isDeleting
+}: PatternSummaryCardProps) {
+ return (
+
+
+
+
+
Active Pattern
+
+ {fileName}
+
+
+
+
+
+
+ Size
+
+ {((pesData.bounds.maxX - pesData.bounds.minX) / 10).toFixed(1)} x{' '}
+ {((pesData.bounds.maxY - pesData.bounds.minY) / 10).toFixed(1)} mm
+
+
+
+ Stitches
+
+ {pesData.stitchCount.toLocaleString()}
+
+
+
+
+
+
Colors:
+
+ {pesData.threads.slice(0, 8).map((thread, idx) => (
+
+ ))}
+ {pesData.colorCount > 8 && (
+
+ +{pesData.colorCount - 8}
+
+ )}
+
+
+
+ {canDelete && (
+
+ {isDeleting ? (
+ <>
+
+
+
+
+ Deleting...
+ >
+ ) : (
+ <>
+
+ Delete Pattern
+ >
+ )}
+
+ )}
+
+ );
+}
diff --git a/src/components/ProgressMonitor.tsx b/src/components/ProgressMonitor.tsx
index d10e596..87a64de 100644
--- a/src/components/ProgressMonitor.tsx
+++ b/src/components/ProgressMonitor.tsx
@@ -6,7 +6,8 @@ import {
CheckBadgeIcon,
ClockIcon,
PauseCircleIcon,
- ExclamationCircleIcon
+ ExclamationCircleIcon,
+ ChartBarIcon
} from '@heroicons/react/24/solid';
import type { PatternInfo, SewingProgress } from '../types/machine';
import { MachineStatus } from '../types/machine';
@@ -14,7 +15,6 @@ import type { PesPatternData } from '../utils/pystitchConverter';
import {
canStartSewing,
canStartMaskTrace,
- canDeletePattern,
canResumeSewing,
getStateVisualInfo
} from '../utils/machineStateHelpers';
@@ -39,8 +39,6 @@ export function ProgressMonitor({
onStartMaskTrace,
onStartSewing,
onResumeSewing,
- onDeletePattern,
- isDeleting = false,
}: ProgressMonitorProps) {
// State indicators
const isMaskTraceComplete = machineStatus === MachineStatus.MASK_TRACE_COMPLETE;
@@ -93,163 +91,105 @@ export function ProgressMonitor({
);
const stateIndicatorColors = {
- idle: 'bg-blue-50 dark:bg-blue-900/20 border-l-blue-600',
- info: 'bg-blue-50 dark:bg-blue-900/20 border-l-blue-600',
- active: 'bg-yellow-50 dark:bg-yellow-900/20 border-l-yellow-500',
- waiting: 'bg-yellow-50 dark:bg-yellow-900/20 border-l-yellow-500',
- warning: 'bg-yellow-50 dark:bg-yellow-900/20 border-l-yellow-500',
- complete: 'bg-green-50 dark:bg-green-900/20 border-l-green-600',
- success: 'bg-green-50 dark:bg-green-900/20 border-l-green-600',
- interrupted: 'bg-red-50 dark:bg-red-900/20 border-l-red-600',
- error: 'bg-red-50 dark:bg-red-900/20 border-l-red-600',
- danger: 'bg-red-50 dark:bg-red-900/20 border-l-red-600',
+ idle: 'bg-blue-50 dark:bg-blue-900/20 border-blue-600',
+ info: 'bg-blue-50 dark:bg-blue-900/20 border-blue-600',
+ active: 'bg-yellow-50 dark:bg-yellow-900/20 border-yellow-500',
+ waiting: 'bg-yellow-50 dark:bg-yellow-900/20 border-yellow-500',
+ warning: 'bg-yellow-50 dark:bg-yellow-900/20 border-yellow-500',
+ complete: 'bg-green-50 dark:bg-green-900/20 border-green-600',
+ success: 'bg-green-50 dark:bg-green-900/20 border-green-600',
+ interrupted: 'bg-red-50 dark:bg-red-900/20 border-red-600',
+ error: 'bg-red-50 dark:bg-red-900/20 border-red-600',
+ danger: 'bg-red-50 dark:bg-red-900/20 border-red-600',
};
return (
-
-
Sewing Progress
-
-
- {/* Left Column - Pattern Info & Progress */}
-
- {patternInfo && (
-
-
-
- Total Stitches
- {patternInfo.totalStitches.toLocaleString()}
-
-
- Est. Time
-
- {Math.floor(patternInfo.totalTime / 60)}:{String(patternInfo.totalTime % 60).padStart(2, '0')}
-
-
-
- Speed
- {patternInfo.speed} spm
-
-
-
- )}
-
+
+
+
+
+
Sewing Progress
{sewingProgress && (
-
-
- Progress
- {progressPercent.toFixed(1)}%
-
-
-
-
-
- Current Stitch
-
- {sewingProgress.currentStitch.toLocaleString()} / {patternInfo?.totalStitches.toLocaleString() || 0}
-
-
-
- Time Elapsed
-
- {Math.floor(sewingProgress.currentTime / 60)}:{String(sewingProgress.currentTime % 60).padStart(2, '0')}
-
-
-
-
+
+ {progressPercent.toFixed(1)}% complete
+
)}
+
+
- {/* State Visual Indicator */}
- {patternInfo && (() => {
- const iconMap = {
- ready:
,
- active:
,
- waiting:
,
- complete:
,
- interrupted:
,
- error:
- };
-
- return (
-
-
- {iconMap[stateVisual.iconName]}
-
-
-
{stateVisual.label}
-
{stateVisual.description}
-
-
- );
- })()}
-
- {/* Action buttons */}
-
- {/* Resume has highest priority when available */}
- {canResumeSewing(machineStatus) && (
-
-
- Resume Sewing
-
- )}
-
- {/* Start Sewing - primary action */}
- {canStartSewing(machineStatus) && !canResumeSewing(machineStatus) && (
-
- Start Sewing
-
- )}
-
- {/* Start Mask Trace - secondary action */}
- {canStartMaskTrace(machineStatus) && (
-
- {isMaskTraceComplete ? 'Trace Again' : 'Start Mask Trace'}
-
- )}
-
- {/* Delete - destructive action, always last */}
- {patternInfo && canDeletePattern(machineStatus) && (
-
- {isDeleting ? (
- <>
-
-
-
-
- Deleting...
- >
- ) : (
- 'Delete Pattern'
- )}
-
- )}
+ {/* Pattern Info */}
+ {patternInfo && (
+
+
+ Total Stitches
+ {patternInfo.totalStitches.toLocaleString()}
+
+
+ Est. Time
+
+ {Math.floor(patternInfo.totalTime / 60)}:{String(patternInfo.totalTime % 60).padStart(2, '0')}
+
+
+
+ Speed
+ {patternInfo.speed} spm
+ )}
- {/* Right Column - Color Blocks */}
-
- {colorBlocks.length > 0 && (
-
-
Color Blocks
-
+ {/* Progress Bar */}
+ {sewingProgress && (
+
+
+
+
+
+ Current Stitch
+
+ {sewingProgress.currentStitch.toLocaleString()} / {patternInfo?.totalStitches.toLocaleString() || 0}
+
+
+
+ Time Elapsed
+
+ {Math.floor(sewingProgress.currentTime / 60)}:{String(sewingProgress.currentTime % 60).padStart(2, '0')}
+
+
+
+
+ )}
+
+ {/* State Visual Indicator */}
+ {patternInfo && (() => {
+ const iconMap = {
+ ready:
,
+ active:
,
+ waiting:
,
+ complete:
,
+ interrupted:
,
+ error:
+ };
+
+ return (
+
+
+ {iconMap[stateVisual.iconName]}
+
+
+
{stateVisual.label}
+
{stateVisual.description}
+
+
+ );
+ })()}
+
+ {/* Color Blocks */}
+ {colorBlocks.length > 0 && (
+
+
Color Blocks
+
{colorBlocks.map((block, index) => {
const isCompleted = currentStitch >= block.endStitch;
const isCurrent = index === currentBlockIndex;
@@ -265,23 +205,23 @@ export function ProgressMonitor({
return (
-
- {/* Larger color swatch with better visibility */}
+
+ {/* Color swatch */}
-
+
Thread {block.colorIndex + 1}
-
+
{block.stitchCount.toLocaleString()} stitches
{/* Status icon */}
{isCompleted ? (
-
+
) : isCurrent ? (
-
+
) : (
-
+
)}
{/* Progress bar for current block */}
{isCurrent && (
-
+ )}
+
+ {/* Action buttons */}
+
+ {/* Resume has highest priority when available */}
+ {canResumeSewing(machineStatus) && (
+
+
+ Resume Sewing
+
+ )}
+
+ {/* Start Sewing - primary action */}
+ {canStartSewing(machineStatus) && !canResumeSewing(machineStatus) && (
+
+ Start Sewing
+
+ )}
+
+ {/* Start Mask Trace - secondary action */}
+ {canStartMaskTrace(machineStatus) && (
+
+ {isMaskTraceComplete ? 'Trace Again' : 'Start Mask Trace'}
+
+ )}
);