import React, { Suspense } from "react"; import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; import { KeycloakProvider } from "@react-keycloak/web"; import * as Sentry from "@sentry/react"; import { loadGroupMappings } from "actions/misc"; import { loadProgram } from "actions/program"; import Footer from "components/Footer"; import Navbar from "components/Navbar"; import Home from "pages/Home"; import Program from "pages/Program"; import { AuthStore } from "stores"; import keycloak from "./keycloak"; /** * 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, }); } const onKeycloakEvent = (event) => { if (["onAuthRefreshSuccess", "onAuthSuccess"].includes(event)) { Sentry.setUser(keycloak.tokenParsed); AuthStore.update((state) => { state.isAuthenticated = true; state.user = { name: keycloak.tokenParsed.name, username: keycloak.tokenParsed.preferred_username, groups: keycloak.tokenParsed.groups, accessToken: keycloak.token, }; }); } }; 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 md:mb-4"> <img src={`${process.env.REACT_APP_STYLEGUIDE_URL}/images/logo-round-black.svg`} className="w-16 mb-2" alt="Pirátská strana" /> <h1 className="head-alt-md md:head-alt-lg">Celostátní fórum 2021</h1> </div> <p className="text-center">Načítám aplikaci ...</p> </div> </div> ); const BaseApp = () => { loadGroupMappings.read(); loadProgram.read(); return ( <Router> <Navbar /> <Switch> <Route exact path="/" children={<Home />} /> <Route exact path="/program" children={<Program />} /> </Switch> <Footer /> </Router> ); }; const AuthenticatedApp = () => { const keycloakInitConfig = { onLoad: "check-sso", // Necessary to prevent Keycloak cookie issues: // @see: https://stackoverflow.com/a/63588334/303184 checkLoginIframe: false, }; return ( <> <KeycloakProvider keycloak={keycloak} initConfig={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;