107 lines
2.7 KiB
TypeScript
107 lines
2.7 KiB
TypeScript
|
|
"use client";
|
||
|
|
|
||
|
|
import { useState, useEffect, useCallback, useSyncExternalStore } from "react";
|
||
|
|
|
||
|
|
// Tipos para las configuraciones
|
||
|
|
export type ThemeMode = "light" | "dark" | "system";
|
||
|
|
export type DefaultView = "grid" | "list";
|
||
|
|
|
||
|
|
export interface AppSettings {
|
||
|
|
// Apariencia
|
||
|
|
theme: ThemeMode;
|
||
|
|
compactMode: boolean;
|
||
|
|
showAnimations: boolean;
|
||
|
|
|
||
|
|
// Proyectos
|
||
|
|
defaultView: DefaultView;
|
||
|
|
showCompletedProjects: boolean;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Valores por defecto
|
||
|
|
export const DEFAULT_SETTINGS: AppSettings = {
|
||
|
|
theme: "system",
|
||
|
|
compactMode: false,
|
||
|
|
showAnimations: true,
|
||
|
|
defaultView: "grid",
|
||
|
|
showCompletedProjects: true,
|
||
|
|
};
|
||
|
|
|
||
|
|
// Clave para localStorage
|
||
|
|
const SETTINGS_KEY = "app-settings";
|
||
|
|
|
||
|
|
// Store global para sincronizar entre componentes
|
||
|
|
let globalSettings: AppSettings = DEFAULT_SETTINGS;
|
||
|
|
const listeners = new Set<() => void>();
|
||
|
|
|
||
|
|
// Notificar a todos los listeners cuando cambian las settings
|
||
|
|
function emitChange() {
|
||
|
|
listeners.forEach((listener) => listener());
|
||
|
|
}
|
||
|
|
|
||
|
|
// Helper para obtener settings de localStorage
|
||
|
|
function getStoredSettings(): AppSettings {
|
||
|
|
if (typeof window === "undefined") return DEFAULT_SETTINGS;
|
||
|
|
try {
|
||
|
|
const stored = localStorage.getItem(SETTINGS_KEY);
|
||
|
|
if (stored) {
|
||
|
|
return { ...DEFAULT_SETTINGS, ...JSON.parse(stored) };
|
||
|
|
}
|
||
|
|
} catch (error) {
|
||
|
|
console.error("Error loading settings:", error);
|
||
|
|
}
|
||
|
|
return DEFAULT_SETTINGS;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Inicializar settings globales
|
||
|
|
if (typeof window !== "undefined") {
|
||
|
|
globalSettings = getStoredSettings();
|
||
|
|
}
|
||
|
|
|
||
|
|
// Subscribe function para useSyncExternalStore
|
||
|
|
function subscribe(listener: () => void) {
|
||
|
|
listeners.add(listener);
|
||
|
|
return () => listeners.delete(listener);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Snapshot function para useSyncExternalStore
|
||
|
|
function getSnapshot() {
|
||
|
|
return globalSettings;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Server snapshot
|
||
|
|
function getServerSnapshot() {
|
||
|
|
return DEFAULT_SETTINGS;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Hook para gestionar configuraciones de la aplicación
|
||
|
|
* Usa useSyncExternalStore para sincronizar entre componentes
|
||
|
|
*/
|
||
|
|
export function useAppSettings() {
|
||
|
|
const settings = useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
||
|
|
|
||
|
|
// Actualizar configuraciones
|
||
|
|
const updateSettings = useCallback((updates: Partial<AppSettings>) => {
|
||
|
|
globalSettings = { ...globalSettings, ...updates };
|
||
|
|
try {
|
||
|
|
localStorage.setItem(SETTINGS_KEY, JSON.stringify(globalSettings));
|
||
|
|
} catch (error) {
|
||
|
|
console.error("Error saving settings:", error);
|
||
|
|
}
|
||
|
|
emitChange();
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
// Resetear a valores por defecto
|
||
|
|
const resetSettings = useCallback(() => {
|
||
|
|
globalSettings = DEFAULT_SETTINGS;
|
||
|
|
try {
|
||
|
|
localStorage.removeItem(SETTINGS_KEY);
|
||
|
|
} catch (error) {
|
||
|
|
console.error("Error resetting settings:", error);
|
||
|
|
}
|
||
|
|
emitChange();
|
||
|
|
}, []);
|
||
|
|
|
||
|
|
return { settings, updateSettings, resetSettings, isLoaded: true };
|
||
|
|
}
|