Files
EpicNext-Cms/src/app/admin/sounds/page.tsx
T
openhands df38dccbf1
Local Build and Deploy / deploy (push) Failing after 46s
style: format code biome
2026-07-13 21:57:41 +02:00

90 lines
2.3 KiB
TypeScript

import { redirect } from "next/navigation";
import { canAccess, getAdminContext, PERMS } from "@/lib/permissions";
import { prisma } from "@/lib/prisma";
import { siteSettings } from "@/lib/services/site-settings";
import {
DEFAULT_SOUNDTRACK_BASE_URL,
parseTrackSamples,
} from "@/lib/services/soundtracks";
import { SoundsClient } from "./sounds-client";
export default async function SoundsPage() {
const { session, permissions } = await getAdminContext();
if (!canAccess(permissions, PERMS.CATALOG_VIEW, session.user.rank)) {
redirect("/admin");
}
const canEdit = canAccess(permissions, PERMS.CATALOG_EDIT, session.user.rank);
const [rows, usage, baseUrlSetting] = await Promise.all([
prisma.soundtracks.findMany({
orderBy: { id: "asc" },
select: {
id: true,
code: true,
name: true,
author: true,
length: true,
track: true,
},
}),
prisma.catalogItems.groupBy({
by: ["songId"],
where: { songId: { gt: 0 } },
_count: { _all: true },
}),
siteSettings.get("soundtrack_base_url", DEFAULT_SOUNDTRACK_BASE_URL),
]);
const usageMap: Record<number, number> = {};
for (const row of usage) {
if (row.songId != null) usageMap[row.songId] = row._count._all;
}
const soundtracks = rows.map((r) => {
const samples = parseTrackSamples(r.track);
return {
id: r.id,
code: r.code,
name: r.name,
author: r.author,
length: r.length,
track: r.track,
samples,
kind: (samples.length > 0 ? "composition" : "single") as
| "composition"
| "single",
usedBy: usageMap[r.id] ?? 0,
};
});
// Normalize: ensure trailing slash so ${base}${code}.mp3 yields a valid URL.
const configuredBaseUrl = baseUrlSetting ?? "/sounds/";
const baseUrl = configuredBaseUrl.endsWith("/")
? configuredBaseUrl
: `${configuredBaseUrl}/`;
return (
<div className="space-y-6">
<div>
<h1 className="text-3xl font-bold tracking-tight">Song Disks</h1>
<p className="text-muted-foreground">
Carica e gestisci i file MP3 dei song disk riprodotti dai jukebox
in-game. I file sono serviti da <code>{baseUrl}</code> (configurabile
in{" "}
<a href="/admin/settings/cms" className="underline">
Impostazioni &gt; CMS
</a>
).
</p>
</div>
<SoundsClient
soundtracks={soundtracks}
canEdit={canEdit}
baseUrl={baseUrl}
/>
</div>
);
}