Files
PoleDanceApp/web/src/hooks/useAuth.ts
Dianaka123 cf4104069e Refactor: move tokenStorage into lib/api/
It only serves the API client — belongs with the HTTP layer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 21:07:15 +03:00

82 lines
2.0 KiB
TypeScript

import { create } from "zustand";
import { authApi } from "@/lib/api/auth";
import { UserOut } from "@/types/user";
import { saveTokens, getRefreshToken, clearTokens, loadFromStorage } from "@/lib/api/tokenStorage";
interface AuthState {
user: UserOut | null;
isLoading: boolean;
isInitialized: boolean;
initialize: () => Promise<void>;
login: (email: string, password: string) => Promise<void>;
register: (data: {
email: string;
password: string;
full_name: string;
phone?: string;
requested_role?: "member" | "organizer";
organization_name?: string;
instagram_handle?: string;
}) => Promise<"approved" | "pending">;
logout: () => Promise<void>;
setUser: (user: UserOut) => void;
}
export const useAuth = create<AuthState>((set) => ({
user: null,
isLoading: false,
isInitialized: false,
initialize: async () => {
loadFromStorage();
try {
const user = await authApi.me();
set({ user, isInitialized: true });
} catch {
clearTokens();
set({ user: null, isInitialized: true });
}
},
login: async (email, password) => {
set({ isLoading: true });
try {
const data = await authApi.login({ email, password });
saveTokens(data.access_token, data.refresh_token);
set({ user: data.user });
} finally {
set({ isLoading: false });
}
},
register: async (data) => {
set({ isLoading: true });
try {
const res = await authApi.register(data);
if (res.access_token && res.refresh_token) {
saveTokens(res.access_token, res.refresh_token);
set({ user: res.user });
return "approved";
}
return "pending";
} finally {
set({ isLoading: false });
}
},
logout: async () => {
const refresh = getRefreshToken();
if (refresh) {
try {
await authApi.logout(refresh);
} catch {
// clear locally regardless
}
}
clearTokens();
set({ user: null });
},
setUser: (user) => set({ user }),
}));