Trying to fix tw

This commit is contained in:
2025-12-26 19:05:49 +01:00
parent 82d45d872e
commit 10bd71a761
8 changed files with 110 additions and 70 deletions
+64 -1
View File
@@ -8,6 +8,7 @@
"name": "dockship", "name": "dockship",
"version": "0.1.0", "version": "0.1.0",
"dependencies": { "dependencies": {
"@radix-ui/react-progress": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-slot": "^1.2.4",
"@types/dockerode": "^3.3.47", "@types/dockerode": "^3.3.47",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
@@ -848,6 +849,68 @@
} }
} }
}, },
"node_modules/@radix-ui/react-context": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.3.tgz",
"integrity": "sha512-ieIFACdMpYfMEjF0rEf5KLvfVyIkOz6PDGyNnP+u+4xQ6jny3VCgA4OgXOwNx2aUkxn8zx9fiVcM8CfFYv9Lxw==",
"license": "MIT",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-primitive": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz",
"integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-slot": "1.2.4"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-progress": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.1.8.tgz",
"integrity": "sha512-+gISHcSPUJ7ktBy9RnTqbdKW78bcGke3t6taawyZ71pio1JewwGSJizycs7rLhGTvMJYCQB1DBK4KQsxs7U8dA==",
"license": "MIT",
"dependencies": {
"@radix-ui/react-context": "1.1.3",
"@radix-ui/react-primitive": "2.1.4"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-slot": { "node_modules/@radix-ui/react-slot": {
"version": "1.2.4", "version": "1.2.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz",
@@ -1301,7 +1364,7 @@
"version": "19.2.3", "version": "19.2.3",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz",
"integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==",
"dev": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
"@types/react": "^19.2.0" "@types/react": "^19.2.0"
+1
View File
@@ -8,6 +8,7 @@
"start": "next start" "start": "next start"
}, },
"dependencies": { "dependencies": {
"@radix-ui/react-progress": "^1.1.8",
"@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-slot": "^1.2.4",
"@types/dockerode": "^3.3.47", "@types/dockerode": "^3.3.47",
"class-variance-authority": "^0.7.1", "class-variance-authority": "^0.7.1",
+3 -3
View File
@@ -5,8 +5,8 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { StatusIndicator } from "@/components/dashboard/StatusIndicator"; import { StatusIndicator } from "@/components/dashboard/StatusIndicator";
import { MetricBar } from "@/components/dashboard/MetricBar";
import { Play, Square, RotateCcw, MoreVertical, Plus } from "lucide-react"; import { Play, Square, RotateCcw, MoreVertical, Plus } from "lucide-react";
import { Progress } from "@/components/ui/progress";
const applications = [ const applications = [
{ {
@@ -130,7 +130,7 @@ export default function ApplicationsPage() {
<div className="col-span-2"> <div className="col-span-2">
<div className="text-xs text-muted-foreground mb-1">CPU</div> <div className="text-xs text-muted-foreground mb-1">CPU</div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<MetricBar value={app.cpu} max={100} /> <Progress value={app.cpu} className="w-full" />
<span className="text-xs font-mono w-8">{app.cpu}%</span> <span className="text-xs font-mono w-8">{app.cpu}%</span>
</div> </div>
</div> </div>
@@ -141,7 +141,7 @@ export default function ApplicationsPage() {
Memory Memory
</div> </div>
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<MetricBar value={app.memory} max={100} /> <Progress value={app.memory} className="w-full" />
<span className="text-xs font-mono w-8">{app.memory}%</span> <span className="text-xs font-mono w-8">{app.memory}%</span>
</div> </div>
</div> </div>
+5 -5
View File
@@ -3,7 +3,6 @@
import { DashboardLayout } from "@/components/dashboard/DashboardLayout"; import { DashboardLayout } from "@/components/dashboard/DashboardLayout";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { MetricBar } from "@/components/dashboard/MetricBar";
import { import {
LineChart, LineChart,
Line, Line,
@@ -14,6 +13,7 @@ import {
AreaChart, AreaChart,
Area, Area,
} from "recharts"; } from "recharts";
import { Progress } from "@/components/ui/progress";
const cpuData = [ const cpuData = [
{ time: "00:00", value: 45 }, { time: "00:00", value: 45 },
@@ -88,7 +88,7 @@ export default function MonitoringPage() {
Cluster CPU Cluster CPU
</div> </div>
<div className="stat-value">68%</div> <div className="stat-value">68%</div>
<MetricBar value={68} max={100} /> <Progress value={68} className="w-full" />
</CardContent> </CardContent>
</Card> </Card>
<Card> <Card>
@@ -97,7 +97,7 @@ export default function MonitoringPage() {
Cluster Memory Cluster Memory
</div> </div>
<div className="stat-value">71%</div> <div className="stat-value">71%</div>
<MetricBar value={71} max={100} /> <Progress value={71} className="w-full" />
</CardContent> </CardContent>
</Card> </Card>
<Card> <Card>
@@ -337,14 +337,14 @@ export default function MonitoringPage() {
<span>CPU</span> <span>CPU</span>
<span>{container.cpu}%</span> <span>{container.cpu}%</span>
</div> </div>
<MetricBar value={container.cpu} max={100} /> <Progress value={container.cpu} className="w-full" />
</div> </div>
<div> <div>
<div className="flex justify-between text-[10px] text-muted-foreground mb-1"> <div className="flex justify-between text-[10px] text-muted-foreground mb-1">
<span>Memory</span> <span>Memory</span>
<span>{container.memory}%</span> <span>{container.memory}%</span>
</div> </div>
<MetricBar value={container.memory} max={100} /> <Progress value={container.memory} className="w-full" />
</div> </div>
<div className="flex justify-between text-[10px] pt-1 border-t border-border"> <div className="flex justify-between text-[10px] pt-1 border-t border-border">
<span className="text-muted-foreground">Network</span> <span className="text-muted-foreground">Network</span>
+4 -4
View File
@@ -5,8 +5,8 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { StatusIndicator } from "@/components/dashboard/StatusIndicator"; import { StatusIndicator } from "@/components/dashboard/StatusIndicator";
import { MetricBar } from "@/components/dashboard/MetricBar";
import { Server, Plus, Settings, Trash2 } from "lucide-react"; import { Server, Plus, Settings, Trash2 } from "lucide-react";
import { Progress } from "@/components/ui/progress";
const nodes = [ const nodes = [
{ {
@@ -130,7 +130,7 @@ export default function NodesPage() {
CPU ({node.cpu.cores} cores) CPU ({node.cpu.cores} cores)
</div> </div>
<div className="stat-value mb-2">{node.cpu.usage}%</div> <div className="stat-value mb-2">{node.cpu.usage}%</div>
<MetricBar value={node.cpu.usage} max={100} /> <Progress value={node.cpu.usage} className="w-full" />
</div> </div>
{/* Memory */} {/* Memory */}
@@ -141,7 +141,7 @@ export default function NodesPage() {
<div className="stat-value mb-2"> <div className="stat-value mb-2">
{node.memory.percentage}% {node.memory.percentage}%
</div> </div>
<MetricBar value={node.memory.percentage} max={100} /> <Progress value={node.memory.percentage} className="w-full" />
<div className="text-[10px] text-muted-foreground mt-1 font-mono"> <div className="text-[10px] text-muted-foreground mt-1 font-mono">
{node.memory.used} / {node.memory.total} {node.memory.used} / {node.memory.total}
</div> </div>
@@ -151,7 +151,7 @@ export default function NodesPage() {
<div> <div>
<div className="text-xs text-muted-foreground mb-2">Disk</div> <div className="text-xs text-muted-foreground mb-2">Disk</div>
<div className="stat-value mb-2">{node.disk.percentage}%</div> <div className="stat-value mb-2">{node.disk.percentage}%</div>
<MetricBar value={node.disk.percentage} max={100} /> <Progress value={node.disk.percentage} className="w-full" />
<div className="text-[10px] text-muted-foreground mt-1 font-mono"> <div className="text-[10px] text-muted-foreground mt-1 font-mono">
{node.disk.used} / {node.disk.total} {node.disk.used} / {node.disk.total}
</div> </div>
+5 -5
View File
@@ -6,7 +6,6 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { StatusIndicator } from "@/components/dashboard/StatusIndicator"; import { StatusIndicator } from "@/components/dashboard/StatusIndicator";
import { MetricBar } from "@/components/dashboard/MetricBar";
import { import {
Box, Box,
Server, Server,
@@ -15,6 +14,7 @@ import {
ArrowRight, ArrowRight,
Clock, Clock,
} from "lucide-react"; } from "lucide-react";
import { Progress } from "@/components/ui/progress";
const recentDeployments = [ const recentDeployments = [
{ {
@@ -172,7 +172,7 @@ export default function OverviewPage() {
</div> </div>
<div className="col-span-2"> <div className="col-span-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<MetricBar value={app.cpu} max={100} /> <Progress value={app.cpu} className="w-full" />
<span className="text-xs text-muted-foreground font-mono w-8"> <span className="text-xs text-muted-foreground font-mono w-8">
{app.cpu}% {app.cpu}%
</span> </span>
@@ -180,7 +180,7 @@ export default function OverviewPage() {
</div> </div>
<div className="col-span-2"> <div className="col-span-2">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<MetricBar value={app.memory} max={100} /> <Progress value={app.memory} className="w-full" />
<span className="text-xs text-muted-foreground font-mono w-8"> <span className="text-xs text-muted-foreground font-mono w-8">
{app.memory}% {app.memory}%
</span> </span>
@@ -257,12 +257,12 @@ export default function OverviewPage() {
<span className="text-muted-foreground">CPU</span> <span className="text-muted-foreground">CPU</span>
<span className="font-mono">{node.cpu}%</span> <span className="font-mono">{node.cpu}%</span>
</div> </div>
<MetricBar value={node.cpu} max={100} /> <Progress value={node.cpu} className="bg-primary" />
<div className="flex items-center justify-between text-xs"> <div className="flex items-center justify-between text-xs">
<span className="text-muted-foreground">Memory</span> <span className="text-muted-foreground">Memory</span>
<span className="font-mono">{node.memory}%</span> <span className="font-mono">{node.memory}%</span>
</div> </div>
<MetricBar value={node.memory} max={100} /> <Progress value={node.memory} className="w-full" />
<div className="flex items-center justify-between text-xs pt-2 border-t border-border mt-2"> <div className="flex items-center justify-between text-xs pt-2 border-t border-border mt-2">
<span className="text-muted-foreground">Containers</span> <span className="text-muted-foreground">Containers</span>
<span className="font-mono">{node.containers}</span> <span className="font-mono">{node.containers}</span>
-32
View File
@@ -1,32 +0,0 @@
interface MetricBarProps {
value: number;
max: number;
variant?: "default" | "success" | "warning" | "danger";
}
export function MetricBar({ value, max, variant = "default" }: MetricBarProps) {
const percentage = Math.min((value / max) * 100, 100);
const getColor = () => {
if (variant !== "default") {
switch (variant) {
case "success": return "bg-success";
case "warning": return "bg-warning";
case "danger": return "bg-destructive";
}
}
if (percentage > 80) return "bg-destructive";
if (percentage > 60) return "bg-warning";
return "bg-primary";
};
return (
<div className="metric-bar">
<div
className={`metric-bar-fill ${getColor()}`}
style={{ width: `${percentage}%` }}
/>
</div>
);
}
+21 -13
View File
@@ -1,23 +1,31 @@
import * as React from "react"; "use client"
import * as ProgressPrimitive from "@radix-ui/react-progress";
import { cn } from "@/lib/utils"; import * as React from "react"
import * as ProgressPrimitive from "@radix-ui/react-progress"
const Progress = React.forwardRef< import { cn } from "@/lib/utils"
React.ElementRef<typeof ProgressPrimitive.Root>,
React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root> function Progress({
>(({ className, value, ...props }, ref) => ( className,
value,
...props
}: React.ComponentProps<typeof ProgressPrimitive.Root>) {
return (
<ProgressPrimitive.Root <ProgressPrimitive.Root
ref={ref} data-slot="progress"
className={cn("relative h-4 w-full overflow-hidden rounded-full bg-secondary", className)} className={cn(
"bg-primary/20 relative h-2 w-full overflow-hidden rounded-full",
className
)}
{...props} {...props}
> >
<ProgressPrimitive.Indicator <ProgressPrimitive.Indicator
className="h-full w-full flex-1 bg-primary transition-all" data-slot="progress-indicator"
className="bg-primary h-full w-full flex-1 transition-all"
style={{ transform: `translateX(-${100 - (value || 0)}%)` }} style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
/> />
</ProgressPrimitive.Root> </ProgressPrimitive.Root>
)); )
Progress.displayName = ProgressPrimitive.Root.displayName; }
export { Progress }; export { Progress }