feat(servers): support claiming servers directly from ServersPage list
This commit is contained in:
1 file changed
+28
-4
@@ -12,6 +12,7 @@ import {
|
|||||||
Users,
|
Users,
|
||||||
AlertTriangle,
|
AlertTriangle,
|
||||||
UserRound,
|
UserRound,
|
||||||
|
Hand,
|
||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { Card, CardContent } from "@/components/ui/card";
|
import { Card, CardContent } from "@/components/ui/card";
|
||||||
@@ -108,7 +109,7 @@ function Stat({
|
|||||||
|
|
||||||
export function ServersPage() {
|
export function ServersPage() {
|
||||||
const { t } = useTranslation(["ops", "servers"]);
|
const { t } = useTranslation(["ops", "servers"]);
|
||||||
const { isAdmin } = useTier();
|
const { isAdmin, identity } = useTier();
|
||||||
const cfg = useConfig();
|
const cfg = useConfig();
|
||||||
|
|
||||||
const fetchFn = useMemo(() => (isAdmin ? api.fleet : api.myServers), [isAdmin]);
|
const fetchFn = useMemo(() => (isAdmin ? api.fleet : api.myServers), [isAdmin]);
|
||||||
@@ -146,6 +147,8 @@ export function ServersPage() {
|
|||||||
playersMax: s.playersMax,
|
playersMax: s.playersMax,
|
||||||
owner: s.owner,
|
owner: s.owner,
|
||||||
endpointAddress: s.endpointAddress,
|
endpointAddress: s.endpointAddress,
|
||||||
|
claimable: !s.owner,
|
||||||
|
owned: s.owner === identity?.email,
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
return (data as ServerInfo[]).map((s) => ({
|
return (data as ServerInfo[]).map((s) => ({
|
||||||
@@ -162,7 +165,7 @@ export function ServersPage() {
|
|||||||
owned: s.owned,
|
owned: s.owned,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}, [data, isAdmin, t]);
|
}, [data, isAdmin, t, identity]);
|
||||||
|
|
||||||
const stats = useMemo(() => {
|
const stats = useMemo(() => {
|
||||||
const counts: Record<Phase, number> = {
|
const counts: Record<Phase, number> = {
|
||||||
@@ -429,10 +432,10 @@ function ServerRow({
|
|||||||
}) {
|
}) {
|
||||||
const { t } = useTranslation("ops");
|
const { t } = useTranslation("ops");
|
||||||
const { t: ts } = useTranslation("servers");
|
const { t: ts } = useTranslation("servers");
|
||||||
const [busy, setBusy] = useState<null | "wake" | "stop">(null);
|
const [busy, setBusy] = useState<null | "wake" | "stop" | "claim">(null);
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
async function act(kind: "wake" | "stop", fn: () => Promise<unknown>) {
|
async function act(kind: "wake" | "stop" | "claim", fn: () => Promise<unknown>) {
|
||||||
setBusy(kind);
|
setBusy(kind);
|
||||||
setError(null);
|
setError(null);
|
||||||
try {
|
try {
|
||||||
@@ -514,6 +517,23 @@ function ServerRow({
|
|||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3 align-middle">
|
<td className="px-4 py-3 align-middle">
|
||||||
<div className="flex items-center justify-end gap-2">
|
<div className="flex items-center justify-end gap-2">
|
||||||
|
{server.claimable && !server.owned ? (
|
||||||
|
<>
|
||||||
|
<Button
|
||||||
|
size="sm"
|
||||||
|
variant="outline"
|
||||||
|
disabled={busy !== null}
|
||||||
|
onClick={() => act("claim", () => api.claim(server.name))}
|
||||||
|
className="text-primary hover:text-primary hover:bg-primary/5 border-primary/20"
|
||||||
|
>
|
||||||
|
<Hand /> {busy === "claim" ? ts("claiming") : ts("claim")}
|
||||||
|
</Button>
|
||||||
|
<Button size="sm" variant="outline" disabled>
|
||||||
|
<Terminal /> {ts("console")}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
{live ? (
|
{live ? (
|
||||||
<Button
|
<Button
|
||||||
size="sm"
|
size="sm"
|
||||||
@@ -533,11 +553,15 @@ function ServerRow({
|
|||||||
<Play /> {busy === "wake" ? ts("waking") : ts("wake")}
|
<Play /> {busy === "wake" ? ts("waking") : ts("wake")}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
{(server.owned || isAdmin) && (
|
||||||
<Link to={`/servers/${server.name}`}>
|
<Link to={`/servers/${server.name}`}>
|
||||||
<Button size="sm" variant="outline">
|
<Button size="sm" variant="outline">
|
||||||
<Terminal /> {ts("console")}
|
<Terminal /> {ts("console")}
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
Reference in new issue
Block a user