diff --git a/app/src/hooks/useAdminData.js b/app/src/hooks/useAdminData.js deleted file mode 100644 index 6357be3..0000000 --- a/app/src/hooks/useAdminData.js +++ /dev/null @@ -1,48 +0,0 @@ -import { useState, useEffect } from 'react'; -import { notifications } from '@mantine/notifications'; -import { getUsers, getWorkspaces, getSystemStats } from '../api/admin'; - -// Hook for admin data fetching (stats and workspaces) -export const useAdminData = (type) => { - const [data, setData] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - - const loadData = async () => { - setLoading(true); - setError(null); - try { - let response; - switch (type) { - case 'stats': - response = await getSystemStats(); - break; - case 'workspaces': - response = await getWorkspaces(); - break; - case 'users': - response = await getUsers(); - break; - default: - throw new Error('Invalid data type'); - } - setData(response); - } catch (err) { - const message = err.response?.data?.error || err.message; - setError(message); - notifications.show({ - title: 'Error', - message: `Failed to load ${type}: ${message}`, - color: 'red', - }); - } finally { - setLoading(false); - } - }; - - useEffect(() => { - loadData(); - }, [type]); - - return { data, loading, error, reload: loadData }; -}; diff --git a/app/src/hooks/useAdminData.ts b/app/src/hooks/useAdminData.ts new file mode 100644 index 0000000..36bb66c --- /dev/null +++ b/app/src/hooks/useAdminData.ts @@ -0,0 +1,91 @@ +import { useState, useEffect } from 'react'; +import { notifications } from '@mantine/notifications'; +import { getUsers, getWorkspaces, getSystemStats } from '@/api/admin'; +import { SystemStats } from '@/types/adminApi'; +import { Workspace } from '@/types/workspace'; +import { User } from '@/types/authApi'; + +// Possible types of admin data +type AdminDataType = 'stats' | 'workspaces' | 'users'; + +// Define the return data type based on the requested data type +type AdminData = T extends 'stats' + ? SystemStats + : T extends 'workspaces' + ? Workspace[] + : T extends 'users' + ? User[] + : never; + +// Define the return type of the hook +interface AdminDataResult { + data: AdminData; + loading: boolean; + error: string | null; + reload: () => Promise; +} + +// Hook for admin data fetching (stats and workspaces) +export const useAdminData = ( + type: T +): AdminDataResult => { + // Initialize with the appropriate empty type + const getInitialData = (): AdminData => { + if (type === 'stats') { + return {} as SystemStats as AdminData; + } else if (type === 'workspaces') { + return [] as Workspace[] as AdminData; + } else if (type === 'users') { + return [] as User[] as AdminData; + } else { + // This case should never happen due to type constraints, + // but TypeScript requires us to handle it + return [] as unknown as AdminData; + } + }; + + const [data, setData] = useState>(getInitialData()); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + const loadData = async () => { + setLoading(true); + setError(null); + try { + let response; + switch (type) { + case 'stats': + response = await getSystemStats(); + break; + case 'workspaces': + response = await getWorkspaces(); + break; + case 'users': + response = await getUsers(); + break; + default: + throw new Error('Invalid data type'); + } + setData(response as AdminData); + } catch (err) { + const message = + err instanceof Error + ? (err as any)?.response?.data?.error || err.message + : 'An unknown error occurred'; + setError(message); + notifications.show({ + title: 'Error', + message: `Failed to load ${type}: ${message}`, + color: 'red', + }); + } finally { + setLoading(false); + } + }; + + useEffect(() => { + loadData(); + }, [type]); + + return { data, loading, error, reload: loadData }; +};