mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-04-22 11:42:15 +00:00
update gpu-switch-mode-indicator.tsx
This commit is contained in:
@@ -31,206 +31,249 @@ export function GpuSwitchModeIndicator({
|
||||
}
|
||||
}
|
||||
|
||||
// Compact version for GPU card
|
||||
if (compact) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex items-center gap-2",
|
||||
isEditing && "cursor-pointer hover:opacity-80",
|
||||
"flex items-center gap-3",
|
||||
isEditing && "cursor-pointer",
|
||||
className
|
||||
)}
|
||||
onClick={handleClick}
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 120 32"
|
||||
className="h-6 w-24"
|
||||
viewBox="0 0 140 40"
|
||||
className="h-8 w-32"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
{/* GPU Chip Icon */}
|
||||
<g transform="translate(2, 4)">
|
||||
{/* GPU Chip Icon - LARGER and always colored */}
|
||||
<g transform="translate(0, 6)">
|
||||
{/* Chip body */}
|
||||
<rect
|
||||
x="2"
|
||||
y="6"
|
||||
width="16"
|
||||
height="12"
|
||||
rx="2"
|
||||
className="fill-muted-foreground/30 stroke-muted-foreground"
|
||||
strokeWidth="1"
|
||||
y="4"
|
||||
width="22"
|
||||
height="18"
|
||||
rx="3"
|
||||
className={cn(
|
||||
"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 */}
|
||||
<line x1="5" y1="4" x2="5" y2="6" className="stroke-muted-foreground" strokeWidth="1" />
|
||||
<line x1="10" y1="4" x2="10" y2="6" className="stroke-muted-foreground" strokeWidth="1" />
|
||||
<line x1="15" y1="4" x2="15" y2="6" className="stroke-muted-foreground" strokeWidth="1" />
|
||||
<line x1="5" y1="18" x2="5" y2="20" className="stroke-muted-foreground" strokeWidth="1" />
|
||||
<line x1="10" y1="18" x2="10" y2="20" className="stroke-muted-foreground" strokeWidth="1" />
|
||||
<line x1="15" y1="18" x2="15" y2="20" className="stroke-muted-foreground" strokeWidth="1" />
|
||||
<text x="10" y="14" textAnchor="middle" className="fill-muted-foreground text-[6px] font-bold">
|
||||
{/* Chip pins top */}
|
||||
<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="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="19" y1="1" x2="19" y2="4" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="1.5" />
|
||||
{/* Chip pins bottom */}
|
||||
<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="13" y1="22" x2="13" y2="25" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="1.5" />
|
||||
<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
|
||||
</text>
|
||||
</g>
|
||||
|
||||
{/* Connection lines from GPU */}
|
||||
<g className="transition-all duration-300">
|
||||
{/* Main line from GPU */}
|
||||
<line
|
||||
x1="22"
|
||||
y1="16"
|
||||
x2="45"
|
||||
y2="16"
|
||||
className="stroke-muted-foreground/50"
|
||||
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"
|
||||
/>
|
||||
{/* Connection line from GPU to switch */}
|
||||
<line
|
||||
x1="26"
|
||||
y1="20"
|
||||
x2="48"
|
||||
y2="20"
|
||||
className={cn(
|
||||
"transition-all duration-300",
|
||||
isLxcActive ? "stroke-blue-500/60" : isVmActive ? "stroke-purple-500/60" : "stroke-muted-foreground/40"
|
||||
)}
|
||||
strokeWidth="2"
|
||||
/>
|
||||
|
||||
{/* LXC branch */}
|
||||
<line
|
||||
x1="58"
|
||||
y1="13"
|
||||
x2="75"
|
||||
y2="8"
|
||||
className={cn(
|
||||
"transition-all duration-300",
|
||||
isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30"
|
||||
)}
|
||||
strokeWidth={isLxcActive ? "2.5" : "1.5"}
|
||||
/>
|
||||
|
||||
{/* VM branch */}
|
||||
<line
|
||||
x1="58"
|
||||
y1="19"
|
||||
x2="75"
|
||||
y2="24"
|
||||
className={cn(
|
||||
"transition-all duration-300",
|
||||
isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/30"
|
||||
)}
|
||||
strokeWidth={isVmActive ? "2.5" : "1.5"}
|
||||
/>
|
||||
</g>
|
||||
{/* Switch node - central junction */}
|
||||
<circle
|
||||
cx="55"
|
||||
cy="20"
|
||||
r="6"
|
||||
className={cn(
|
||||
"transition-all duration-300",
|
||||
isEditing
|
||||
? "fill-amber-500/30 stroke-amber-500"
|
||||
: isLxcActive
|
||||
? "fill-blue-500/30 stroke-blue-500"
|
||||
: isVmActive
|
||||
? "fill-purple-500/30 stroke-purple-500"
|
||||
: "fill-muted stroke-muted-foreground/50"
|
||||
)}
|
||||
strokeWidth="2"
|
||||
/>
|
||||
|
||||
{/* Animated dot inside switch */}
|
||||
<circle
|
||||
cx="55"
|
||||
cy="20"
|
||||
r="2.5"
|
||||
className={cn(
|
||||
"transition-all duration-300",
|
||||
isEditing
|
||||
? "fill-amber-500"
|
||||
: isLxcActive
|
||||
? "fill-blue-500"
|
||||
: isVmActive
|
||||
? "fill-purple-500"
|
||||
: "fill-muted-foreground"
|
||||
)}
|
||||
/>
|
||||
|
||||
{/* LXC Icon - Container */}
|
||||
<g transform="translate(78, 2)">
|
||||
{/* LXC branch line */}
|
||||
<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
|
||||
x="0"
|
||||
y="0"
|
||||
width="14"
|
||||
height="12"
|
||||
rx="1.5"
|
||||
width="18"
|
||||
height="14"
|
||||
rx="2"
|
||||
className={cn(
|
||||
"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"
|
||||
/>
|
||||
<line
|
||||
x1="0"
|
||||
y1="4"
|
||||
x2="14"
|
||||
y2="4"
|
||||
className={cn(
|
||||
"transition-all duration-300",
|
||||
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>
|
||||
{/* Container layers */}
|
||||
<line x1="0" y1="5" x2="18" y2="5" className={cn(isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30")} strokeWidth="1" />
|
||||
<line x1="0" y1="9" x2="18" y2="9" className={cn(isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30")} strokeWidth="1" />
|
||||
{/* Dots */}
|
||||
<circle cx="4" cy="2.5" r="1" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
|
||||
<circle cx="4" cy="7" r="1" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
|
||||
<circle cx="4" cy="11.5" r="1" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
|
||||
</g>
|
||||
|
||||
{/* VM Icon - Monitor/PC */}
|
||||
<g transform="translate(78, 18)">
|
||||
{/* VM Icon - Monitor */}
|
||||
<g transform="translate(83, 24)">
|
||||
<rect
|
||||
x="1"
|
||||
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"
|
||||
height="8"
|
||||
rx="1"
|
||||
className={cn(
|
||||
"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"
|
||||
height="6"
|
||||
rx="0.5"
|
||||
className={cn(isVmActive ? "fill-purple-500/30" : "fill-muted-foreground/10")}
|
||||
/>
|
||||
{/* 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>
|
||||
|
||||
{/* 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>
|
||||
|
||||
{/* Status text */}
|
||||
<span
|
||||
className={cn(
|
||||
"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>
|
||||
|
||||
{hasChanged && (
|
||||
<span className="text-xs text-amber-500 font-medium animate-pulse">
|
||||
(pending)
|
||||
{/* Status description */}
|
||||
<div className="flex flex-col items-start gap-0.5 min-w-0 flex-1">
|
||||
<span
|
||||
className={cn(
|
||||
"text-xs font-medium transition-all duration-300",
|
||||
isLxcActive ? "text-blue-500" : isVmActive ? "text-purple-500" : "text-muted-foreground"
|
||||
)}
|
||||
>
|
||||
{isLxcActive
|
||||
? "Ready for LXC containers"
|
||||
: isVmActive
|
||||
? "Ready for VM passthrough"
|
||||
: "Mode unknown"}
|
||||
</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>
|
||||
)
|
||||
}
|
||||
|
||||
// Full version (not used in current implementation but kept for flexibility)
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"relative rounded-lg border p-3 transition-all duration-300",
|
||||
"relative rounded-lg border p-4 transition-all duration-300",
|
||||
isEditing
|
||||
? "border-amber-500/50 bg-amber-500/5"
|
||||
: "border-border/50 bg-muted/30",
|
||||
@@ -242,237 +285,196 @@ export function GpuSwitchModeIndicator({
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<svg
|
||||
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"
|
||||
>
|
||||
{/* GPU Chip Icon */}
|
||||
<g transform="translate(5, 12)">
|
||||
{/* GPU Chip Icon - LARGE and colored */}
|
||||
<g transform="translate(0, 8)">
|
||||
<rect
|
||||
x="0"
|
||||
y="8"
|
||||
width="28"
|
||||
height="20"
|
||||
rx="3"
|
||||
className="fill-muted-foreground/20 stroke-muted-foreground"
|
||||
strokeWidth="1.5"
|
||||
x="2"
|
||||
y="6"
|
||||
width="32"
|
||||
height="24"
|
||||
rx="4"
|
||||
className={cn(
|
||||
"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 */}
|
||||
<line x1="6" y1="4" x2="6" y2="8" className="stroke-muted-foreground" strokeWidth="1.5" />
|
||||
<line x1="14" y1="4" x2="14" y2="8" className="stroke-muted-foreground" strokeWidth="1.5" />
|
||||
<line x1="22" y1="4" x2="22" 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="18" y1="2" x2="18" y2="6" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="2" />
|
||||
<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 */}
|
||||
<line x1="6" y1="28" x2="6" y2="32" className="stroke-muted-foreground" strokeWidth="1.5" />
|
||||
<line x1="14" y1="28" x2="14" y2="32" className="stroke-muted-foreground" strokeWidth="1.5" />
|
||||
<line x1="22" y1="28" x2="22" y2="32" className="stroke-muted-foreground" strokeWidth="1.5" />
|
||||
<text x="14" y="21" textAnchor="middle" className="fill-muted-foreground text-[8px] font-bold">
|
||||
<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="18" y1="30" x2="18" y2="34" className={cn(isLxcActive ? "stroke-blue-500" : isVmActive ? "stroke-purple-500" : "stroke-muted-foreground")} strokeWidth="2" />
|
||||
<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="18"
|
||||
y="22"
|
||||
textAnchor="middle"
|
||||
className={cn(
|
||||
"text-[10px] font-bold",
|
||||
isLxcActive ? "fill-blue-500" : isVmActive ? "fill-purple-500" : "fill-muted-foreground"
|
||||
)}
|
||||
>
|
||||
GPU
|
||||
</text>
|
||||
</g>
|
||||
|
||||
{/* Connection lines */}
|
||||
<g className="transition-all duration-300">
|
||||
{/* Main line from GPU to switch */}
|
||||
<line
|
||||
x1="38"
|
||||
y1="30"
|
||||
x2="70"
|
||||
y2="30"
|
||||
className="stroke-muted-foreground/50"
|
||||
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"
|
||||
/>
|
||||
{/* Main connection line */}
|
||||
<line
|
||||
x1="38"
|
||||
y1="26"
|
||||
x2="70"
|
||||
y2="26"
|
||||
className={cn(
|
||||
"transition-all duration-300",
|
||||
isLxcActive ? "stroke-blue-500/60" : isVmActive ? "stroke-purple-500/60" : "stroke-muted-foreground/40"
|
||||
)}
|
||||
strokeWidth="3"
|
||||
/>
|
||||
|
||||
{/* VM branch - bottom */}
|
||||
<path
|
||||
d="M 92 36 Q 105 45, 125 45"
|
||||
fill="none"
|
||||
className={cn(
|
||||
"transition-all duration-300",
|
||||
isVmActive ? "stroke-purple-500" : "stroke-muted-foreground/30"
|
||||
)}
|
||||
strokeWidth={isVmActive ? "3" : "2"}
|
||||
/>
|
||||
|
||||
{/* Active glow for VM */}
|
||||
{isVmActive && (
|
||||
<path
|
||||
d="M 92 36 Q 105 45, 125 45"
|
||||
fill="none"
|
||||
className="stroke-purple-500/30"
|
||||
strokeWidth="6"
|
||||
/>
|
||||
{/* Switch node */}
|
||||
<circle
|
||||
cx="82"
|
||||
cy="26"
|
||||
r="10"
|
||||
className={cn(
|
||||
"transition-all duration-300",
|
||||
isEditing
|
||||
? "fill-amber-500/30 stroke-amber-500"
|
||||
: isLxcActive
|
||||
? "fill-blue-500/30 stroke-blue-500"
|
||||
: isVmActive
|
||||
? "fill-purple-500/30 stroke-purple-500"
|
||||
: "fill-muted stroke-muted-foreground/50"
|
||||
)}
|
||||
</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 */}
|
||||
<g transform="translate(130, 5)">
|
||||
{/* LXC branch */}
|
||||
<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
|
||||
x="0"
|
||||
y="0"
|
||||
width="24"
|
||||
width="26"
|
||||
height="20"
|
||||
rx="2"
|
||||
rx="3"
|
||||
className={cn(
|
||||
"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"
|
||||
/>
|
||||
{/* Container layers */}
|
||||
<line
|
||||
x1="0"
|
||||
y1="7"
|
||||
x2="24"
|
||||
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")} />
|
||||
<line x1="0" y1="7" x2="26" y2="7" className={cn(isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30")} strokeWidth="1.5" />
|
||||
<line x1="0" y1="13" x2="26" y2="13" className={cn(isLxcActive ? "stroke-blue-500" : "stroke-muted-foreground/30")} strokeWidth="1.5" />
|
||||
<circle cx="5" cy="3.5" r="1.5" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
|
||||
<circle cx="5" cy="10" r="1.5" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
|
||||
<circle cx="5" cy="16.5" r="1.5" className={cn(isLxcActive ? "fill-blue-500" : "fill-muted-foreground/30")} />
|
||||
</g>
|
||||
|
||||
{/* LXC label */}
|
||||
<text
|
||||
x="167"
|
||||
y="18"
|
||||
x="178"
|
||||
y="14"
|
||||
textAnchor="middle"
|
||||
className={cn(
|
||||
"text-[9px] font-bold transition-all duration-300",
|
||||
isLxcActive ? "fill-blue-500" : "fill-muted-foreground/50"
|
||||
"text-[10px] font-bold",
|
||||
isLxcActive ? "fill-blue-500" : "fill-muted-foreground/40"
|
||||
)}
|
||||
>
|
||||
LXC
|
||||
</text>
|
||||
|
||||
{/* VM Icon - Monitor/Desktop */}
|
||||
<g transform="translate(130, 35)">
|
||||
{/* VM Monitor icon */}
|
||||
<g transform="translate(135, 32)">
|
||||
<rect
|
||||
x="2"
|
||||
y="0"
|
||||
width="20"
|
||||
width="22"
|
||||
height="14"
|
||||
rx="2"
|
||||
className={cn(
|
||||
"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"
|
||||
/>
|
||||
{/* Screen content */}
|
||||
<rect
|
||||
x="5"
|
||||
y="3"
|
||||
width="14"
|
||||
width="16"
|
||||
height="8"
|
||||
rx="1"
|
||||
className={cn(
|
||||
"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"
|
||||
className={cn(isVmActive ? "fill-purple-500/30" : "fill-muted-foreground/10")}
|
||||
/>
|
||||
<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>
|
||||
|
||||
{/* VM label */}
|
||||
<text
|
||||
x="167"
|
||||
y="50"
|
||||
x="178"
|
||||
y="48"
|
||||
textAnchor="middle"
|
||||
className={cn(
|
||||
"text-[9px] font-bold transition-all duration-300",
|
||||
isVmActive ? "fill-purple-500" : "fill-muted-foreground/50"
|
||||
"text-[10px] font-bold",
|
||||
isVmActive ? "fill-purple-500" : "fill-muted-foreground/40"
|
||||
)}
|
||||
>
|
||||
VM
|
||||
</text>
|
||||
</svg>
|
||||
|
||||
{/* Status text and edit hint */}
|
||||
{/* Status */}
|
||||
<div className="flex flex-col items-end gap-1">
|
||||
<span
|
||||
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"
|
||||
)}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user