Unverified Commit e1892659 authored by Lemon-miaow's avatar Lemon-miaow
Browse files

refactor(panel): compact server card layout, denser grid

parent ae91133e
Loading
Loading
Loading
Loading
+22 −23
Changes for panel/src/components/ServerCard.tsx: 22 added lines, 23 removed lines.
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ import { useState } from "react";
import { Link } from "react-router-dom";
import { Play, Square, Hand, Users, ExternalLink, Terminal } from "lucide-react";
import { useTranslation } from "react-i18next";
import { Card, CardContent, CardFooter, CardHeader } from "@/components/ui/card";
import { Card } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { PhaseBadge } from "@/components/PhaseBadge";
import { api, humanizeError } from "@/lib/api";
@@ -42,41 +42,40 @@ export function ServerCard({ server, cfg, onChanged }: Props) {
  const transitioning = server.phase === "Starting" || server.phase === "Stopping";

  return (
    <Card className="flex flex-col transition-colors hover:border-primary/40">
      <CardHeader className="flex-row items-start justify-between space-y-0">
        <div className="min-w-0">
          <div className="truncate font-semibold">
    <Card className="flex flex-col p-4 transition-colors hover:border-primary/40">
      {/* Header Row */}
      <div className="flex items-center justify-between gap-2">
        <span className="truncate text-sm font-semibold text-foreground">
          {server.displayName || server.name}
        </span>
        <PhaseBadge phase={server.phase} />
      </div>

      {/* Info Row */}
      <div className="mt-2 flex items-center justify-between text-xs text-muted-foreground">
        <a
          href={`https://${host}`}
          target="_blank"
          rel="noreferrer"
            className="mt-0.5 inline-flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground"
          className="inline-flex items-center gap-1 hover:text-foreground truncate max-w-[70%]"
        >
          {host}
            <ExternalLink className="h-3 w-3" />
          <ExternalLink className="h-3 w-3 shrink-0" />
        </a>
        </div>
        <PhaseBadge phase={server.phase} />
      </CardHeader>

      <CardContent className="flex-1 text-sm text-muted-foreground">
        <div className="flex items-center gap-1.5">
          <Users className="h-3.5 w-3.5" />
          {running ? (
        <div className="flex items-center gap-1.5 shrink-0 mr-1">
          <span>
              {server.players ?? 0}
              {server.maxPlayers ? ` / ${server.maxPlayers}` : ""} {t("online")}
            {running
              ? `${server.players ?? 0}${server.maxPlayers ? `/${server.maxPlayers}` : ""}`
              : "—"}
          </span>
          ) : (
            <span>—</span>
          )}
          <Users className="h-3.5 w-3.5" />
        </div>
      </div>

      {error && <p className="mt-2 text-xs text-destructive">{error}</p>}
      </CardContent>

      <CardFooter className="flex flex-wrap gap-2">
      {/* Action Row */}
      <div className="mt-4 flex flex-wrap gap-2 border-t border-border/50 pt-3">
        {server.owned && (
          <Link to={`/servers/${server.name}`}>
            <Button variant="ghost" size="sm">
@@ -114,7 +113,7 @@ export function ServerCard({ server, cfg, onChanged }: Props) {
              <Play /> {busy === "wake" ? t("waking") : t("wake")}
            </Button>
          ))}
      </CardFooter>
      </div>
    </Card>
  );
}