Compare commits

..

No commits in common. "ea879640a2e3581697b91427dd8be271dfb03b96" and "93ca7ea406b8a5751fa277a5ce6c97cff6b87920" have entirely different histories.

12 changed files with 28 additions and 98 deletions

View file

@ -4,19 +4,18 @@
"rsc": false, "rsc": false,
"tsx": true, "tsx": true,
"tailwind": { "tailwind": {
"config": "tailwind.config.js", "config": "",
"css": "src/App.css", "css": "src/App.css",
"baseColor": "slate", "baseColor": "slate",
"cssVariables": true, "cssVariables": true,
"prefix": "" "prefix": ""
}, },
"iconLibrary": "lucide",
"aliases": { "aliases": {
"components": "@/components", "components": "src/components",
"utils": "@/lib/utils", "utils": "src/lib/utils",
"ui": "@/components/ui", "ui": "src/components/ui",
"lib": "@/lib", "lib": "src/lib",
"hooks": "@/hooks" "hooks": "src/hooks"
}, },
"registries": {} "iconLibrary": "lucide"
} }

10
package-lock.json generated
View file

@ -32,7 +32,6 @@
"react-konva": "^19.2.1", "react-konva": "^19.2.1",
"tailwind-merge": "^3.4.0", "tailwind-merge": "^3.4.0",
"tailwindcss": "^4.1.17", "tailwindcss": "^4.1.17",
"tailwindcss-animate": "^1.0.7",
"tw-animate-css": "^1.4.0", "tw-animate-css": "^1.4.0",
"update-electron-app": "^3.1.2", "update-electron-app": "^3.1.2",
"zustand": "^5.0.9" "zustand": "^5.0.9"
@ -16686,15 +16685,6 @@
"integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/tailwindcss-animate": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz",
"integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==",
"license": "MIT",
"peerDependencies": {
"tailwindcss": ">=3.0.0 || insiders"
}
},
"node_modules/tapable": { "node_modules/tapable": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz",

View file

@ -45,7 +45,6 @@
"react-konva": "^19.2.1", "react-konva": "^19.2.1",
"tailwind-merge": "^3.4.0", "tailwind-merge": "^3.4.0",
"tailwindcss": "^4.1.17", "tailwindcss": "^4.1.17",
"tailwindcss-animate": "^1.0.7",
"tw-animate-css": "^1.4.0", "tw-animate-css": "^1.4.0",
"update-electron-app": "^3.1.2", "update-electron-app": "^3.1.2",
"zustand": "^5.0.9" "zustand": "^5.0.9"

View file

@ -1,6 +1,4 @@
@import "tailwindcss"; @import "tailwindcss";
@plugin "tailwindcss-animate";
@import "tw-animate-css"; @import "tw-animate-css";
/* ============================================ /* ============================================

View file

@ -256,34 +256,16 @@ export function FileUpload() {
onChange={handleFileChange} onChange={handleFileChange}
id="file-input" id="file-input"
className="hidden" className="hidden"
disabled={ disabled={isLoading || patternUploaded || isUploading}
isLoading ||
patternUploaded ||
isUploading ||
(uploadProgress > 0 && !patternUploaded)
}
/> />
<Button <Button
asChild={ asChild={!fileService.hasNativeDialogs()}
!fileService.hasNativeDialogs() &&
!(
isLoading ||
patternUploaded ||
isUploading ||
(uploadProgress > 0 && !patternUploaded)
)
}
onClick={ onClick={
fileService.hasNativeDialogs() fileService.hasNativeDialogs()
? () => handleFileChange() ? () => handleFileChange()
: undefined : undefined
} }
disabled={ disabled={isLoading || patternUploaded || isUploading}
isLoading ||
patternUploaded ||
isUploading ||
(uploadProgress > 0 && !patternUploaded)
}
variant="outline" variant="outline"
className="flex-[2]" className="flex-[2]"
> >
@ -307,10 +289,7 @@ export function FileUpload() {
)} )}
</> </>
) : ( ) : (
<label <label htmlFor="file-input" className="flex items-center gap-2">
htmlFor="file-input"
className="flex items-center gap-2 cursor-pointer"
>
{isLoading ? ( {isLoading ? (
<> <>
<Loader2 className="w-3.5 h-3.5 animate-spin" /> <Loader2 className="w-3.5 h-3.5 animate-spin" />
@ -407,8 +386,11 @@ export function FileUpload() {
)} )}
{pesData && boundsCheck.error && ( {pesData && boundsCheck.error && (
<Alert variant="destructive"> <Alert
<AlertDescription> variant="destructive"
className="bg-danger-100 dark:bg-danger-900/20 border-danger-200 dark:border-danger-800"
>
<AlertDescription className="text-danger-800 dark:text-danger-200 text-sm">
<strong>Pattern too large:</strong> {boundsCheck.error} <strong>Pattern too large:</strong> {boundsCheck.error}
</AlertDescription> </AlertDescription>
</Alert> </Alert>

View file

@ -117,13 +117,7 @@ export function PatternInfo({
.join(" "); .join(" ");
// Secondary metadata: chart and description // Secondary metadata: chart and description
// Only show chart if it's different from catalogNumber const secondaryMetadata = [color.chart, color.description]
const secondaryMetadata = [
color.chart && color.chart !== color.catalogNumber
? color.chart
: null,
color.description,
]
.filter(Boolean) .filter(Boolean)
.join(" "); .join(" ");

View file

@ -281,13 +281,8 @@ export function ProgressMonitor() {
.join(" "); .join(" ");
// Secondary metadata: chart and description // Secondary metadata: chart and description
// Only show chart if it's different from catalogNumber
const secondaryMetadata = [ const secondaryMetadata = [
block.threadChart && block.threadChart,
block.threadChart !==
block.threadCatalogNumber
? block.threadChart
: null,
block.threadDescription, block.threadDescription,
] ]
.filter(Boolean) .filter(Boolean)

View file

@ -65,33 +65,16 @@ export function PatternCanvasSkeleton() {
export function PatternInfoSkeleton() { export function PatternInfoSkeleton() {
return ( return (
<div className="mb-3"> <div className="mt-4">
{/* Three column grid matching PatternInfo stats */} <SkeletonLoader className="h-6 w-40 mb-4" variant="text" />
<div className="grid grid-cols-3 gap-2 text-xs mb-2"> <div className="bg-gray-200 dark:bg-gray-900 p-4 rounded-lg space-y-3">
{[1, 2, 3].map((i) => ( {[1, 2, 3, 4].map((i) => (
<div key={i} className="bg-gray-200 dark:bg-gray-700/50 p-2 rounded"> <div key={i} className="flex justify-between">
<SkeletonLoader className="h-3 w-12 mb-1" variant="text" /> <SkeletonLoader className="h-4 w-24" variant="text" />
<SkeletonLoader className="h-4 w-16" variant="text" /> <SkeletonLoader className="h-4 w-32" variant="text" />
</div> </div>
))} ))}
</div> </div>
{/* Separator */}
<div className="h-px bg-gray-200 dark:bg-gray-700 mb-3" />
{/* Color swatches row */}
<div className="flex items-center gap-2 mb-2">
<SkeletonLoader className="h-3 w-12" variant="text" />
<div className="flex gap-1">
{[1, 2, 3, 4, 5].map((i) => (
<SkeletonLoader
key={i}
className="w-3 h-3 rounded-full"
variant="circle"
/>
))}
</div>
</div>
</div> </div>
); );
} }

View file

@ -10,7 +10,7 @@ const alertVariants = cva(
variant: { variant: {
default: "bg-card text-card-foreground", default: "bg-card text-card-foreground",
destructive: destructive:
"bg-danger-100 dark:bg-danger-900/20 border-danger-200 dark:border-danger-800 text-danger-900 dark:text-danger-100 [&>svg]:text-current *:data-[slot=alert-description]:text-danger-900 dark:*:data-[slot=alert-description]:text-danger-100", "text-destructive bg-card [&>svg]:text-current *:data-[slot=alert-description]:text-destructive/90",
}, },
}, },
defaultVariants: { defaultVariants: {

View file

@ -1,4 +1,4 @@
import { clsx, type ClassValue } from "clsx"; import { type ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge"; import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) { export function cn(...inputs: ClassValue[]) {

View file

@ -1,10 +1,6 @@
{ {
"extends": "./tsconfig.json", "extends": "./tsconfig.json",
"compilerOptions": { "compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"module": "commonjs", "module": "commonjs",
"outDir": "dist-electron", "outDir": "dist-electron",
"types": ["node"] "types": ["node"]

View file

@ -3,11 +3,5 @@
"references": [ "references": [
{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" } { "path": "./tsconfig.node.json" }
], ]
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
} }