Update for new API

This commit is contained in:
2026-05-28 13:14:58 -04:00
parent 2c9b9137df
commit 2d8dc128f1
5 changed files with 39 additions and 21 deletions
@@ -7,7 +7,7 @@
import {Button} from '$lib/components/ui/button'; import {Button} from '$lib/components/ui/button';
import {Card} from '$lib/components/ui/card'; import {Card} from '$lib/components/ui/card';
import {Input} from '$lib/components/ui/input'; import {Input} from '$lib/components/ui/input';
import type {PunishmentsPayload} from '$lib/types/api'; import type {PunishmentSummary, PunishmentsPayload} from '$lib/types/api';
import {lowerSearch, titleCase} from '$lib/utils'; import {lowerSearch, titleCase} from '$lib/utils';
interface Props { interface Props {
@@ -22,13 +22,13 @@
let type = $state('all'); let type = $state('all');
let status = $state('all'); let status = $state('all');
const punishments = $derived<Array<Record<string, unknown>>>(data?.punishments ?? []); const punishments = $derived<PunishmentSummary[]>(data?.punishments ?? []);
const types = $derived<string[]>(Array.from(new Set(punishments.map((item) => String(item.type ?? item.kind ?? '')).filter(Boolean))).sort()); const types = $derived<string[]>(Array.from(new Set(punishments.map((item) => item.type).filter(Boolean))).sort());
const visible = $derived.by(() => { const visible = $derived.by(() => {
const q = filter.toLowerCase().trim(); const q = filter.toLowerCase().trim();
return punishments.filter((item) => { return punishments.filter((item) => {
const itemType = String(item.type ?? item.kind ?? ''); const itemType = item.type;
const active = Boolean(item.active ?? item.isActive ?? item.current); const active = item.active;
const itemStatus = active ? 'active' : 'expired'; const itemStatus = active ? 'active' : 'expired';
return (!q || lowerSearch(item).includes(q)) && (type === 'all' || itemType === type) && (status === 'all' || itemStatus === status); return (!q || lowerSearch(item).includes(q)) && (type === 'all' || itemType === type) && (status === 'all' || itemStatus === status);
}); });
@@ -41,7 +41,7 @@
return String(value); return String(value);
} }
function entries(item: Record<string, unknown>) { function entries(item: PunishmentSummary) {
return Object.entries(item).filter(([key]) => !['id', 'uuid'].includes(key)); return Object.entries(item).filter(([key]) => !['id', 'uuid'].includes(key));
} }
@@ -105,14 +105,15 @@
<p class="mt-4 text-sm text-muted-foreground">No punishments match those filters.</p> <p class="mt-4 text-sm text-muted-foreground">No punishments match those filters.</p>
{:else} {:else}
<section class="rise mt-4 grid gap-3 md:grid-cols-2"> <section class="rise mt-4 grid gap-3 md:grid-cols-2">
{#each visible as punishment, index (String(punishment.id ?? index))} {#each visible as punishment, index (`${punishment.type}:${punishment.issueDate}:${index}`)}
{@const itemType = String(punishment.type ?? punishment.kind ?? 'punishment')} {@const itemType = punishment.type}
{@const active = Boolean(punishment.active ?? punishment.isActive ?? punishment.current)} {@const active = punishment.active}
<Card class="p-4"> <Card class="p-4">
<div class="flex items-start justify-between gap-3"> <div class="flex items-start justify-between gap-3">
<div> <div>
<h2 class="font-medium">{titleCase(itemType)}</h2> <h2 class="font-medium">{titleCase(itemType)}</h2>
<p class="mt-1 text-sm text-muted-foreground">{displayValue(punishment.reason)}</p> <p class="mt-1 text-sm text-muted-foreground">{displayValue(punishment.reason)}</p>
<p class="mt-1 text-xs text-muted-foreground">{displayValue(punishment.punisherDisplayName)} · {displayValue(punishment.source)}</p>
</div> </div>
<Badge variant={active ? 'destructive' : 'secondary'}>{active ? 'active' : 'expired'}</Badge> <Badge variant={active ? 'destructive' : 'secondary'}>{active ? 'active' : 'expired'}</Badge>
</div> </div>
+16 -1
View File
@@ -50,10 +50,25 @@ export interface CommandGroup {
export interface PunishmentsPayload { export interface PunishmentsPayload {
player: { uuid: string; name: string }; player: { uuid: string; name: string };
punishments: Array<Record<string, unknown>>; punishments: PunishmentSummary[];
canViewIps: boolean; canViewIps: boolean;
} }
export interface PunishmentSummary {
punished: string;
punisher?: string | null;
source: 'PLAYER' | 'CONSOLE' | 'WEB';
punisherReference?: string | null;
punisherDisplayName: string;
ip: string;
type: string;
reason: string;
customTime: boolean;
active: boolean;
issueDate: string;
endDate?: string | null;
}
export interface Schematic { export interface Schematic {
name: string; name: string;
size: number; size: number;
@@ -3,6 +3,7 @@ package dev.plex.request;
import dev.plex.HTTPDModule; import dev.plex.HTTPDModule;
import dev.plex.api.player.PlexPlayerView; import dev.plex.api.player.PlexPlayerView;
import dev.plex.api.punishment.PunishmentRequest; import dev.plex.api.punishment.PunishmentRequest;
import dev.plex.api.punishment.PunishmentSource;
import dev.plex.api.punishment.PunishmentType; import dev.plex.api.punishment.PunishmentType;
import dev.plex.authentication.AuthenticatedUser; import dev.plex.authentication.AuthenticatedUser;
import dev.plex.logging.Log; import dev.plex.logging.Log;
@@ -73,7 +74,7 @@ public class PlayerActionServlet extends HttpServlet
return; return;
} }
PlexPlayerView target = module.api().players().byUuid(uuid).orElse(null); PlexPlayerView target = module.api().players().player(uuid).orElse(null);
if (target == null) if (target == null)
{ {
response.getWriter().write(JsonResponse.error(response, HttpServletResponse.SC_NOT_FOUND, "Player not found.")); response.getWriter().write(JsonResponse.error(response, HttpServletResponse.SC_NOT_FOUND, "Player not found."));
@@ -100,9 +101,9 @@ public class PlayerActionServlet extends HttpServlet
PunishmentRequest punishment = new PunishmentRequest( PunishmentRequest punishment = new PunishmentRequest(
uuid, uuid,
null, null,
"xf:" + staff.username(), PunishmentSource.WEB,
"xf:" + staff.userId() + ":" + staff.username(),
ip, ip,
target.name(),
type, type,
safeReason, safeReason,
TEMP_ACTIONS.contains(action), TEMP_ACTIONS.contains(action),
@@ -67,7 +67,7 @@ public class PlayerAdminEndpoint extends AbstractServlet
{ {
try try
{ {
return module.api().players().byUuid(UUID.fromString(query)).orElse(null); return module.api().players().player(UUID.fromString(query)).orElse(null);
} }
catch (IllegalArgumentException ignored) catch (IllegalArgumentException ignored)
{ {
@@ -37,7 +37,7 @@ public class PunishmentsEndpoint extends AbstractServlet
try try
{ {
UUID pathUUID = UUID.fromString(request.getPathInfo().replace("/", "")); UUID pathUUID = UUID.fromString(request.getPathInfo().replace("/", ""));
punishedPlayer = module.api().players().byUuid(pathUUID).orElse(null); punishedPlayer = module.api().players().player(pathUUID).orElse(null);
} }
catch (IllegalArgumentException ignored) catch (IllegalArgumentException ignored)
{ {
@@ -53,11 +53,11 @@ public class PunishmentsEndpoint extends AbstractServlet
List<?> punishments; List<?> punishments;
if (viewer == null) if (viewer == null)
{ {
punishments = punishedPlayer.punishments().stream().map(PunishmentsEndpoint::hideIp).toList(); punishments = punishedPlayer.punishments().stream().map(punishment -> serialize(punishment, true)).toList();
} }
else else
{ {
punishments = punishedPlayer.punishments().stream().toList(); punishments = punishedPlayer.punishments().stream().map(punishment -> serialize(punishment, false)).toList();
} }
Map<String, Object> player = new LinkedHashMap<>(); Map<String, Object> player = new LinkedHashMap<>();
@@ -71,15 +71,16 @@ public class PunishmentsEndpoint extends AbstractServlet
return JsonResponse.json(response, body); return JsonResponse.json(response, body);
} }
private static Object hideIp(PunishmentView punishment) private static Object serialize(PunishmentView punishment, boolean hideIp)
{ {
return new Object() return new Object()
{ {
public final UUID punished = punishment.punished(); public final UUID punished = punishment.punished();
public final UUID punisher = punishment.punisher(); public final UUID punisher = punishment.punisher();
public final String punisherName = punishment.punisherName(); public final Object source = punishment.source();
public final String ip = ""; public final String punisherReference = punishment.punisherReference();
public final String punishedUsername = punishment.punishedUsername(); public final String punisherDisplayName = punishment.punisherDisplayName();
public final String ip = hideIp ? "" : punishment.ip();
public final Object type = punishment.type(); public final Object type = punishment.type();
public final String reason = punishment.reason(); public final String reason = punishment.reason();
public final boolean customTime = punishment.customTime(); public final boolean customTime = punishment.customTime();