Files
BaraBingo/components/AuthProvider.tsx
SlavaVlad 05677924b5
Some checks failed
Deploy / build-and-deploy (push) Failing after 2m53s
V1 bingo
2026-06-14 21:29:43 +03:00

80 lines
2.2 KiB
TypeScript

"use client";
import { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from "react";
type User = { id: string; nickname: string; isAdmin: boolean } | null;
type AuthContext = {
user: User;
login: (nickname: string, password: string) => Promise<string | null>;
register: (nickname: string, password: string) => Promise<string | null>;
logout: () => Promise<void>;
loading: boolean;
refetch: () => Promise<void>;
};
const ctx = createContext<AuthContext>({
user: null,
login: async () => null,
register: async () => null,
logout: async () => {},
loading: true,
refetch: async () => {},
});
export function AuthProvider({ children }: { children: ReactNode }) {
const [user, setUser] = useState<User>(null);
const [loading, setLoading] = useState(true);
const refetch = useCallback(async () => {
try {
const res = await fetch("/api/auth/me");
const data = await res.json();
setUser(data.user);
} catch {
setUser(null);
} finally {
setLoading(false);
}
}, []);
useEffect(() => { refetch(); }, [refetch]);
const login = async (nickname: string, password: string): Promise<string | null> => {
const res = await fetch("/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ nickname, password }),
});
const data = await res.json();
if (data.error) return data.error;
setUser(data);
return null;
};
const register = async (nickname: string, password: string): Promise<string | null> => {
const res = await fetch("/api/auth/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ nickname, password }),
});
const data = await res.json();
if (data.error) return data.error;
const loginErr = await login(nickname, password);
return loginErr;
};
const logout = async () => {
await fetch("/api/auth/login", { method: "DELETE" });
setUser(null);
};
return (
<ctx.Provider value={{ user, login, register, logout, loading, refetch }}>
{children}
</ctx.Provider>
);
}
export const useAuth = () => useContext(ctx);