feat: improve mobile navigation with tap-to-reset and history filtering
This commit is contained in:
@@ -1,24 +1,35 @@
|
||||
import { adminPath } from '../../constants';
|
||||
import type { NavKey } from '../components/BottomNav';
|
||||
|
||||
const STORAGE_KEY = 'admin-mobile-tab-history-v1';
|
||||
const STORAGE_KEY = 'admin-mobile-tab-history-v2';
|
||||
const EXPIRY_MS = 1000 * 60 * 60 * 2; // 2 hours
|
||||
|
||||
type TabHistory = Partial<Record<NavKey, string>>;
|
||||
type TabHistory = {
|
||||
paths: Partial<Record<NavKey, string>>;
|
||||
updatedAt: number;
|
||||
};
|
||||
|
||||
function readHistory(): TabHistory {
|
||||
if (typeof window === 'undefined') {
|
||||
return {};
|
||||
return { paths: {}, updatedAt: 0 };
|
||||
}
|
||||
|
||||
try {
|
||||
const raw = window.localStorage.getItem(STORAGE_KEY);
|
||||
if (!raw) {
|
||||
return {};
|
||||
return { paths: {}, updatedAt: 0 };
|
||||
}
|
||||
const parsed = JSON.parse(raw) as TabHistory;
|
||||
return parsed ?? {};
|
||||
|
||||
// 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 {};
|
||||
return { paths: {}, updatedAt: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,15 +47,16 @@ function writeHistory(history: TabHistory): void {
|
||||
|
||||
export function setTabHistory(key: NavKey, path: string): void {
|
||||
const history = readHistory();
|
||||
history[key] = path;
|
||||
history.paths[key] = path;
|
||||
history.updatedAt = Date.now();
|
||||
writeHistory(history);
|
||||
}
|
||||
|
||||
export function getTabHistory(): TabHistory {
|
||||
return readHistory();
|
||||
export function getTabHistory(): Partial<Record<NavKey, string>> {
|
||||
return readHistory().paths;
|
||||
}
|
||||
|
||||
function resolveDefaultTarget(key: NavKey, slug?: string | null): string {
|
||||
export function resolveDefaultTarget(key: NavKey, slug?: string | null): string {
|
||||
if (key === 'tasks') {
|
||||
return slug ? adminPath(`/mobile/events/${slug}/tasks`) : adminPath('/mobile/tasks');
|
||||
}
|
||||
@@ -81,7 +93,7 @@ function resolveEventScopedTarget(path: string, slug: string | null | undefined,
|
||||
|
||||
export function resolveTabTarget(key: NavKey, slug?: string | null): string {
|
||||
const history = readHistory();
|
||||
const stored = history[key];
|
||||
const stored = history.paths[key];
|
||||
const fallback = resolveDefaultTarget(key, slug);
|
||||
|
||||
if (!stored) {
|
||||
|
||||
Reference in New Issue
Block a user