songs page init
This commit is contained in:
78
src/routes/songs/+page.ts
Normal file
78
src/routes/songs/+page.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { z } from "zod";
|
||||
import type { SongFilters } from "$lib/db/client-db";
|
||||
import { db, ensureSeeded, getSongsWithFilters } from "$lib/db/client-db";
|
||||
import {
|
||||
SongCategoryMap,
|
||||
SongTypeMap,
|
||||
SongTypeReverseMap,
|
||||
} from "$lib/utils/amq";
|
||||
import type { PageLoad } from "./$types";
|
||||
|
||||
const SearchSchema = z
|
||||
.object({
|
||||
q: z.string().optional(), // song name
|
||||
artist: z.string().optional(), // artist name
|
||||
anime: z.string().optional(), // anime mainName
|
||||
type: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((s) => {
|
||||
if (!s) return undefined;
|
||||
return s
|
||||
.split(",")
|
||||
.map((t) => SongTypeMap[t.trim().toUpperCase()])
|
||||
.filter((n) => n !== undefined);
|
||||
}),
|
||||
gpm: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((s) => (s ? parseInt(s, 10) : undefined)), // global percent min
|
||||
gpx: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((s) => (s ? parseInt(s, 10) : undefined)), // global percent max
|
||||
cat: z
|
||||
.string()
|
||||
.optional()
|
||||
.transform((s) => (s ? parseInt(s, 10) : undefined)), // category
|
||||
})
|
||||
.strict();
|
||||
|
||||
export const load: PageLoad = async ({ url, fetch, depends }) => {
|
||||
depends("clientdb:songs");
|
||||
|
||||
const parsed = SearchSchema.safeParse(
|
||||
Object.fromEntries(url.searchParams.entries()),
|
||||
);
|
||||
|
||||
const filters: SongFilters = {};
|
||||
if (parsed.success) {
|
||||
if (parsed.data.q) filters.songName = parsed.data.q;
|
||||
if (parsed.data.artist) filters.artistName = parsed.data.artist;
|
||||
if (parsed.data.anime) filters.animeName = parsed.data.anime;
|
||||
if (parsed.data.type && parsed.data.type.length > 0)
|
||||
filters.songTypes = parsed.data.type;
|
||||
if (parsed.data.gpm !== undefined)
|
||||
filters.globalPercentMin = parsed.data.gpm;
|
||||
if (parsed.data.gpx !== undefined)
|
||||
filters.globalPercentMax = parsed.data.gpx;
|
||||
if (parsed.data.cat !== undefined) filters.category = parsed.data.cat;
|
||||
}
|
||||
|
||||
// Client-only DB: on the server `db` is null, so return [] and let hydration re-run load in browser.
|
||||
if (!db) {
|
||||
return {
|
||||
filters: parsed.success ? parsed.data : {}, // Return original parsed data for form state
|
||||
songRows: [],
|
||||
};
|
||||
}
|
||||
|
||||
await ensureSeeded({ fetch });
|
||||
|
||||
const songRows = await getSongsWithFilters(db, filters);
|
||||
|
||||
return {
|
||||
filters: parsed.success ? parsed.data : {}, // Return original parsed data for form state
|
||||
songRows,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user