Fix ESLint configuration and resolve all linting issues

- Rename eslint.config.js to eslint.config.mjs to support ES modules
- Remove unused parameters from interface implementations
- Fix refs access during render in WorkflowStepper by removing redundant check
- Wrap colorBlocks computation in useMemo to fix exhaustive-deps warning

All linting errors and warnings are now resolved.

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Henrik Bruhn 2025-12-11 14:11:35 +01:00
parent 75ec5c49a9
commit 3516b609f6
6 changed files with 47 additions and 47 deletions

View file

@ -1,4 +1,4 @@
import { useRef, useEffect, useState } from "react"; import { useRef, useEffect, useState, useMemo } from "react";
import { import {
CheckCircleIcon, CheckCircleIcon,
ArrowRightIcon, ArrowRightIcon,
@ -58,53 +58,53 @@ export function ProgressMonitor({
: 0; : 0;
// Calculate color block information from pesData // Calculate color block information from pesData
const colorBlocks = pesData const colorBlocks = useMemo(() => {
? (() => { if (!pesData) return [];
const blocks: Array<{
colorIndex: number;
threadHex: string;
startStitch: number;
endStitch: number;
stitchCount: number;
threadCatalogNumber: string | null;
threadBrand: string | null;
threadDescription: string | null;
threadChart: string | null;
}> = [];
let currentColorIndex = pesData.stitches[0]?.[3] ?? 0; const blocks: Array<{
let blockStartStitch = 0; colorIndex: number;
threadHex: string;
startStitch: number;
endStitch: number;
stitchCount: number;
threadCatalogNumber: string | null;
threadBrand: string | null;
threadDescription: string | null;
threadChart: string | null;
}> = [];
for (let i = 0; i < pesData.stitches.length; i++) { let currentColorIndex = pesData.stitches[0]?.[3] ?? 0;
const stitchColorIndex = pesData.stitches[i][3]; let blockStartStitch = 0;
// When color changes, save the previous block for (let i = 0; i < pesData.stitches.length; i++) {
if ( const stitchColorIndex = pesData.stitches[i][3];
stitchColorIndex !== currentColorIndex ||
i === pesData.stitches.length - 1
) {
const endStitch = i === pesData.stitches.length - 1 ? i + 1 : i;
const thread = pesData.threads[currentColorIndex];
blocks.push({
colorIndex: currentColorIndex,
threadHex: thread?.hex || "#000000",
threadCatalogNumber: thread?.catalogNumber ?? null,
threadBrand: thread?.brand ?? null,
threadDescription: thread?.description ?? null,
threadChart: thread?.chart ?? null,
startStitch: blockStartStitch,
endStitch: endStitch,
stitchCount: endStitch - blockStartStitch,
});
currentColorIndex = stitchColorIndex; // When color changes, save the previous block
blockStartStitch = i; if (
} stitchColorIndex !== currentColorIndex ||
} i === pesData.stitches.length - 1
) {
const endStitch = i === pesData.stitches.length - 1 ? i + 1 : i;
const thread = pesData.threads[currentColorIndex];
blocks.push({
colorIndex: currentColorIndex,
threadHex: thread?.hex || "#000000",
threadCatalogNumber: thread?.catalogNumber ?? null,
threadBrand: thread?.brand ?? null,
threadDescription: thread?.description ?? null,
threadChart: thread?.chart ?? null,
startStitch: blockStartStitch,
endStitch: endStitch,
stitchCount: endStitch - blockStartStitch,
});
return blocks; currentColorIndex = stitchColorIndex;
})() blockStartStitch = i;
: []; }
}
return blocks;
}, [pesData]);
// Determine current color block based on current stitch // Determine current color block based on current stitch
const currentStitch = sewingProgress?.currentStitch || 0; const currentStitch = sewingProgress?.currentStitch || 0;

View file

@ -375,7 +375,7 @@ export function WorkflowStepper({
</div> </div>
{/* Popover */} {/* Popover */}
{showPopover && popoverStep !== null && stepRefs.current[popoverStep] && ( {showPopover && popoverStep !== null && (
<div <div
ref={popoverRef} ref={popoverRef}
className="absolute top-full mt-4 left-1/2 transform -translate-x-1/2 w-full max-w-xl z-50 animate-fadeIn" className="absolute top-full mt-4 left-1/2 transform -translate-x-1/2 w-full max-w-xl z-50 animate-fadeIn"

View file

@ -23,7 +23,7 @@ export class BrowserFileService implements IFileService {
}); });
} }
async saveFileDialog(_data: Uint8Array, _defaultName: string): Promise<void> { async saveFileDialog(): Promise<void> {
// No-op in browser - could implement download if needed in the future // No-op in browser - could implement download if needed in the future
console.warn('saveFileDialog not implemented in browser'); console.warn('saveFileDialog not implemented in browser');
} }

View file

@ -4,7 +4,7 @@ import type { IFileService } from '../interfaces/IFileService';
* Electron implementation of file service using native dialogs via IPC * Electron implementation of file service using native dialogs via IPC
*/ */
export class ElectronFileService implements IFileService { export class ElectronFileService implements IFileService {
async openFileDialog(_options: { accept: string }): Promise<File | null> { async openFileDialog(): Promise<File | null> {
if (!window.electronAPI) { if (!window.electronAPI) {
throw new Error('Electron API not available'); throw new Error('Electron API not available');
} }

View file

@ -68,7 +68,7 @@ export class ElectronStorageService implements IStorageService {
} }
} }
async hasPattern(_uuid: string): Promise<boolean> { async hasPattern(): Promise<boolean> {
// Since this is async in Electron, we can't truly implement this synchronously // Since this is async in Electron, we can't truly implement this synchronously
// Returning false as a safe default // Returning false as a safe default
console.warn('[ElectronStorage] hasPattern called synchronously, returning false'); console.warn('[ElectronStorage] hasPattern called synchronously, returning false');