UI/UX Polishing: CBT dashboard, sidebar tiers, landing pricing, and exam disclaimer

This commit is contained in:
2026-07-09 17:05:40 +05:30
parent b80d73ec26
commit 22b167b985
15 changed files with 481 additions and 202 deletions

View File

@@ -15,7 +15,10 @@ export interface UserProfile {
state: string;
tier: "Free" | "Pro" | "Al_Coach"; // Al_Coach in database schema
streak_count: number;
streak_count: number;
longest_streak: number;
active_session_token?: string;
created_at?: string;
}
export const DEFAULT_USER_ID = "b0e17378-864d-439e-8806-708dc48a891b"; // AI Coach
@@ -50,7 +53,20 @@ export function useActiveUser() {
return;
}
const data = await res.json();
setUser(data);
// Single Active Session Check
if (typeof window !== 'undefined') {
const localToken = localStorage.getItem("active_session_token");
if (data.active_session_token && localToken && data.active_session_token !== localToken) {
localStorage.removeItem("activeUserId");
localStorage.removeItem("active_session_token");
alert("Your account was logged in from another device. You have been logged out.");
window.location.href = "/";
return;
}
}
setUser(data);
} catch (err: any) {
console.error("Error fetching active user profile:", err);
setError(err.message || "Failed to load user");
@@ -71,11 +87,33 @@ export function useActiveUser() {
if (typeof window === "undefined") return;
const handleUpdate = () => fetchUserProfile(userId);
window.addEventListener('pragativeer-user-updated', handleUpdate);
return () => window.removeEventListener('pragativeer-user-updated', handleUpdate);
// Poll every 10 seconds for session validity
const interval = setInterval(() => {
fetchUserProfile(userId);
}, 10000);
return () => {
window.removeEventListener('pragativeer-user-updated', handleUpdate);
clearInterval(interval);
};
}, [userId, fetchUserProfile]);
const switchUser = useCallback((newId: string) => {
const switchUser = useCallback(async (newId: string) => {
if (typeof window !== "undefined") {
const sessionToken = crypto.randomUUID();
localStorage.setItem("active_session_token", sessionToken);
try {
await fetch(`/api/users/${newId}/session`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ session_token: sessionToken })
});
} catch (err) {
console.error("Failed to set session", err);
}
localStorage.setItem("activeUserId", newId);
setUserIdState(newId);
window.location.reload();