kaboot/hooks/useUserPreferences.ts

94 lines
2.9 KiB
TypeScript

import { useState, useCallback, useEffect } from 'react';
import toast from 'react-hot-toast';
import { useAuthenticatedFetch } from './useAuthenticatedFetch';
import type { UserPreferences } from '../types';
import { COLOR_SCHEMES } from '../types';
const DEFAULT_PREFERENCES: UserPreferences = {
colorScheme: 'blue',
};
export const applyColorScheme = (schemeId: string) => {
const scheme = COLOR_SCHEMES.find(s => s.id === schemeId) || COLOR_SCHEMES[0];
document.documentElement.style.setProperty('--theme-primary', scheme.primary);
document.documentElement.style.setProperty('--theme-primary-dark', scheme.primaryDark);
document.documentElement.style.setProperty('--theme-primary-darker', scheme.primaryDarker);
};
interface UseUserPreferencesReturn {
preferences: UserPreferences;
hasAIAccess: boolean;
loading: boolean;
saving: boolean;
fetchPreferences: () => Promise<void>;
savePreferences: (prefs: UserPreferences) => Promise<void>;
applyColorScheme: (schemeId: string) => void;
}
export const useUserPreferences = (): UseUserPreferencesReturn => {
const { authFetch, isAuthenticated } = useAuthenticatedFetch();
const [preferences, setPreferences] = useState<UserPreferences>(DEFAULT_PREFERENCES);
const [hasAIAccess, setHasAIAccess] = useState(false);
const [loading, setLoading] = useState(false);
const [saving, setSaving] = useState(false);
const fetchPreferences = useCallback(async () => {
if (!isAuthenticated) return;
setLoading(true);
try {
const response = await authFetch('/api/users/me/preferences');
if (response.ok) {
const data = await response.json();
const prefs: UserPreferences = {
colorScheme: data.colorScheme || 'blue',
geminiApiKey: data.geminiApiKey || undefined,
};
setPreferences(prefs);
setHasAIAccess(data.hasAIAccess || false);
applyColorScheme(prefs.colorScheme);
}
} catch {
} finally {
setLoading(false);
}
}, [authFetch, isAuthenticated]);
const savePreferences = useCallback(async (prefs: UserPreferences) => {
setSaving(true);
try {
const response = await authFetch('/api/users/me/preferences', {
method: 'PUT',
body: JSON.stringify(prefs),
});
if (!response.ok) {
throw new Error('Failed to save preferences');
}
setPreferences(prefs);
applyColorScheme(prefs.colorScheme);
toast.success('Preferences saved!');
} catch (err) {
const message = err instanceof Error ? err.message : 'Failed to save preferences';
toast.error(message);
throw err;
} finally {
setSaving(false);
}
}, [authFetch]);
useEffect(() => {
fetchPreferences();
}, [fetchPreferences]);
return {
preferences,
hasAIAccess,
loading,
saving,
fetchPreferences,
savePreferences,
applyColorScheme,
};
};