Redirect app root to login when visiting /generadorexamenesllm without a session.
This fixes the blank page on the base URL by normalizing the no-trailing-slash path in nginx and redirecting unauthenticated users to /login before React mounts.
This commit is contained in:
@@ -50,6 +50,11 @@ server {
|
|||||||
try_files $uri =404;
|
try_files $uri =404;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Raíz sin barra final → login (evita pantalla en blanco por basename)
|
||||||
|
location = /generadorexamenesllm {
|
||||||
|
return 301 /generadorexamenesllm/login;
|
||||||
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
try_files $uri $uri/ /index.html;
|
try_files $uri $uri/ /index.html;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import { Navigate, Route, Routes } from "react-router-dom";
|
import { Navigate, Route, Routes } from "react-router-dom";
|
||||||
import Layout from "./components/layout/Layout";
|
import Layout from "./components/layout/Layout";
|
||||||
import ProtectedRoute from "./components/layout/ProtectedRoute";
|
import ProtectedRoute from "./components/layout/ProtectedRoute";
|
||||||
|
import RootRoute from "./components/layout/RootRoute";
|
||||||
import LoginPage from "./pages/LoginPage";
|
import LoginPage from "./pages/LoginPage";
|
||||||
import RegisterPage from "./pages/RegisterPage";
|
import RegisterPage from "./pages/RegisterPage";
|
||||||
import DashboardPage from "./pages/DashboardPage";
|
|
||||||
import CreateTemplatePage from "./pages/CreateTemplatePage";
|
import CreateTemplatePage from "./pages/CreateTemplatePage";
|
||||||
import TemplateDetailPage from "./pages/TemplateDetailPage";
|
import TemplateDetailPage from "./pages/TemplateDetailPage";
|
||||||
import NotFoundPage from "./pages/NotFoundPage";
|
import NotFoundPage from "./pages/NotFoundPage";
|
||||||
@@ -21,7 +21,7 @@ export default function App() {
|
|||||||
</ProtectedRoute>
|
</ProtectedRoute>
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Route path="/" element={<DashboardPage />} />
|
<Route path="/" element={<RootRoute />} />
|
||||||
<Route path="/plantillas/nueva" element={<CreateTemplatePage />} />
|
<Route path="/plantillas/nueva" element={<CreateTemplatePage />} />
|
||||||
<Route path="/plantillas/:templateId" element={<TemplateDetailPage />} />
|
<Route path="/plantillas/:templateId" element={<TemplateDetailPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import { Navigate } from "react-router-dom";
|
||||||
|
import { useAuth } from "../../context/AuthContext";
|
||||||
|
import { SpinnerCenter } from "../ui/Spinner";
|
||||||
|
import DashboardPage from "../../pages/DashboardPage";
|
||||||
|
|
||||||
|
/** Raíz de la app: login si no hay sesión, dashboard si la hay. */
|
||||||
|
export default function RootRoute() {
|
||||||
|
const { isAuthenticated, loading } = useAuth();
|
||||||
|
|
||||||
|
if (loading) return <SpinnerCenter label="Cargando tu sesión…" />;
|
||||||
|
|
||||||
|
if (!isAuthenticated) {
|
||||||
|
return <Navigate to="/login" replace />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <DashboardPage />;
|
||||||
|
}
|
||||||
@@ -4,8 +4,11 @@ import { BrowserRouter } from "react-router-dom";
|
|||||||
import App from "./App";
|
import App from "./App";
|
||||||
import { AuthProvider } from "./context/AuthContext";
|
import { AuthProvider } from "./context/AuthContext";
|
||||||
import { ToastProvider } from "./context/ToastContext";
|
import { ToastProvider } from "./context/ToastContext";
|
||||||
|
import { redirectRootToLoginIfNeeded } from "./utils/redirectRoot";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|
||||||
|
redirectRootToLoginIfNeeded();
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById("root")).render(
|
ReactDOM.createRoot(document.getElementById("root")).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<BrowserRouter basename={import.meta.env.BASE_URL}>
|
<BrowserRouter basename={import.meta.env.BASE_URL}>
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
const TOKEN_KEY = "genex_token";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Si el usuario entra en la raíz de la app sin sesión, redirige a /login
|
||||||
|
* antes de montar React (evita pantalla en blanco por basename sin barra final).
|
||||||
|
*/
|
||||||
|
export function redirectRootToLoginIfNeeded() {
|
||||||
|
const base = import.meta.env.BASE_URL || "/";
|
||||||
|
const baseNoSlash = base.replace(/\/$/, "");
|
||||||
|
const { pathname, search, hash } = window.location;
|
||||||
|
const normalizedPath = pathname.replace(/\/$/, "") || "/";
|
||||||
|
|
||||||
|
const isAppRoot =
|
||||||
|
normalizedPath === baseNoSlash ||
|
||||||
|
normalizedPath === "/" ||
|
||||||
|
pathname === base;
|
||||||
|
|
||||||
|
if (!isAppRoot) return;
|
||||||
|
if (localStorage.getItem(TOKEN_KEY)) return;
|
||||||
|
|
||||||
|
const loginUrl = `${baseNoSlash}/login${search}${hash}`;
|
||||||
|
if (pathname + search + hash !== `${baseNoSlash}/login${search}${hash}`) {
|
||||||
|
window.location.replace(loginUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user