update gpu-switch-mode-indicator.tsx

This commit is contained in:
MacRimi
2026-04-09 15:29:41 +02:00
parent af63b71ab8
commit 3cede88a3d
2 changed files with 333 additions and 331 deletions

View File

@@ -31,206 +31,249 @@ export function GpuSwitchModeIndicator({
} }
} }
// Compact version for GPU card
if (compact) { if (compact) {
return ( return (
<div <div
className={cn( className={cn(
"flex items-center gap-2", "flex items-center gap-3",
isEditing && "cursor-pointer hover:opacity-80", isEditing && "cursor-pointer",
className className
)} )}
onClick={handleClick} onClick={handleClick}
> >
<svg <svg
viewBox="0 0 120 32" viewBox="0 0 140 40"
className="h-6 w-24" className="h-8 w-32"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
{/* GPU Chip Icon */} {/* GPU Chip Icon - LARGER and always colored */}
<g transform="translate(2, 4)"> <g transform="translate(0, 6)">
{/* Chip body */}
<rect <rect
x="2" x="2"
y="6" y="4"
width="16" width="22"
height="12" height="18"
rx="2" rx="3"
className="fill-muted-foreground/30 stroke-muted-foreground" className={cn(
strokeWidth="1" "transition-all duration-300",
isLxcActive
? "fill-blue-500/20 stroke-blue-500"
: isVmActive
? "fill-purple-500/20 stroke-purple-500"
: "fill-muted-foreground/20 stroke-muted-foreground"
)}
strokeWidth="1.5"
/> />
{/* Chip pins */} {/* Chip pins top */}
<line x1="5" y1="4" x2="5" y2="6" className="stroke-muted-foreground" strokeWidth="1" /> <line x1="7" y1="1" x2="7" y2="4" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="1.5" />
<line x1="10" y1="4" x2="10" y2="6" className="stroke-muted-foreground" strokeWidth="1" /> <line x1="13" y1="1" x2="13" y2="4" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="1.5" />
<line x1="15" y1="4" x2="15" y2="6" className="stroke-muted-foreground" strokeWidth="1" /> <line x1="19" y1="1" x2="19" y2="4" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="1.5" />
<line x1="5" y1="18" x2="5" y2="20" className="stroke-muted-foreground" strokeWidth="1" /> {/* Chip pins bottom */}
<line x1="10" y1="18" x2="10" y2="20" className="stroke-muted-foreground" strokeWidth="1" /> <line x1="7" y1="22" x2="7" y2="25" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="1.5" />
<line x1="15" y1="18" x2="15" y2="20" className="stroke-muted-foreground" strokeWidth="1" /> <line x1="13" y1="22" x2="13" y2="25" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="1.5" />
<text x="10" y="14" textAnchor="middle" className="fill-muted-foreground text-[6px] font-bold"> <line x1="19" y1="22" x2="19" y2="25" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="1.5" />
{/* GPU text */}
<text
x="13"
y="16"
textAnchor="middle"
className={cn(
"text-[7px] font-bold transition-all duration-300",
isLxcActive ? "fill-blue-500" : isVmActive ? "fill-purple-500" : "fill-muted-foreground"
)}
>
GPU GPU
</text> </text>
</g> </g>
{/* Connection lines from GPU */} {/* Connection line from GPU to switch */}
<g className="transition-all duration-300"> <line
{/* Main line from GPU */} x1="26"
<line y1="20"
x1="22" x2="48"
y1="16" y2="20"
x2="45" className={cn(
y2="16" "transition-all duration-300",
className="stroke-muted-foreground/50" isLxcActive ? "stroke-blue-500/60" : isVmActive ? "stroke-purple-500/60" : "stroke-muted-foreground/40"
strokeWidth="2" )}
/> strokeWidth="2"
/>
{/* Switch circle */}
<circle
cx="52"
cy="16"
r="6"
className={cn(
"transition-all duration-300",
isEditing ? "fill-amber-500/20 stroke-amber-500" : "fill-muted stroke-muted-foreground/50"
)}
strokeWidth="1.5"
/>
{/* LXC branch */} {/* Switch node - central junction */}
<line <circle
x1="58" cx="55"
y1="13" cy="20"
x2="75" r="6"
y2="8" className={cn(
className={cn( "transition-all duration-300",
"transition-all duration-300", isEditing
isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30" ? "fill-amber-500/30 stroke-amber-500"
)} : isLxcActive
strokeWidth={isLxcActive ? "2.5" : "1.5"} ? "fill-blue-500/30 stroke-blue-500"
/> : isVmActive
? "fill-purple-500/30 stroke-purple-500"
{/* VM branch */} : "fill-muted stroke-muted-foreground/50"
<line )}
x1="58" strokeWidth="2"
y1="19" />
x2="75"
y2="24" {/* Animated dot inside switch */}
className={cn( <circle
"transition-all duration-300", cx="55"
isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/30" cy="20"
)} r="2.5"
strokeWidth={isVmActive ? "2.5" : "1.5"} className={cn(
/> "transition-all duration-300",
</g> isEditing
? "fill-amber-500"
: isLxcActive
? "fill-blue-500"
: isVmActive
? "fill-purple-500"
: "fill-muted-foreground"
)}
/>
{/* LXC Icon - Container */} {/* LXC branch line */}
<g transform="translate(78, 2)"> <path
d="M 61 17 L 80 8"
fill="none"
className={cn(
"transition-all duration-300",
isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30"
)}
strokeWidth={isLxcActive ? "2.5" : "1.5"}
strokeLinecap="round"
/>
{/* VM branch line */}
<path
d="M 61 23 L 80 32"
fill="none"
className={cn(
"transition-all duration-300",
isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/30"
)}
strokeWidth={isVmActive ? "2.5" : "1.5"}
strokeLinecap="round"
/>
{/* LXC Icon - Container box */}
<g transform="translate(83, 0)">
<rect <rect
x="0" x="0"
y="0" y="0"
width="14" width="18"
height="12" height="14"
rx="1.5" rx="2"
className={cn( className={cn(
"transition-all duration-300", "transition-all duration-300",
isLxcActive ? "fill-blue-500/20 stroke-blue-500" : "fill-muted stroke-muted-foreground/40" isLxcActive ? "fill-blue-500/25 stroke-blue-500" : "fill-muted stroke-muted-foreground/30"
)} )}
strokeWidth="1.5" strokeWidth="1.5"
/> />
<line {/* Container layers */}
x1="0" <line x1="0" y1="5" x2="18" y2="5" className={cn(isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30")} strokeWidth="1" />
y1="4" <line x1="0" y1="9" x2="18" y2="9" className={cn(isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30")} strokeWidth="1" />
x2="14" {/* Dots */}
y2="4" <circle cx="4" cy="2.5" r="1" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
className={cn( <circle cx="4" cy="7" r="1" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
"transition-all duration-300", <circle cx="4" cy="11.5" r="1" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/40"
)}
strokeWidth="1"
/>
<line
x1="0"
y1="8"
x2="14"
y2="8"
className={cn(
"transition-all duration-300",
isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/40"
)}
strokeWidth="1"
/>
<text
x="7"
y="21"
textAnchor="middle"
className={cn(
"text-[7px] font-semibold transition-all duration-300",
isLxcActive ? "fill-blue-500" : "fill-muted-foreground/50"
)}
>
LXC
</text>
</g> </g>
{/* VM Icon - Monitor/PC */} {/* VM Icon - Monitor */}
<g transform="translate(78, 18)"> <g transform="translate(83, 24)">
<rect <rect
x="1" x="1"
y="0" y="0"
width="16"
height="10"
rx="1.5"
className={cn(
"transition-all duration-300",
isVmActive ? "fill-purple-500/25 stroke-purple-500" : "fill-muted stroke-muted-foreground/30"
)}
strokeWidth="1.5"
/>
{/* Screen shine */}
<rect
x="3"
y="2"
width="12" width="12"
height="8" height="6"
rx="1" rx="0.5"
className={cn( className={cn(isVmActive ? "fill-purple-500/30" : "fill-muted-foreground/10")}
"transition-all duration-300",
isVmActive ? "fill-purple-500/20 stroke-purple-500" : "fill-muted stroke-muted-foreground/40"
)}
strokeWidth="1.5"
/>
<line
x1="7"
y1="8"
x2="7"
y2="10"
className={cn(
"transition-all duration-300",
isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/40"
)}
strokeWidth="1.5"
/>
<line
x1="3"
y1="10"
x2="11"
y2="10"
className={cn(
"transition-all duration-300",
isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/40"
)}
strokeWidth="1.5"
/> />
{/* Stand */}
<line x1="9" y1="10" x2="9" y2="13" className={cn(isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/30")} strokeWidth="1.5" />
<line x1="5" y1="13" x2="13" y2="13" className={cn(isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/30")} strokeWidth="1.5" />
</g> </g>
{/* LXC Label */}
<text
x="115"
y="10"
textAnchor="start"
className={cn(
"text-[8px] font-bold transition-all duration-300",
isLxcActive ? "fill-blue-500" : "fill-muted-foreground/40"
)}
>
LXC
</text>
{/* VM Label */}
<text
x="115"
y="35"
textAnchor="start"
className={cn(
"text-[8px] font-bold transition-all duration-300",
isVmActive ? "fill-purple-500" : "fill-muted-foreground/40"
)}
>
VM
</text>
</svg> </svg>
{/* Status text */} {/* Status description */}
<span <div className="flex flex-col items-start gap-0.5 min-w-0 flex-1">
className={cn( <span
"text-xs font-medium transition-all duration-300", className={cn(
isLxcActive ? "text-blue-500" : isVmActive ? "text-purple-500" : "text-muted-foreground" "text-xs font-medium transition-all duration-300",
)} isLxcActive ? "text-blue-500" : isVmActive ? "text-purple-500" : "text-muted-foreground"
> )}
{isLxcActive ? "LXC" : isVmActive ? "VM" : "N/A"} >
</span> {isLxcActive
? "Ready for LXC containers"
{hasChanged && ( : isVmActive
<span className="text-xs text-amber-500 font-medium animate-pulse"> ? "Ready for VM passthrough"
(pending) : "Mode unknown"}
</span> </span>
)} <span className="text-[10px] text-muted-foreground">
{isLxcActive
? "Native driver active"
: isVmActive
? "VFIO-PCI driver active"
: "No driver detected"}
</span>
{hasChanged && (
<span className="text-[10px] text-amber-500 font-medium animate-pulse">
Change pending...
</span>
)}
</div>
</div> </div>
) )
} }
// Full version (not used in current implementation but kept for flexibility)
return ( return (
<div <div
className={cn( className={cn(
"relative rounded-lg border p-3 transition-all duration-300", "relative rounded-lg border p-4 transition-all duration-300",
isEditing isEditing
? "border-amber-500/50 bg-amber-500/5" ? "border-amber-500/50 bg-amber-500/5"
: "border-border/50 bg-muted/30", : "border-border/50 bg-muted/30",
@@ -242,237 +285,196 @@ export function GpuSwitchModeIndicator({
<div className="flex items-center justify-between gap-4"> <div className="flex items-center justify-between gap-4">
<svg <svg
viewBox="0 0 200 60" viewBox="0 0 200 60"
className="h-12 w-full max-w-[180px]" className="h-14 w-full max-w-[200px]"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
> >
{/* GPU Chip Icon */} {/* GPU Chip Icon - LARGE and colored */}
<g transform="translate(5, 12)"> <g transform="translate(0, 8)">
<rect <rect
x="0" x="2"
y="8" y="6"
width="28" width="32"
height="20" height="24"
rx="3" rx="4"
className="fill-muted-foreground/20 stroke-muted-foreground" className={cn(
strokeWidth="1.5" "transition-all duration-300",
isLxcActive
? "fill-blue-500/20 stroke-blue-500"
: isVmActive
? "fill-purple-500/20 stroke-purple-500"
: "fill-muted-foreground/20 stroke-muted-foreground"
)}
strokeWidth="2"
/> />
{/* Chip pins top */} {/* Chip pins top */}
<line x1="6" y1="4" x2="6" y2="8" className="stroke-muted-foreground" strokeWidth="1.5" /> <line x1="9" y1="2" x2="9" y2="6" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="2" />
<line x1="14" y1="4" x2="14" y2="8" className="stroke-muted-foreground" strokeWidth="1.5" /> <line x1="18" y1="2" x2="18" y2="6" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="2" />
<line x1="22" y1="4" x2="22" y2="8" className="stroke-muted-foreground" strokeWidth="1.5" /> <line x1="27" y1="2" x2="27" y2="6" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="2" />
{/* Chip pins bottom */} {/* Chip pins bottom */}
<line x1="6" y1="28" x2="6" y2="32" className="stroke-muted-foreground" strokeWidth="1.5" /> <line x1="9" y1="30" x2="9" y2="34" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="2" />
<line x1="14" y1="28" x2="14" y2="32" className="stroke-muted-foreground" strokeWidth="1.5" /> <line x1="18" y1="30" x2="18" y2="34" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="2" />
<line x1="22" y1="28" x2="22" y2="32" className="stroke-muted-foreground" strokeWidth="1.5" /> <line x1="27" y1="30" x2="27" y2="34" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="2" />
<text x="14" y="21" textAnchor="middle" className="fill-muted-foreground text-[8px] font-bold"> <text
x="18"
y="22"
textAnchor="middle"
className={cn(
"text-[10px] font-bold",
isLxcActive ? "fill-blue-500" : isVmActive ? "fill-purple-500" : "fill-muted-foreground"
)}
>
GPU GPU
</text> </text>
</g> </g>
{/* Connection lines */} {/* Main connection line */}
<g className="transition-all duration-300"> <line
{/* Main line from GPU to switch */} x1="38"
<line y1="26"
x1="38" x2="70"
y1="30" y2="26"
x2="70" className={cn(
y2="30" "transition-all duration-300",
className="stroke-muted-foreground/50" isLxcActive ? "stroke-blue-500/60" : isVmActive ? "stroke-purple-500/60" : "stroke-muted-foreground/40"
strokeWidth="2.5"
/>
{/* Switch circle */}
<circle
cx="82"
cy="30"
r="10"
className={cn(
"transition-all duration-300",
isEditing ? "fill-amber-500/30 stroke-amber-500" : "fill-muted stroke-muted-foreground/50"
)}
strokeWidth="2"
/>
{/* Switch indicator inside circle */}
<circle
cx={isLxcActive ? 78 : 86}
cy="30"
r="4"
className={cn(
"transition-all duration-500",
isLxcActive ? "fill-blue-500" : "fill-purple-500"
)}
/>
{/* LXC branch - top */}
<path
d="M 92 24 Q 105 15, 125 15"
fill="none"
className={cn(
"transition-all duration-300",
isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30"
)}
strokeWidth={isLxcActive ? "3" : "2"}
/>
{/* Active glow for LXC */}
{isLxcActive && (
<path
d="M 92 24 Q 105 15, 125 15"
fill="none"
className="stroke-blue-500/30"
strokeWidth="6"
/>
)} )}
strokeWidth="3"
/>
{/* VM branch - bottom */} {/* Switch node */}
<path <circle
d="M 92 36 Q 105 45, 125 45" cx="82"
fill="none" cy="26"
className={cn( r="10"
"transition-all duration-300", className={cn(
isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/30" "transition-all duration-300",
)} isEditing
strokeWidth={isVmActive ? "3" : "2"} ? "fill-amber-500/30 stroke-amber-500"
/> : isLxcActive
? "fill-blue-500/30 stroke-blue-500"
{/* Active glow for VM */} : isVmActive
{isVmActive && ( ? "fill-purple-500/30 stroke-purple-500"
<path : "fill-muted stroke-muted-foreground/50"
d="M 92 36 Q 105 45, 125 45"
fill="none"
className="stroke-purple-500/30"
strokeWidth="6"
/>
)} )}
</g> strokeWidth="2"
/>
<circle
cx="82"
cy="26"
r="4"
className={cn(
"transition-all duration-300",
isEditing
? "fill-amber-500"
: isLxcActive
? "fill-blue-500"
: isVmActive
? "fill-purple-500"
: "fill-muted-foreground"
)}
/>
{/* LXC Icon - Container with layers */} {/* LXC branch */}
<g transform="translate(130, 5)"> <path
d="M 92 20 Q 110 10, 130 10"
fill="none"
className={cn(
"transition-all duration-300",
isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30"
)}
strokeWidth={isLxcActive ? "3" : "2"}
strokeLinecap="round"
/>
{/* VM branch */}
<path
d="M 92 32 Q 110 42, 130 42"
fill="none"
className={cn(
"transition-all duration-300",
isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/30"
)}
strokeWidth={isVmActive ? "3" : "2"}
strokeLinecap="round"
/>
{/* LXC Container icon */}
<g transform="translate(135, 0)">
<rect <rect
x="0" x="0"
y="0" y="0"
width="24" width="26"
height="20" height="20"
rx="2" rx="3"
className={cn( className={cn(
"transition-all duration-300", "transition-all duration-300",
isLxcActive ? "fill-blue-500/20 stroke-blue-500" : "fill-muted stroke-muted-foreground/40" isLxcActive ? "fill-blue-500/25 stroke-blue-500" : "fill-muted stroke-muted-foreground/30"
)} )}
strokeWidth="2" strokeWidth="2"
/> />
{/* Container layers */} <line x1="0" y1="7" x2="26" y2="7" className={cn(isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30")} strokeWidth="1.5" />
<line <line x1="0" y1="13" x2="26" y2="13" className={cn(isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30")} strokeWidth="1.5" />
x1="0" <circle cx="5" cy="3.5" r="1.5" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
y1="7" <circle cx="5" cy="10" r="1.5" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
x2="24" <circle cx="5" cy="16.5" r="1.5" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
y2="7"
className={cn(
"transition-all duration-300",
isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/40"
)}
strokeWidth="1.5"
/>
<line
x1="0"
y1="13"
x2="24"
y2="13"
className={cn(
"transition-all duration-300",
isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/40"
)}
strokeWidth="1.5"
/>
{/* Small dots on layers */}
<circle cx="5" cy="3.5" r="1.5" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/40")} />
<circle cx="5" cy="10" r="1.5" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/40")} />
<circle cx="5" cy="16.5" r="1.5" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/40")} />
</g> </g>
{/* LXC label */}
<text <text
x="167" x="178"
y="18" y="14"
textAnchor="middle" textAnchor="middle"
className={cn( className={cn(
"text-[9px] font-bold transition-all duration-300", "text-[10px] font-bold",
isLxcActive ? "fill-blue-500" : "fill-muted-foreground/50" isLxcActive ? "fill-blue-500" : "fill-muted-foreground/40"
)} )}
> >
LXC LXC
</text> </text>
{/* VM Icon - Monitor/Desktop */} {/* VM Monitor icon */}
<g transform="translate(130, 35)"> <g transform="translate(135, 32)">
<rect <rect
x="2" x="2"
y="0" y="0"
width="20" width="22"
height="14" height="14"
rx="2" rx="2"
className={cn( className={cn(
"transition-all duration-300", "transition-all duration-300",
isVmActive ? "fill-purple-500/20 stroke-purple-500" : "fill-muted stroke-muted-foreground/40" isVmActive ? "fill-purple-500/25 stroke-purple-500" : "fill-muted stroke-muted-foreground/30"
)} )}
strokeWidth="2" strokeWidth="2"
/> />
{/* Screen content */}
<rect <rect
x="5" x="5"
y="3" y="3"
width="14" width="16"
height="8" height="8"
rx="1" rx="1"
className={cn( className={cn(isVmActive ? "fill-purple-500/30" : "fill-muted-foreground/10")}
"transition-all duration-300",
isVmActive ? "fill-purple-500/30" : "fill-muted-foreground/20"
)}
/>
{/* Stand */}
<line
x1="12"
y1="14"
x2="12"
y2="18"
className={cn(
"transition-all duration-300",
isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/40"
)}
strokeWidth="2"
/>
<line
x1="6"
y1="18"
x2="18"
y2="18"
className={cn(
"transition-all duration-300",
isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/40"
)}
strokeWidth="2"
/> />
<line x1="13" y1="14" x2="13" y2="18" className={cn(isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/30")} strokeWidth="2" />
<line x1="7" y1="18" x2="19" y2="18" className={cn(isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/30")} strokeWidth="2" />
</g> </g>
{/* VM label */}
<text <text
x="167" x="178"
y="50" y="48"
textAnchor="middle" textAnchor="middle"
className={cn( className={cn(
"text-[9px] font-bold transition-all duration-300", "text-[10px] font-bold",
isVmActive ? "fill-purple-500" : "fill-muted-foreground/50" isVmActive ? "fill-purple-500" : "fill-muted-foreground/40"
)} )}
> >
VM VM
</text> </text>
</svg> </svg>
{/* Status text and edit hint */} {/* Status */}
<div className="flex flex-col items-end gap-1"> <div className="flex flex-col items-end gap-1">
<span <span
className={cn( className={cn(
"text-sm font-semibold transition-all duration-300", "text-base font-semibold transition-all duration-300",
isLxcActive ? "text-blue-500" : isVmActive ? "text-purple-500" : "text-muted-foreground" isLxcActive ? "text-blue-500" : isVmActive ? "text-purple-500" : "text-muted-foreground"
)} )}
> >

View File

@@ -879,9 +879,9 @@ export default function Hardware() {
<span className="text-xs font-medium text-muted-foreground uppercase tracking-wide"> <span className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
Switch Mode Switch Mode
</span> </span>
<div className="flex items-center gap-1"> <div className="flex items-center gap-2">
{editingSwitchModeGpu === fullSlot ? ( {editingSwitchModeGpu === fullSlot ? (
<> <div className="flex items-center gap-1">
<Button <Button
variant="ghost" variant="ghost"
size="sm" size="sm"
@@ -889,7 +889,7 @@ export default function Hardware() {
onClick={(e) => handleSwitchModeSave(fullSlot, e)} onClick={(e) => handleSwitchModeSave(fullSlot, e)}
title="Save changes" title="Save changes"
> >
<Check className="h-3.5 w-3.5" /> <Check className="h-4 w-4" />
</Button> </Button>
<Button <Button
variant="ghost" variant="ghost"
@@ -898,18 +898,18 @@ export default function Hardware() {
onClick={(e) => handleSwitchModeCancel(fullSlot, e)} onClick={(e) => handleSwitchModeCancel(fullSlot, e)}
title="Cancel" title="Cancel"
> >
<X className="h-3.5 w-3.5" /> <X className="h-4 w-4" />
</Button> </Button>
</> </div>
) : ( ) : (
<Button <Button
variant="ghost" variant="outline"
size="sm" size="sm"
className="h-6 w-6 p-0 text-muted-foreground hover:text-foreground" className="h-7 px-2 text-xs flex items-center gap-1"
onClick={(e) => handleSwitchModeEdit(fullSlot, e)} onClick={(e) => handleSwitchModeEdit(fullSlot, e)}
title="Edit switch mode"
> >
<Pencil className="h-3.5 w-3.5" /> <Pencil className="h-3 w-3" />
Edit
</Button> </Button>
)} )}
</div> </div>