feat(zustand): add zustand stores for exam, timer and auth

This commit is contained in:
shafin-r
2025-08-31 18:28:01 +06:00
parent 65e3338859
commit 7df2708db7
18 changed files with 352 additions and 106 deletions

90
stores/authStore.ts Normal file
View File

@ -0,0 +1,90 @@
"use client";
import { create } from "zustand";
import { UserData } from "@/types/auth";
import { API_URL } from "@/lib/auth";
// Cookie utilities
const getCookie = (name: string): string | null => {
if (typeof document === "undefined") return null;
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) {
return parts.pop()?.split(";").shift() || null;
}
return null;
};
const setCookie = (
name: string,
value: string | null,
days: number = 7
): void => {
if (typeof document === "undefined") return;
if (value === null) {
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/; SameSite=Strict; Secure`;
} else {
const expires = new Date();
expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000);
document.cookie = `${name}=${value}; expires=${expires.toUTCString()}; path=/; SameSite=Strict; Secure`;
}
};
interface AuthState {
token: string | null;
isLoading: boolean;
user: UserData | null;
setToken: (token: string | null) => void;
fetchUser: () => Promise<void>;
logout: () => void;
initializeAuth: () => Promise<void>;
}
export const useAuthStore = create<AuthState>((set, get) => ({
token: null,
isLoading: true,
user: null,
setToken: (newToken) => {
set({ token: newToken });
setCookie("authToken", newToken);
},
fetchUser: async () => {
const token = get().token;
if (!token) return;
try {
const res = await fetch(`${API_URL}/me/profile/`, {
headers: {
Authorization: `Bearer ${token}`,
},
});
if (!res.ok) throw new Error("Failed to fetch user info");
const data: UserData = await res.json();
set({ user: data });
} catch (err) {
console.error("Error fetching user:", err);
get().logout();
}
},
logout: () => {
set({ token: null, user: null });
setCookie("authToken", null);
},
initializeAuth: async () => {
const storedToken = getCookie("authToken");
if (storedToken) {
set({ token: storedToken });
await get().fetchUser();
}
set({ isLoading: false });
},
}));