Select Git revision
App.js 5.15 KiB
import { Suspense } from "react";
import { Helmet } from "react-helmet";
import { BrowserRouter as Router, Link, Route, Switch } from "react-router-dom";
import { ReactKeycloakProvider as KeycloakProvider } from "@react-keycloak/web";
import { ExtraErrorData } from "@sentry/integrations/dist/extraerrordata";
import * as Sentry from "@sentry/react";
import { Integrations } from "@sentry/tracing";
import { basics } from "config";
import VNav from "./components/VNav";
import Accommodation from "./pages/Accommodation";
import Home from "./pages/Home";
import Map from "./pages/Map";
import Registration from "./pages/Registration";
import Team from "./pages/Team";
import Volunteers from "./pages/Volunteers";
import keycloak from "./keycloak";
import partyLogo from "./logo-full-black.svg";
import "./styles.css";
/**
* If configured, set up Sentry client that reports uncaught errors down to
* https://sentry.io.
*/
if (process.env.REACT_APP_SENTRY_DSN) {
Sentry.init({
dsn: process.env.REACT_APP_SENTRY_DSN,
tracesSampleRate: 0.1,
integrations: [new ExtraErrorData(), new Integrations.BrowserTracing()],
});
}
const WithNav = ({ children }) => {
return (
<div className="flex flex-col md:flex-row md:space-x-8">
{children}
<VNav className="mt-8 md:mt-0 md:w-1/4 p-4 md:p-8" />
</div>
);
};
function BaseApp() {
const year = new Date().getFullYear();
return (
<Router>
<Helmet>
<title>{basics.appTitle} | Pirátská strana</title>
<meta name="description" content={basics.appDesc} />
</Helmet>
<div className="container container--default my-4 md:my-16 space-y-8 md:space-y-16">
<header className="md:flex items-center text-center md:text-left">
<h1 className="head-alt-xl">
<Link to="/" className="no-underline hover:no-underline">
{basics.appTitle}
</Link>
</h1>
<div className="md:text-right ml-auto head-alt-base">
<h2>{process.env.REACT_APP_CF_EVENT_DATE}</h2>
<h2>{process.env.REACT_APP_CF_EVENT_CITY}</h2>
<h2>{process.env.REACT_APP_CF_EVENT_VENUE}</h2>
</div>
</header>
<Switch>
<Route path="/registrace">
<WithNav>
<Registration />
</WithNav>
</Route>
<Route path="/organizatori">
<WithNav>
<Team />
</WithNav>
</Route>
<Route path="/ubytovani">
<WithNav>
<Accommodation />
</WithNav>
</Route>
<Route path="/mapa">
<WithNav>
<Map />
</WithNav>
</Route>
<Route path="/pro-dobrovolniky">
<WithNav>
<Volunteers />
</WithNav>
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
<footer className="border-t border-grey-125 pt-4 flex flex-col md:flex-row items-center md:justify-between space-y-4 text-center md:text-left">
<img src={partyLogo} className="w-32" alt="Pirátská strana" />
<p>Piráti, {year}. Všechna práva vyhlazena.</p>
</footer>
</div>
</Router>
);
}
const LoadingComponent = (
<div className="h-screen w-screen flex justify-center items-center">
<div className="text-center">
<div className="flex flex-col md:flex-row items-center space-x-4 text-center mb-2">
<h1 className="head-alt-md md:head-alt-lg">{basics.appTitle}</h1>
</div>
<p className="text-center head-xs">Načítám aplikaci ...</p>
</div>
</div>
);
const AuthenticatedApp = () => {
const keycloakInitConfig = {
onLoad: "check-sso",
// Necessary to prevent Keycloak cookie issues:
// @see: https://stackoverflow.com/a/63588334/303184
checkLoginIframe: false,
};
const onKeycloakEvent = async (event) => {
if (["onAuthRefreshSuccess", "onAuthSuccess"].includes(event)) {
Sentry.setUser(keycloak.tokenParsed);
}
};
return (
<>
<KeycloakProvider
authClient={keycloak}
initOptions={keycloakInitConfig}
LoadingComponent={LoadingComponent}
onEvent={onKeycloakEvent}
>
<Suspense fallback={LoadingComponent}>
<BaseApp />
</Suspense>
</KeycloakProvider>
</>
);
};
const ErrorBoundaryFallback = ({ error }) => {
return (
<div className="h-screen w-screen flex justify-center items-center">
<div className="text-center">
<h1 className="head-alt-xl text-red-600 mb-4">
V aplikaci došlo k chybě :(
</h1>
<p className="text-lg leading-normal">
Naši vývojáři o tom již byli informování a opraví to co nejdříve.
<br />
Omlouváme se za tuto nepříjemnost.
</p>
<a href="/" className="btn mt-8">
<div className="btn__body">Načíst znovu</div>
</a>
</div>
</div>
);
};
const App = Sentry.withProfiler(() => {
return (
<Sentry.ErrorBoundary fallback={ErrorBoundaryFallback} showDialog>
<AuthenticatedApp />
</Sentry.ErrorBoundary>
);
});
export default App;