mirror of
https://github.com/maziggy/bambuddy.git
synced 2026-10-17 19:36:28 +02:00
Improved printer card size selector
This commit is contained in:
@@ -23,8 +23,6 @@ import {
|
||||
Pencil,
|
||||
ArrowUp,
|
||||
ArrowDown,
|
||||
LayoutGrid,
|
||||
LayoutList,
|
||||
Layers,
|
||||
Video,
|
||||
Search,
|
||||
@@ -37,7 +35,6 @@ import {
|
||||
Fan,
|
||||
Wind,
|
||||
AirVent,
|
||||
Minus,
|
||||
Download,
|
||||
} from 'lucide-react';
|
||||
|
||||
@@ -862,6 +859,7 @@ function PrinterCard({
|
||||
hideIfDisconnected,
|
||||
maintenanceInfo,
|
||||
viewMode = 'expanded',
|
||||
cardSize = 2,
|
||||
amsThresholds,
|
||||
spoolmanEnabled = false,
|
||||
hasUnlinkedSpools = false,
|
||||
@@ -870,6 +868,7 @@ function PrinterCard({
|
||||
hideIfDisconnected?: boolean;
|
||||
maintenanceInfo?: PrinterMaintenanceInfo;
|
||||
viewMode?: ViewMode;
|
||||
cardSize?: number;
|
||||
amsThresholds?: {
|
||||
humidityGood: number;
|
||||
humidityFair: number;
|
||||
@@ -1209,11 +1208,40 @@ function PrinterCard({
|
||||
return null;
|
||||
}
|
||||
|
||||
// Size-based styling helpers
|
||||
const getImageSize = () => {
|
||||
switch (cardSize) {
|
||||
case 1: return 'w-10 h-10';
|
||||
case 2: return 'w-14 h-14';
|
||||
case 3: return 'w-16 h-16';
|
||||
case 4: return 'w-20 h-20';
|
||||
default: return 'w-14 h-14';
|
||||
}
|
||||
};
|
||||
const getTitleSize = () => {
|
||||
switch (cardSize) {
|
||||
case 1: return 'text-base truncate';
|
||||
case 2: return 'text-lg';
|
||||
case 3: return 'text-xl';
|
||||
case 4: return 'text-2xl';
|
||||
default: return 'text-lg';
|
||||
}
|
||||
};
|
||||
const getSpacing = () => {
|
||||
switch (cardSize) {
|
||||
case 1: return 'mb-2';
|
||||
case 2: return 'mb-4';
|
||||
case 3: return 'mb-5';
|
||||
case 4: return 'mb-6';
|
||||
default: return 'mb-4';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Card className="relative">
|
||||
<CardContent>
|
||||
<CardContent className={cardSize >= 3 ? 'p-5' : ''}>
|
||||
{/* Header */}
|
||||
<div className={viewMode === 'compact' ? 'mb-2' : 'mb-4'}>
|
||||
<div className={getSpacing()}>
|
||||
{/* Top row: Image, Name, Menu */}
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<div className="flex items-center gap-3 min-w-0 flex-1">
|
||||
@@ -1221,11 +1249,11 @@ function PrinterCard({
|
||||
<img
|
||||
src={getPrinterImage(printer.model)}
|
||||
alt={printer.model || 'Printer'}
|
||||
className={`object-contain rounded-lg bg-bambu-dark flex-shrink-0 ${viewMode === 'compact' ? 'w-10 h-10' : 'w-14 h-14'}`}
|
||||
className={`object-contain rounded-lg bg-bambu-dark flex-shrink-0 ${getImageSize()}`}
|
||||
/>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<h3 className={`font-semibold text-white ${viewMode === 'compact' ? 'text-base truncate' : 'text-lg'}`}>{printer.name}</h3>
|
||||
<h3 className={`font-semibold text-white ${getTitleSize()}`}>{printer.name}</h3>
|
||||
{/* Connection indicator dot for compact mode */}
|
||||
{viewMode === 'compact' && (
|
||||
<div
|
||||
@@ -3568,14 +3596,13 @@ export function PrintersPage() {
|
||||
const [sortAsc, setSortAsc] = useState<boolean>(() => {
|
||||
return localStorage.getItem('printerSortAsc') !== 'false';
|
||||
});
|
||||
const [viewMode, setViewMode] = useState<ViewMode>(() => {
|
||||
return (localStorage.getItem('printerViewMode') as ViewMode) || 'expanded';
|
||||
});
|
||||
// Card size: 1=small, 2=medium, 3=large, 4=xl
|
||||
const [cardSize, setCardSize] = useState<number>(() => {
|
||||
const saved = localStorage.getItem('printerCardSize');
|
||||
return saved ? parseInt(saved, 10) : 2; // Default to medium
|
||||
});
|
||||
// Derive viewMode from cardSize: S=compact, M/L/XL=expanded
|
||||
const viewMode: ViewMode = cardSize === 1 ? 'compact' : 'expanded';
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const { data: printers, isLoading } = useQuery({
|
||||
@@ -3679,26 +3706,14 @@ export function PrintersPage() {
|
||||
localStorage.setItem('printerSortAsc', String(newAsc));
|
||||
};
|
||||
|
||||
const toggleViewMode = () => {
|
||||
const newMode = viewMode === 'expanded' ? 'compact' : 'expanded';
|
||||
setViewMode(newMode);
|
||||
localStorage.setItem('printerViewMode', newMode);
|
||||
};
|
||||
|
||||
const changeCardSize = (delta: number) => {
|
||||
const newSize = Math.max(1, Math.min(4, cardSize + delta));
|
||||
setCardSize(newSize);
|
||||
localStorage.setItem('printerCardSize', String(newSize));
|
||||
};
|
||||
|
||||
// Grid classes based on card size (1=small, 2=medium, 3=large, 4=xl)
|
||||
const getGridClasses = () => {
|
||||
switch (cardSize) {
|
||||
case 1: return 'grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5';
|
||||
case 2: return 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3';
|
||||
case 3: return 'grid-cols-1 md:grid-cols-2';
|
||||
case 4: return 'grid-cols-1 max-w-3xl';
|
||||
default: return 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3';
|
||||
case 1: return 'grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5'; // S: many small cards
|
||||
case 2: return 'grid-cols-1 md:grid-cols-2 xl:grid-cols-3'; // M: medium cards
|
||||
case 3: return 'grid-cols-1 lg:grid-cols-2'; // L: large cards, 2 columns max
|
||||
case 4: return 'grid-cols-1'; // XL: single column, full width
|
||||
default: return 'grid-cols-1 md:grid-cols-2 xl:grid-cols-3';
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3797,40 +3812,33 @@ export function PrintersPage() {
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* View mode toggle */}
|
||||
<button
|
||||
onClick={toggleViewMode}
|
||||
className="p-1.5 rounded-lg hover:bg-bambu-dark-tertiary transition-colors"
|
||||
title={viewMode === 'expanded' ? 'Switch to compact view' : 'Switch to expanded view'}
|
||||
>
|
||||
{viewMode === 'expanded' ? (
|
||||
<LayoutList className="w-5 h-5 text-bambu-gray" />
|
||||
) : (
|
||||
<LayoutGrid className="w-5 h-5 text-bambu-gray" />
|
||||
)}
|
||||
</button>
|
||||
|
||||
{/* Card size control */}
|
||||
<div className="flex items-center gap-1 bg-bambu-dark rounded-lg border border-bambu-dark-tertiary">
|
||||
<button
|
||||
onClick={() => changeCardSize(-1)}
|
||||
disabled={cardSize <= 1}
|
||||
className="p-1.5 rounded-l-lg hover:bg-bambu-dark-tertiary transition-colors disabled:opacity-30 disabled:cursor-not-allowed"
|
||||
title="Smaller cards"
|
||||
>
|
||||
<Minus className="w-4 h-4 text-bambu-gray" />
|
||||
</button>
|
||||
<span className="text-xs text-bambu-gray w-6 text-center font-medium">
|
||||
{cardSizeLabels[cardSize - 1]}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => changeCardSize(1)}
|
||||
disabled={cardSize >= 4}
|
||||
className="p-1.5 rounded-r-lg hover:bg-bambu-dark-tertiary transition-colors disabled:opacity-30 disabled:cursor-not-allowed"
|
||||
title="Larger cards"
|
||||
>
|
||||
<Plus className="w-4 h-4 text-bambu-gray" />
|
||||
</button>
|
||||
{/* Card size selector */}
|
||||
<div className="flex items-center bg-bambu-dark rounded-lg border border-bambu-dark-tertiary">
|
||||
{cardSizeLabels.map((label, index) => {
|
||||
const size = index + 1;
|
||||
const isSelected = cardSize === size;
|
||||
return (
|
||||
<button
|
||||
key={label}
|
||||
onClick={() => {
|
||||
setCardSize(size);
|
||||
localStorage.setItem('printerCardSize', String(size));
|
||||
}}
|
||||
className={`px-2 py-1.5 text-xs font-medium transition-colors ${
|
||||
index === 0 ? 'rounded-l-lg' : ''
|
||||
} ${
|
||||
index === cardSizeLabels.length - 1 ? 'rounded-r-lg' : ''
|
||||
} ${
|
||||
isSelected
|
||||
? 'bg-bambu-green text-white'
|
||||
: 'text-bambu-gray hover:bg-bambu-dark-tertiary hover:text-white'
|
||||
}`}
|
||||
title={`${label === 'S' ? 'Small' : label === 'M' ? 'Medium' : label === 'L' ? 'Large' : 'Extra large'} cards`}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div className="w-px h-6 bg-bambu-dark-tertiary" />
|
||||
@@ -3925,6 +3933,7 @@ export function PrintersPage() {
|
||||
hideIfDisconnected={hideDisconnected}
|
||||
maintenanceInfo={maintenanceByPrinter[printer.id]}
|
||||
viewMode={viewMode}
|
||||
cardSize={cardSize}
|
||||
amsThresholds={settings ? {
|
||||
humidityGood: Number(settings.ams_humidity_good) || 40,
|
||||
humidityFair: Number(settings.ams_humidity_fair) || 60,
|
||||
@@ -3949,6 +3958,7 @@ export function PrintersPage() {
|
||||
hideIfDisconnected={hideDisconnected}
|
||||
maintenanceInfo={maintenanceByPrinter[printer.id]}
|
||||
viewMode={viewMode}
|
||||
cardSize={cardSize}
|
||||
spoolmanEnabled={spoolmanEnabled}
|
||||
hasUnlinkedSpools={hasUnlinkedSpools}
|
||||
amsThresholds={settings ? {
|
||||
|
||||
Reference in New Issue
Block a user