// src/lib/siteSettings.ts // ───────────────────────────────────────────────────────────────────────────── // Server-only loader for site-wide settings (branding, footer, social). // Reads the SiteSetting key-value table and merges with defaults. // // For pure types and defaults safe to import from client components, // use src/lib/siteSettingsTypes.ts instead. // ───────────────────────────────────────────────────────────────────────────── import "server-only"; import { prisma } from "@/lib/prisma"; import { getLocalizedData } from "@/lib/i18nHelper"; import { DEFAULT_BRANDING, DEFAULT_FOOTER, DEFAULT_SOCIAL, type BrandingSettings, type FooterSettings, type SocialSettings, } from "@/lib/siteSettingsTypes"; export { DEFAULT_BRANDING, DEFAULT_FOOTER, DEFAULT_SOCIAL, type BrandingSettings, type FooterSettings, type SocialSettings, }; function safeParse(json: string | null | undefined, fallback: T): T { if (!json) return fallback; try { return JSON.parse(json) as T; } catch { return fallback; } } async function readSetting(key: string, defaults: T, locale?: string): Promise { try { const row = await prisma.siteSetting.findUnique({ where: { key } }); if (!row) return defaults; const localized = locale ? getLocalizedData(row, locale) : row; const value = safeParse>(localized.valueJson, {} as Partial); return { ...defaults, ...value }; } catch (error) { console.error(`[siteSettings] Failed to read "${key}":`, error); return defaults; } } export const getBranding = (locale?: string) => readSetting("branding", DEFAULT_BRANDING, locale); export const getFooterSettings = (locale?: string) => readSetting("footer", DEFAULT_FOOTER, locale); export const getSocialLinks = (locale?: string) => readSetting("social", DEFAULT_SOCIAL, locale); export async function getAllSettings() { const [branding, footer, social] = await Promise.all([ getBranding(), getFooterSettings(), getSocialLinks(), ]); return { branding, footer, social }; }