57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
import { prisma } from "@/lib/prisma";
|
|
|
|
// Fallback values used when a setting row is missing OR the DB is unreachable,
|
|
// so the app still renders (e.g. local dev without a DATABASE_URL).
|
|
const DEFAULTS: Record<string, string> = {
|
|
hotel_name: "Atom",
|
|
habbo_imaging_url: "https://epicnabbo.nl/imaging/",
|
|
logo_url: "",
|
|
nitro_client_url: "",
|
|
};
|
|
|
|
/**
|
|
* DB-driven CMS config, mirroring AtomCMS's `setting()` / habbo-next's
|
|
* `siteSettings`. Loads the whole website_settings table into a key→value map,
|
|
* cached in-process, with graceful fallback to DEFAULTS. Booleans are stored as
|
|
* the strings '1' / '0'.
|
|
*/
|
|
class SiteSettings {
|
|
private cache: Map<string, string> | null = null;
|
|
|
|
private async load(): Promise<Map<string, string>> {
|
|
if (this.cache === null) {
|
|
try {
|
|
const rows = await prisma.websiteSetting.findMany({
|
|
select: { key: true, value: true },
|
|
});
|
|
this.cache = new Map(rows.map((r) => [r.key, r.value]));
|
|
} catch {
|
|
// DB unavailable — serve defaults without caching so we retry later.
|
|
return new Map(Object.entries(DEFAULTS));
|
|
}
|
|
}
|
|
return this.cache;
|
|
}
|
|
|
|
async get(key: string, fallback: string | null = null): Promise<string | null> {
|
|
const map = await this.load();
|
|
if (map.has(key)) return map.get(key) as string;
|
|
if (key in DEFAULTS) return DEFAULTS[key] as string;
|
|
return fallback;
|
|
}
|
|
|
|
async getBool(key: string, fallback = false): Promise<boolean> {
|
|
const v = await this.get(key, null);
|
|
if (v === null) return fallback;
|
|
const s = v.toLowerCase();
|
|
return s === "1" || s === "true";
|
|
}
|
|
|
|
/** Invalidate the in-process cache after a settings write. */
|
|
reload(): void {
|
|
this.cache = null;
|
|
}
|
|
}
|
|
|
|
export const siteSettings = new SiteSettings();
|