Files
kickkingsadmin/src/lib/dashboard-search-url.ts
T
2026-07-26 18:31:43 +00:00

99 lines
3.5 KiB
TypeScript

import type { MatchmakerLogSource } from "@/lib/matchmaker-log-source";
import { DEFAULT_LEDGER_PAGE_SIZE } from "@/lib/ledger-table-view";
export type AdminDashboardTab =
| "dashboard"
| "players"
| "matches"
| "matchmaker"
| "ledger"
| "analysis"
| "logs";
export type DashboardUrlQuery = {
tab: AdminDashboardTab;
highlightId: string | null;
participantRaw: string | null;
editId?: number | null;
saveError?: boolean;
/** Ledger: failed system supply action */
supplyError?: boolean;
/** When tab is matchmaker: `raw` selects matchmaker.log; omit or processed → history.log */
matchmakerSource?: MatchmakerLogSource | null;
/** Ledger tab: UTC date-only bounds (`lfrom` / `lto` query params). */
ledgerFrom?: string | null;
ledgerTo?: string | null;
ledgerPage?: number | null;
/** Ledger rows per page (`lsize`); omitted from URL when equal to default. */
ledgerPageSize?: number | null;
ledgerSort?: string | null;
ledgerOrder?: "asc" | "desc" | null;
/** Analysis tab: UTC date-only bounds (`afrom` / `ato`). */
analysisFrom?: string | null;
analysisTo?: string | null;
/** Analysis tab: comma-separated player ids (`aplayers`). */
analysisPlayers?: string | null;
/** Matches tab: local date-only bounds (`mfrom` / `mto`) + tz offset minutes (`mtz`). */
matchesFrom?: string | null;
matchesTo?: string | null;
matchesTzOffsetMinutes?: number | null;
};
/** Build `/?…` for dashboard tabs, filters, and optional edit / error flags. */
export function buildDashboardHref(q: DashboardUrlQuery): string {
const p = new URLSearchParams();
if (q.tab === "matches") p.set("tab", "matches");
else if (q.tab === "players") p.set("tab", "players");
else if (q.tab === "matchmaker") p.set("tab", "matchmaker");
else if (q.tab === "ledger") p.set("tab", "ledger");
else if (q.tab === "analysis") p.set("tab", "analysis");
else if (q.tab === "logs") p.set("tab", "logs");
if (q.highlightId) p.set("highlight", q.highlightId);
if (q.participantRaw) p.set("participant", q.participantRaw);
if (q.tab === "matchmaker" && q.matchmakerSource === "raw") {
p.set("mklog", "raw");
}
if (q.tab === "ledger") {
if (q.ledgerFrom) p.set("lfrom", q.ledgerFrom);
if (q.ledgerTo) p.set("lto", q.ledgerTo);
if (
q.ledgerPage != null &&
Number.isFinite(q.ledgerPage) &&
Math.trunc(q.ledgerPage) > 1
) {
p.set("lpage", String(Math.trunc(q.ledgerPage)));
}
if (q.ledgerSort) p.set("lsort", q.ledgerSort);
if (q.ledgerOrder) p.set("lorder", q.ledgerOrder);
if (
q.ledgerPageSize != null &&
Number.isFinite(q.ledgerPageSize) &&
Math.trunc(q.ledgerPageSize) !== DEFAULT_LEDGER_PAGE_SIZE
) {
p.set("lsize", String(Math.trunc(q.ledgerPageSize)));
}
}
if (q.tab === "analysis") {
if (q.analysisFrom) p.set("afrom", q.analysisFrom);
if (q.analysisTo) p.set("ato", q.analysisTo);
if (q.analysisPlayers) p.set("aplayers", q.analysisPlayers);
}
if (q.tab === "matches") {
if (q.matchesFrom) p.set("mfrom", q.matchesFrom);
if (q.matchesTo) p.set("mto", q.matchesTo);
if (
q.matchesTzOffsetMinutes != null &&
Number.isFinite(q.matchesTzOffsetMinutes)
) {
p.set("mtz", String(Math.trunc(q.matchesTzOffsetMinutes)));
}
}
if (q.editId != null && Number.isFinite(q.editId)) {
p.set("edit", String(q.editId));
}
if (q.saveError) p.set("saveError", "1");
if (q.supplyError) p.set("supplyErr", "1");
const s = p.toString();
return s ? `/?${s}` : "/";
}