SkateSpots/src/components/RouteErrorBoundary.tsx
SkateSpots caa5f8c56e fix: tier 4 — offer role trust, proof replay, crew alerts, error/nav i18n
- H13 offer threads: the seller is ALWAYS the listing author (derived from the
  event pubkey), never a self-declared role tag — a non-owner can no longer
  appear as the seller with a payment pointer.
- H12 trade reputation: a preimage/deposit proof counts at most once, so a real
  payment can't be reused across attestations to inflate payment-verified.
- Crew alerts: listed crews are filtered against the user's own membership
  confirmation labels (one batched query), so a confirmed member no longer gets
  a phantom 'confirm to join' badge/notification when the crew is edited.
- Error boundaries (app + route) and DesktopNavManager are translated; the
  class boundary renders a translated functional ErrorFallback. New batch4
  namespaces errorsUi.* / desktopNav.*.
2026-10-02 23:22:13 +07:00

45 lines
1.6 KiB
TypeScript

import { useLocation } from 'react-router-dom';
import { ErrorBoundary } from '@/components/ErrorBoundary';
import { ErrorFallback } from '@/components/ErrorFallback';
/**
* Per-route error boundary.
*
* The app has a single top-level ErrorBoundary (in main.tsx) as a last resort,
* but on its own that means ANY component throwing blanks the ENTIRE app. This
* wrapper adds a second, inner boundary around the routed page content so a
* crash in one page shows a recoverable message while the app keeps running.
*
* It is keyed by the current pathname: navigating to a different route remounts
* the boundary and clears the error automatically, so a broken page never
* "sticks" once the user moves away.
*/
export function RouteErrorBoundary({ children }: { children: React.ReactNode }) {
const location = useLocation();
// After a deploy an already-open tab can hold a stale module graph, so a lazy
// route import 404s. `lazyWithRetry` reloads once; if it still fails the
// boundary is shown — so give the user a real way out: clear the "already
// reloaded" flag and do a fresh reload (fetching the new index + chunks).
const hardReload = () => {
try { sessionStorage.removeItem('skatespots:chunk-reload'); } catch { /* ignore */ }
window.location.reload();
};
return (
<ErrorBoundary
key={location.pathname}
fallback={
<ErrorFallback
variant="route"
onReload={hardReload}
onBack={() => window.history.back()}
/>
}
>
{children}
</ErrorBoundary>
);
}
export default RouteErrorBoundary;