Files
CRM-LeadRadar/apps/web/src/hooks.ts
T
yuriandClaude Opus 5.5 9749da5ae7 Lead Radar: исходный код
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-25 23:11:04 +04:00

45 lines
1.6 KiB
TypeScript

import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import { api, ApiError, type Me } from './api.ts';
export const ME_KEY = ['me'] as const;
/** Текущий пользователь; null — не вошёл. */
export function useMe() {
return useQuery({
queryKey: ME_KEY,
queryFn: async (): Promise<Me | null> => {
try {
return await api<Me>('/me');
} catch (e) {
if (e instanceof ApiError && e.status === 401) return null;
throw e;
}
},
});
}
/** Мутация, после которой перечитываются указанные запросы (по умолчанию — все). */
export function useAction<TArgs = void, TResult = unknown>(
fn: (args: TArgs) => Promise<TResult>,
invalidate?: readonly unknown[],
) {
const qc = useQueryClient();
return useMutation({
mutationFn: fn,
onSuccess: () => qc.invalidateQueries(invalidate ? { queryKey: invalidate } : undefined),
});
}
export type Theme = 'dark' | 'light';
export function useTheme(): [Theme, () => void] {
const [theme, setTheme] = useState<Theme>(() => (localStorage.getItem('lr_theme') === 'light' ? 'light' : 'dark'));
useEffect(() => {
document.documentElement.dataset.theme = theme;
localStorage.setItem('lr_theme', theme);
document.querySelector('meta[name="theme-color"]')?.setAttribute('content', theme === 'light' ? '#f6f8fb' : '#020617');
}, [theme]);
return [theme, () => setTheme((v) => (v === 'dark' ? 'light' : 'dark'))];
}