build auth modal

This commit is contained in:
2026-03-28 01:23:53 -05:00
parent 3761e2cf52
commit 2c128a404e
12 changed files with 360 additions and 41 deletions

View File

@@ -0,0 +1,52 @@
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
interface AuthStatus {
authenticated: boolean;
user?: string;
}
async function fetchMe(): Promise<AuthStatus> {
const res = await fetch('/api/auth/me');
return res.json() as Promise<AuthStatus>;
}
export function useAuth() {
return useQuery({
queryKey: ['auth'],
queryFn: fetchMe,
staleTime: 60_000,
});
}
export function useLogin() {
const qc = useQueryClient();
return useMutation({
mutationFn: async ({ username, password }: { username: string; password: string }) => {
const res = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),
});
if (!res.ok) {
const err = await res.json().catch(() => ({ error: 'Login failed' }));
throw new Error(err.error ?? 'Login failed');
}
return res.json();
},
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['auth'] });
},
});
}
export function useLogout() {
const qc = useQueryClient();
return useMutation({
mutationFn: async () => {
await fetch('/api/auth/logout', { method: 'POST' });
},
onSuccess: () => {
qc.invalidateQueries({ queryKey: ['auth'] });
},
});
}