UI/UX Polishing: CBT dashboard, sidebar tiers, landing pricing, and exam disclaimer
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user