feat: implement My Account page
Add /account route showing display name (from localStorage), role badge, session expiry decoded from JWT, and recovery PIN display with copy button. Join and recover flows now persist display_name to localStorage via setAuth(). Feed header logout button replaced with person-icon link to /account; logout is available from the account page. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@ import { browser } from '$app/environment';
|
||||
const TOKEN_KEY = 'eventsnap_jwt';
|
||||
const PIN_KEY = 'eventsnap_pin';
|
||||
const USER_ID_KEY = 'eventsnap_user_id';
|
||||
const DISPLAY_NAME_KEY = 'eventsnap_display_name';
|
||||
|
||||
export const isAuthenticated = writable(false);
|
||||
|
||||
@@ -22,11 +23,28 @@ export function getUserId(): string | null {
|
||||
return localStorage.getItem(USER_ID_KEY);
|
||||
}
|
||||
|
||||
export function setAuth(jwt: string, pin: string | null, userId: string): void {
|
||||
export function getDisplayName(): string | null {
|
||||
if (!browser) return null;
|
||||
return localStorage.getItem(DISPLAY_NAME_KEY);
|
||||
}
|
||||
|
||||
export function getExpiry(): Date | null {
|
||||
const token = getToken();
|
||||
if (!token) return null;
|
||||
try {
|
||||
const payload = JSON.parse(atob(token.split('.')[1]));
|
||||
return payload.exp ? new Date(payload.exp * 1000) : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function setAuth(jwt: string, pin: string | null, userId: string, displayName?: string): void {
|
||||
if (!browser) return;
|
||||
localStorage.setItem(TOKEN_KEY, jwt);
|
||||
if (pin) localStorage.setItem(PIN_KEY, pin);
|
||||
localStorage.setItem(USER_ID_KEY, userId);
|
||||
if (displayName) localStorage.setItem(DISPLAY_NAME_KEY, displayName);
|
||||
isAuthenticated.set(true);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user