"use server"; import { eq } from "drizzle-orm"; import { revalidatePath } from "next/cache"; import { db } from "@/lib/db"; import { users } from "@/modules/_core/schema"; import { VALID_PALETTES, VALID_THEME_MODES, VALID_FONT_PAIRS, VALID_DENSITIES, VALID_DASH_LAYOUTS, VALID_CAL_VIEWS, VALID_NAV_STYLES, } from "@/modules/_core/themes"; import type { Palette, ThemeMode, FontPair, Density, DashLayout, CalView, NavStyle, } from "@/modules/_core/themes"; import { getCurrentSession } from "@/lib/session"; import { revokeShareLink } from "@/modules/_core/share"; export interface ThemePatch { palette?: Palette; mode?: ThemeMode; fontPair?: FontPair; density?: Density; dashLayout?: DashLayout; calView?: CalView; navStyle?: NavStyle; } export async function setUserTheme(patch: ThemePatch) { const update: Record = {}; if (patch.palette !== undefined) { if (!VALID_PALETTES.has(patch.palette)) throw new Error("Invalid palette"); update["themePalette"] = patch.palette; } if (patch.mode !== undefined) { if (!VALID_THEME_MODES.has(patch.mode)) throw new Error("Invalid theme mode"); update["themeMode"] = patch.mode; } if (patch.fontPair !== undefined) { if (!VALID_FONT_PAIRS.has(patch.fontPair)) throw new Error("Invalid font pair"); update["themeFontPair"] = patch.fontPair; } if (patch.density !== undefined) { if (!VALID_DENSITIES.has(patch.density)) throw new Error("Invalid density"); update["themeDensity"] = patch.density; } if (patch.dashLayout !== undefined) { if (!VALID_DASH_LAYOUTS.has(patch.dashLayout)) throw new Error("Invalid dashboard layout"); update["themeDashLayout"] = patch.dashLayout; } if (patch.calView !== undefined) { if (!VALID_CAL_VIEWS.has(patch.calView)) throw new Error("Invalid calendar view"); update["themeCalView"] = patch.calView; } if (patch.navStyle !== undefined) { if (!VALID_NAV_STYLES.has(patch.navStyle)) throw new Error("Invalid nav style"); update["themeNavStyle"] = patch.navStyle; } if (Object.keys(update).length === 0) return; const { user } = await getCurrentSession(); await db.update(users).set(update).where(eq(users.id, user.id)); } export async function setCompletionVisibilityHours(hours: number): Promise { const parsed = Number(hours); if (!Number.isInteger(parsed) || parsed < 0 || parsed > 8760) throw new Error("Invalid hours value"); const { user } = await getCurrentSession(); await db.update(users).set({ completionVisibilityHours: parsed }).where(eq(users.id, user.id)); revalidatePath("/settings"); } export async function revokeShareLinkAction(formData: FormData): Promise { const id = formData.get("id"); if (typeof id !== "string") throw new Error("Missing id"); await revokeShareLink(id); revalidatePath("/settings"); }