mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-11 12:09:03 +00:00
Merge pull request #642 from kaitranntt/kai/fix/home-route-no-last-restore
fix(ui): keep home route at root without last-route redirect
This commit is contained in:
3 files changed
+36
-40
No files matched your search
+2
-12
@@ -1,5 +1,5 @@
|
||||
import { lazy, Suspense } from 'react';
|
||||
import { BrowserRouter, Navigate, Routes, Route } from 'react-router-dom';
|
||||
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
||||
import { QueryClientProvider } from '@tanstack/react-query';
|
||||
import { Toaster } from 'sonner';
|
||||
import { queryClient } from '@/lib/query-client';
|
||||
@@ -8,7 +8,6 @@ import { PrivacyProvider } from '@/contexts/privacy-context';
|
||||
import { AuthProvider } from '@/contexts/auth-context';
|
||||
import { RequireAuth } from '@/components/auth/require-auth';
|
||||
import { Layout } from '@/components/layout/layout';
|
||||
import { getStoredLastRoute, shouldRestoreRoute } from '@/lib/last-route';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
|
||||
// Eager load: HomePage (initial route) + LoginPage (auth flow)
|
||||
@@ -48,15 +47,6 @@ function PageLoader() {
|
||||
);
|
||||
}
|
||||
|
||||
function HomeEntryRoute() {
|
||||
const lastRoute = getStoredLastRoute();
|
||||
if (shouldRestoreRoute(lastRoute)) {
|
||||
return <Navigate to={lastRoute} replace />;
|
||||
}
|
||||
|
||||
return <HomePage />;
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
@@ -71,7 +61,7 @@ export default function App() {
|
||||
{/* Protected routes: wrapped with RequireAuth */}
|
||||
<Route element={<RequireAuth />}>
|
||||
<Route element={<Layout />}>
|
||||
<Route path="/" element={<HomeEntryRoute />} />
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route
|
||||
path="/analytics"
|
||||
element={
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const LAST_ROUTE_STORAGE_KEY = 'ccs-dashboard:last-route';
|
||||
const NON_RESTORABLE_PATHS = new Set(['/login']);
|
||||
|
||||
export function storeLastRoute(pathname: string, search = '', hash = ''): void {
|
||||
try {
|
||||
@@ -8,30 +7,3 @@ export function storeLastRoute(pathname: string, search = '', hash = ''): void {
|
||||
// Ignore storage failures (private mode, quota, etc.)
|
||||
}
|
||||
}
|
||||
|
||||
export function getStoredLastRoute(): string | null {
|
||||
try {
|
||||
const route = localStorage.getItem(LAST_ROUTE_STORAGE_KEY);
|
||||
if (!route || !route.startsWith('/')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const pathOnly = route.split(/[?#]/, 1)[0];
|
||||
if (NON_RESTORABLE_PATHS.has(pathOnly)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return route;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export function shouldRestoreRoute(route: string | null): route is string {
|
||||
if (!route) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const pathOnly = route.split(/[?#]/, 1)[0];
|
||||
return pathOnly !== '/' && !NON_RESTORABLE_PATHS.has(pathOnly);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { storeLastRoute } from '@/lib/last-route';
|
||||
|
||||
const LAST_ROUTE_STORAGE_KEY = 'ccs-dashboard:last-route';
|
||||
|
||||
describe('storeLastRoute', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('writes pathname with search and hash', () => {
|
||||
storeLastRoute('/accounts', '?tab=auth', '#matrix');
|
||||
|
||||
expect(localStorage.setItem).toHaveBeenCalledWith(
|
||||
LAST_ROUTE_STORAGE_KEY,
|
||||
'/accounts?tab=auth#matrix'
|
||||
);
|
||||
});
|
||||
|
||||
it('writes pathname when search and hash are omitted', () => {
|
||||
storeLastRoute('/health');
|
||||
|
||||
expect(localStorage.setItem).toHaveBeenCalledWith(LAST_ROUTE_STORAGE_KEY, '/health');
|
||||
});
|
||||
|
||||
it('does not throw when localStorage write fails', () => {
|
||||
const setItemSpy = vi.spyOn(Storage.prototype, 'setItem').mockImplementation(() => {
|
||||
throw new Error('quota exceeded');
|
||||
});
|
||||
|
||||
expect(() => storeLastRoute('/providers')).not.toThrow();
|
||||
setItemSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user