This commit is contained in:
Andras Schmelczer 2026-05-09 09:26:40 +01:00
parent 701c17a703
commit f114ada255
44 changed files with 5264 additions and 1674 deletions

View file

@ -52,6 +52,10 @@ function PageFallback() {
return <div className="flex-1 bg-warm-50 dark:bg-navy-950" />;
}
function unavailableAuthAction(): never {
throw new Error('Authentication actions are not available in this render mode');
}
function pageToPath(page: Page, inviteCode?: string): string {
switch (page) {
case 'dashboard':
@ -80,7 +84,10 @@ function pageToPath(page: Page, inviteCode?: string): string {
case 'account':
return '/account';
case 'invite':
return `/invite/${inviteCode || ''}`;
if (!inviteCode) {
throw new Error('Cannot build invite path without an invite code');
}
return `/invite/${inviteCode}`;
default:
return '/';
}
@ -190,7 +197,7 @@ export default function App() {
setShowLicenseSuccess(true);
}
// Always refresh auth on startup to pick up server-side subscription changes
refreshAuth().catch(() => {});
refreshAuth().catch(() => { });
}, []); // eslint-disable-line react-hooks/exhaustive-deps
const savedSearches = useSavedSearches(user?.id ?? null);
@ -263,7 +270,9 @@ export default function App() {
window.history.replaceState(
{ page: activePage },
'',
pageToPath(activePage) + window.location.search + window.location.hash
pageToPath(activePage, inviteCode ?? undefined) +
window.location.search +
window.location.hash
);
}
const handlePopState = (e: PopStateEvent) => {
@ -275,7 +284,6 @@ export default function App() {
setPendingInfoFeature(e.state.infoFeature);
}
} else {
// Fall back to deriving page from pathname
const parsed = pathToPage(window.location.pathname);
page = parsed?.page || 'home';
setActivePage(page);
@ -326,9 +334,9 @@ export default function App() {
user={null}
theme={theme}
screenshotMode
onLoginClick={() => {}}
onRegisterClick={() => {}}
onLicenseGranted={() => {}}
onLoginClick={unavailableAuthAction}
onRegisterClick={unavailableAuthAction}
onLicenseGranted={unavailableAuthAction}
/>
</Suspense>
);
@ -340,19 +348,21 @@ export default function App() {
<MapPage
features={features}
poiCategoryGroups={poiCategoryGroups}
initialFilters={urlState.filters || {}}
initialFilters={urlState.filters}
initialViewState={initialViewState}
initialPOICategories={urlState.poiCategories || new Set()}
initialTab={urlState.tab || 'area'}
initialPOICategories={urlState.poiCategories}
initialTab={urlState.tab}
initialLoading={initialLoading}
theme={theme}
pendingInfoFeature={null}
onClearPendingInfoFeature={() => {}}
onNavigateTo={() => {}}
onClearPendingInfoFeature={() => { }}
onNavigateTo={() => { }}
screenshotMode
ogMode={isOgMode}
initialTravelTime={urlState.travelTime}
shareCode={urlState.share}
onLoginClick={unavailableAuthAction}
onRegisterClick={unavailableAuthAction}
/>
</Suspense>
);
@ -365,8 +375,7 @@ export default function App() {
onPageChange={navigateTo}
theme={theme}
onToggleTheme={toggleTheme}
onExport={exportState?.onExport ?? null}
exporting={exportState?.exporting ?? false}
exportState={activePage === 'dashboard' ? exportState : null}
onSaveSearch={activePage === 'dashboard' && user ? () => setShowSaveModal(true) : null}
savingSearch={savedSearches.saving}
user={user}
@ -452,10 +461,10 @@ export default function App() {
<MapPage
features={features}
poiCategoryGroups={poiCategoryGroups}
initialFilters={mapUrlState.filters || {}}
initialFilters={mapUrlState.filters}
initialViewState={initialViewState}
initialPOICategories={mapUrlState.poiCategories || new Set()}
initialTab={mapUrlState.tab || 'area'}
initialPOICategories={mapUrlState.poiCategories}
initialTab={mapUrlState.tab}
initialLoading={initialLoading}
theme={theme}
pendingInfoFeature={pendingInfoFeature}