diff --git a/src/App.jsx b/src/App.jsx
index b0a8df4..301773a 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -50,56 +50,32 @@ const LayoutWrapper = ({ children, currentPageName }) => Layout ?
{children}
: <>{children}>;
-// Paths that render for anyone, signed in or not, skipping the auth gate below.
-//
-// LandingPage is genuinely public: pure marketing markup, no entity reads, so it
-// needs nothing from Base44. Events is not — it lists Event, Staff and VendorRate,
-// all of which stay behind Base44 auth. Opening the route only removes the login
-// redirect; a signed-out visitor gets the page shell with empty lists, because
-// skipping the gate cannot grant data the backend still refuses to serve.
-const PUBLIC_ROUTES = new Map([
- ['/LandingPage', LandingPage],
- ['/Events', Pages['Events']],
-]);
+// Routes that render for anyone, signed in or not. LandingPage is pure marketing
+// markup — it reads no entities and never touches useAuth — so the only thing the
+// auth gate ever did for it was bounce visitors to a Google login before they
+// could read what the product is. Its CTAs point at /Dashboard, which is still
+// gated, so signing in stays one click away.
+const PUBLIC_ROUTES = new Set(['/LandingPage']);
-const getPublicPage = (pathname) => {
- // Tolerate a trailing slash, and compare case-insensitively so /events lands on
- // the same page as /Events — that is how React Router already matches the gated
- // routes, and a mismatch here would send one casing to login and not the other.
- const trimmed = pathname.length > 1 ? pathname.replace(/\/+$/, '') : pathname;
- const normalized = trimmed.toLowerCase();
- for (const [path, Page] of PUBLIC_ROUTES) {
- if (path.toLowerCase() === normalized) {
- return Page;
- }
- }
- return null;
+const isPublicRoute = (pathname) => {
+ // Tolerate a trailing slash so /LandingPage/ isn't quietly sent to login.
+ const normalized = pathname.length > 1 ? pathname.replace(/\/+$/, '') : pathname;
+ return PUBLIC_ROUTES.has(normalized);
};
-// The bare domain is the front door, so it can't be allowed to bounce anonymous
-// visitors to Google — signed out it shows the marketing page, signed in it shows
-// the dashboard as before.
-const ROOT_PATH = '/';
-
const AuthenticatedApp = () => {
const { isLoadingAuth, isLoadingPublicSettings, authError, isAuthenticated, navigateToLogin } = useAuth();
const location = useLocation();
- // Ahead of both gates below. The spinner would stall these pages on a network
- // round-trip, and the auth gate would redirect away from them — either one
- // defeats the point of a public route. Rendered bare, without LayoutWrapper,
- // so the nav chrome doesn't fire its own authenticated queries here.
- const PublicPage = getPublicPage(location.pathname);
- if (PublicPage) {
- return ;
- }
-
- // Decided on the token rather than on the resolved auth state, so it settles
- // synchronously: a visitor with no session gets the marketing page on the first
- // paint instead of watching a spinner for a bootstrap request whose only
- // possible outcome, for them, is a redirect away.
- if (location.pathname === ROOT_PATH && !appParams.token) {
- return ;
+ // Ahead of both gates below. The spinner would stall this page on a network
+ // round-trip it has no use for, and the auth gate would redirect away from it —
+ // either one defeats the point of a public page.
+ if (isPublicRoute(location.pathname)) {
+ return (
+
+ } />
+
+ );
}
// Show loading spinner while checking app public settings or auth
@@ -116,12 +92,6 @@ const AuthenticatedApp = () => {
if (authError.type === 'user_not_registered') {
return ;
} else if (authError.type === 'auth_required') {
- // Reaching here on the root path means a token existed but is no longer
- // good — expired, revoked, or for another app. Treating that as signed out
- // keeps the front door open instead of trapping it in a login redirect.
- if (location.pathname === ROOT_PATH) {
- return ;
- }
// Redirect to login automatically
navigateToLogin();
return null;