diff --git a/src/hooks/useAuth.ts b/src/hooks/useAuth.ts new file mode 100644 index 0000000..b0ad7a6 --- /dev/null +++ b/src/hooks/useAuth.ts @@ -0,0 +1,24 @@ +import { useState, useCallback } from 'react'; +import { apiClient } from '../api/client'; + +export function useAuth() { + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + const login = useCallback(async (email: string, password: string) => { + setLoading(true); + setError(null); + try { + const { data } = await apiClient.post('/v1/auth/login', { email, password }); + localStorage.setItem('access_token', data.token); + return true; + } catch (e: unknown) { + setError(e instanceof Error ? e.message : 'Login failed'); + return false; + } finally { + setLoading(false); + } + }, []); + + return { login, loading, error }; +} diff --git a/src/pages/Dashboard.tsx b/src/pages/Dashboard.tsx new file mode 100644 index 0000000..88d95ca --- /dev/null +++ b/src/pages/Dashboard.tsx @@ -0,0 +1,29 @@ +import React from 'react'; +import { useQuery } from '@tanstack/react-query'; +import { apiClient } from '../api/client'; +import { LoadingSpinner } from '../components/LoadingSpinner'; + +interface User { id: string; username: string; email: string; } + +export const Dashboard: React.FC = () => { + const { data: users, isLoading } = useQuery({ + queryKey: ['users'], + queryFn: () => apiClient.get('/v1/users').then(r => r.data), + }); + + return ( +
+

Dashboard

+ {isLoading ? : ( + + + + {users?.map(u => ( + + ))} + +
UsernameEmail
{u.username}{u.email}
+ )} +
+ ); +};