105 lines
2.6 KiB
TypeScript
105 lines
2.6 KiB
TypeScript
import { adminPath } from '../../constants';
|
|
import type { NavKey } from '../components/BottomNav';
|
|
|
|
const STORAGE_KEY = 'admin-mobile-tab-history-v2';
|
|
const EXPIRY_MS = 1000 * 60 * 60 * 2; // 2 hours
|
|
|
|
type TabHistory = {
|
|
paths: Partial<Record<NavKey, string>>;
|
|
updatedAt: number;
|
|
};
|
|
|
|
function readHistory(): TabHistory {
|
|
if (typeof window === 'undefined') {
|
|
return { paths: {}, updatedAt: 0 };
|
|
}
|
|
|
|
try {
|
|
const raw = window.localStorage.getItem(STORAGE_KEY);
|
|
if (!raw) {
|
|
return { paths: {}, updatedAt: 0 };
|
|
}
|
|
const parsed = JSON.parse(raw) as TabHistory;
|
|
|
|
// Check for expiry
|
|
if (Date.now() - parsed.updatedAt > EXPIRY_MS) {
|
|
window.localStorage.removeItem(STORAGE_KEY);
|
|
return { paths: {}, updatedAt: 0 };
|
|
}
|
|
|
|
return parsed ?? { paths: {}, updatedAt: 0 };
|
|
} catch {
|
|
return { paths: {}, updatedAt: 0 };
|
|
}
|
|
}
|
|
|
|
function writeHistory(history: TabHistory): void {
|
|
if (typeof window === 'undefined') {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(history));
|
|
} catch {
|
|
// Ignore storage errors.
|
|
}
|
|
}
|
|
|
|
export function setTabHistory(key: NavKey, path: string): void {
|
|
const history = readHistory();
|
|
history.paths[key] = path;
|
|
history.updatedAt = Date.now();
|
|
writeHistory(history);
|
|
}
|
|
|
|
export function getTabHistory(): Partial<Record<NavKey, string>> {
|
|
return readHistory().paths;
|
|
}
|
|
|
|
export function resolveDefaultTarget(key: NavKey, slug?: string | null): string {
|
|
if (key === 'tasks') {
|
|
return slug ? adminPath(`/mobile/events/${slug}/tasks`) : adminPath('/mobile/tasks');
|
|
}
|
|
if (key === 'uploads') {
|
|
return slug ? adminPath(`/mobile/events/${slug}/photos`) : adminPath('/mobile/uploads');
|
|
}
|
|
if (key === 'profile') {
|
|
return adminPath('/mobile/profile');
|
|
}
|
|
return adminPath('/mobile/dashboard');
|
|
}
|
|
|
|
function resolveEventScopedTarget(path: string, slug: string | null | undefined, key: NavKey): string {
|
|
if (!slug) {
|
|
return path;
|
|
}
|
|
|
|
if (key !== 'tasks' && key !== 'uploads') {
|
|
return path;
|
|
}
|
|
|
|
const match = path.match(/\/event-admin\/mobile\/events\/([^/]+)\/(tasks|photos)(?:\/.*)?$/);
|
|
if (!match) {
|
|
return resolveDefaultTarget(key, slug);
|
|
}
|
|
|
|
const storedSlug = match[1];
|
|
if (storedSlug === slug) {
|
|
return path;
|
|
}
|
|
|
|
return resolveDefaultTarget(key, slug);
|
|
}
|
|
|
|
export function resolveTabTarget(key: NavKey, slug?: string | null): string {
|
|
const history = readHistory();
|
|
const stored = history.paths[key];
|
|
const fallback = resolveDefaultTarget(key, slug);
|
|
|
|
if (!stored) {
|
|
return fallback;
|
|
}
|
|
|
|
return resolveEventScopedTarget(stored, slug, key);
|
|
}
|