diff --git a/src/components/theme-customizer/index.tsx b/src/components/theme-customizer/index.tsx index c719243..2e1482e 100644 --- a/src/components/theme-customizer/index.tsx +++ b/src/components/theme-customizer/index.tsx @@ -9,6 +9,7 @@ import { useThemeManager } from '@/hooks/use-theme-manager' import { useTheme } from '@/hooks/use-theme' import { useSidebarConfig } from '@/contexts/sidebar-context' import { tweakcnThemes } from '@/config/theme-data' +import { toast } from 'sonner' import { saveUserPrefsAction } from '@/lib/appwrite/user-prefs-actions' import type { UserPrefs as ThemePrefs } from '@/lib/appwrite/user-prefs-actions' import { getLocalThemePrefs, saveLocalThemePrefs } from '@/lib/local-theme-prefs' @@ -58,6 +59,12 @@ export function ThemeCustomizer({ open, onOpenChange, initialPrefs }: ThemeCusto }) }, [sidebarConfig.variant, sidebarConfig.collapsible, sidebarConfig.side]) + const savePrefs = (update: Parameters[0]) => { + saveUserPrefsAction(update).then((res) => { + if (!res.ok) toast.error("Tercihler kaydedilemedi: " + res.error) + }) + } + const handleReset = () => { setSelectedTheme("default") setSelectedTweakcnTheme("") @@ -68,7 +75,7 @@ export function ThemeCustomizer({ open, onOpenChange, initialPrefs }: ThemeCusto applyRadius("0.5rem") updateSidebarConfig({ variant: "inset", collapsible: "offcanvas", side: "left" }) saveLocalThemePrefs({ colorTheme: "default", tweakcnTheme: "", radius: "0.5rem", sidebarVariant: "inset", sidebarCollapsible: "offcanvas", sidebarSide: "left" }) - void saveUserPrefsAction({ colorTheme: "default", tweakcnTheme: "", radius: "0.5rem", sidebarVariant: "inset", sidebarCollapsible: "offcanvas", sidebarSide: "left" }) + savePrefs({ colorTheme: "default", tweakcnTheme: "", radius: "0.5rem", sidebarVariant: "inset", sidebarCollapsible: "offcanvas", sidebarSide: "left" }) } const handleImport = (themeData: ImportedTheme) => { @@ -165,20 +172,20 @@ export function ThemeCustomizer({ open, onOpenChange, initialPrefs }: ThemeCusto setSelectedTheme(value) setSelectedTweakcnTheme("") saveLocalThemePrefs({ colorTheme: value, tweakcnTheme: "" }) - void saveUserPrefsAction({ colorTheme: value, tweakcnTheme: "" }) + savePrefs({ colorTheme: value, tweakcnTheme: "" }) }} selectedTweakcnTheme={selectedTweakcnTheme} setSelectedTweakcnTheme={(value) => { setSelectedTweakcnTheme(value) setSelectedTheme("") saveLocalThemePrefs({ tweakcnTheme: value, colorTheme: "" }) - void saveUserPrefsAction({ tweakcnTheme: value, colorTheme: "" }) + savePrefs({ tweakcnTheme: value, colorTheme: "" }) }} selectedRadius={selectedRadius} setSelectedRadius={(value) => { setSelectedRadius(value) saveLocalThemePrefs({ radius: value }) - void saveUserPrefsAction({ radius: value }) + savePrefs({ radius: value }) }} setImportedTheme={setImportedTheme} onImportClick={handleImportClick} diff --git a/src/lib/appwrite/user-prefs-actions.ts b/src/lib/appwrite/user-prefs-actions.ts index e3eb364..d10f4c8 100644 --- a/src/lib/appwrite/user-prefs-actions.ts +++ b/src/lib/appwrite/user-prefs-actions.ts @@ -30,11 +30,12 @@ export async function getUserPrefs(): Promise { if (result.rows.length === 0) return {}; const row = result.rows[0] as Record; + const str = (v: unknown) => (v && typeof v === "string" ? v : undefined); return { theme: (row.theme as UserPrefs["theme"]) ?? undefined, - colorTheme: (row.colorTheme as string) ?? undefined, - tweakcnTheme: (row.tweakcnTheme as string) ?? undefined, - radius: (row.radius as string) ?? undefined, + colorTheme: str(row.colorTheme), + tweakcnTheme: str(row.tweakcnTheme), + radius: str(row.radius), sidebarVariant: (row.sidebarVariant as UserPrefs["sidebarVariant"]) ?? undefined, sidebarCollapsible: (row.sidebarCollapsible as UserPrefs["sidebarCollapsible"]) ?? undefined, sidebarSide: (row.sidebarSide as UserPrefs["sidebarSide"]) ?? undefined, @@ -44,18 +45,21 @@ export async function getUserPrefs(): Promise { } } -export async function saveUserPrefsAction(update: Partial): Promise { +export async function saveUserPrefsAction( + update: Partial, +): Promise<{ ok: boolean; error?: string }> { try { const { account } = await createSessionClient(); const user = await account.get(); const { tablesDB } = createAdminClient(); - // Sadece tanımlı (undefined olmayan) alanları yaz + // undefined → skip, "" → null (Appwrite rejects empty strings on nullable attrs) const clean: Record = {}; for (const [k, v] of Object.entries(update)) { - if (v !== undefined) clean[k] = v; + if (v === undefined) continue; + clean[k] = v === "" ? null : v; } - if (Object.keys(clean).length === 0) return; + if (Object.keys(clean).length === 0) return { ok: true }; const existing = await tablesDB.listRows({ databaseId: DATABASE_ID, @@ -85,7 +89,11 @@ export async function saveUserPrefsAction(update: Partial): Promise