/** * Personal dashboards API hooks (Phase M2/M3). * * Layout shape (validated server-side, DashboardLayout): * { version: 1, tabs: [{ id, name, widgets: [{ app_id, settings, col, row, col_span, row_span }] }] } */ import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { apiGet, apiPost, apiPut, apiDelete } from './client'; export interface DashboardWidget { app_id: string; settings: Record; col: number; row: number; col_span: number; row_span: number; } export interface DashboardTab { id: string; name: string; widgets: DashboardWidget[]; } export interface DashboardLayout { version: number; tabs: DashboardTab[]; } export interface Dashboard { id: string; name: string; layout: DashboardLayout; is_default: boolean; user_id: string; created_at: string | null; updated_at: string | null; } export interface DashboardInput { name: string; } export interface DashboardUpdateInput { name?: string; layout?: DashboardLayout; } export const DASHBOARD_QUERY_KEYS = { all: ['dashboards'] as const, one: (id: string) => ['dashboards', id] as const, }; export function useDashboards() { return useQuery({ queryKey: DASHBOARD_QUERY_KEYS.all, queryFn: () => apiGet('/dashboards'), staleTime: 30 * 1000, }); } export function useCreateDashboard() { const qc = useQueryClient(); return useMutation({ mutationFn: (input: DashboardInput) => apiPost('/dashboards', input), onSuccess: () => qc.invalidateQueries({ queryKey: DASHBOARD_QUERY_KEYS.all }), }); } export function useUpdateDashboard() { const qc = useQueryClient(); return useMutation({ mutationFn: ({ id, input }: { id: string; input: DashboardUpdateInput }) => apiPut(`/dashboards/${id}`, input), onSuccess: (_data, vars) => { qc.invalidateQueries({ queryKey: DASHBOARD_QUERY_KEYS.all }); qc.invalidateQueries({ queryKey: DASHBOARD_QUERY_KEYS.one(vars.id) }); }, }); } export function useDeleteDashboard() { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => apiDelete(`/dashboards/${id}`), onSuccess: () => qc.invalidateQueries({ queryKey: DASHBOARD_QUERY_KEYS.all }), }); } export function useSetDefaultDashboard() { const qc = useQueryClient(); return useMutation({ mutationFn: (id: string) => apiPost(`/dashboards/${id}/set-default`), onSuccess: () => qc.invalidateQueries({ queryKey: DASHBOARD_QUERY_KEYS.all }), }); }