Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • to/cf-online-ui
  • vpfafrin/cf2021
2 results
Select Git revision
Show changes
Commits on Source (151)
REACT_APP_STYLEGUIDE_URL=http://localhost:3001 REACT_APP_STYLEGUIDE_URL=https://styleguide.pirati.cz/2.11.0
REACT_APP_API_BASE_URL=https://cf2021.pirati.cz/api REACT_APP_API_BASE_URL=https://cf2024.online/api
REACT_APP_MATOMO_ID=135
REACT_APP_SENTRY_DSN=https://aa80453ff4d54b9a9c1b49e79060498a@sentry.pirati.cz/14
REACT_APP_STYLEGUIDE_URL=http://localhost:3001
image: node:buster image: node:18.20.4-bullseye
variables: variables:
SITE_NAME: cf2021.pirati.cz SITE_NAME: cf2024.online
ARTIFACTS_PATH: build ARTIFACTS_PATH: build
REACT_APP_STYLEGUIDE_URL: https://styleguide.pir-test.eu/latest REACT_APP_API_BASE_URL: /api
API_URL: https://cf2021.pirati.cz/api
WEBHOOK_URL: https://ha-web.pirati.cz WEBHOOK_URL: https://ha-web.pirati.cz
before_script: before_script:
...@@ -13,13 +13,13 @@ before_script: ...@@ -13,13 +13,13 @@ before_script:
build: build:
stage: build stage: build
script: script:
- npm install - npm install --legacy-peer-deps
- npm run build - npm run build
after_script: after_script:
- echo "{\"job_token\":\"$CI_JOB_TOKEN\", \"name\":\"$SITE_NAME\" }" > request.json - echo "{\"name\":\"$SITE_NAME\" }" > request.json
- "curl -H 'Content-Type: application/json' -X POST -d @request.json $WEBHOOK_URL" - "curl -k -H 'Content-Type: application/json' -X POST -d @request.json $WEBHOOK_URL"
artifacts: artifacts:
expire_in: 30 min expire_in: 30 min
paths: paths:
- $ARTIFACTS_PATH - $ARTIFACTS_PATH
14.13 18.20.4
\ No newline at end of file
FROM node:14.13-alpine3.12 as build FROM node:18.20.4-alpine AS build
ARG BUILD_REACT_APP_STYLEGUIDE_URL ENV REACT_APP_STYLEGUIDE_URL="https://styleguide.pirati.cz/2.12.1"
ENV REACT_APP_API_BASE_URL=https://cf2024.online/api
ENV REACT_APP_STYLEGUIDE_URL=${BUILD_REACT_APP_STYLEGUIDE_URL} ENV REACT_APP_MATOMO_ID=135
ENV REACT_APP_SENTRY_DSN=https://aa80453ff4d54b9a9c1b49e79060498a@sentry.pirati.cz/14
RUN mkdir -p /home/node/cf2021 RUN mkdir -p /home/node/cf2021
...@@ -10,7 +11,7 @@ WORKDIR /home/node/cf2021 ...@@ -10,7 +11,7 @@ WORKDIR /home/node/cf2021
COPY package*.json ./ COPY package*.json ./
RUN npm ci RUN npm ci --legacy-peer-deps
COPY . . COPY . .
...@@ -18,7 +19,7 @@ RUN npm run build ...@@ -18,7 +19,7 @@ RUN npm run build
# --- # ---
FROM nginx:alpine as production FROM nginx:alpine AS production
COPY --from=build /home/node/cf2021/build /usr/share/nginx/html/ COPY --from=build /home/node/cf2021/build /usr/share/nginx/html/
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
FROM node:14.13-alpine3.12 FROM node:18.20.4-alpine
# libs for development -- most of theme needed for canvas support in tests # libs for development -- most of theme needed for canvas support in tests
RUN apk add --no-cache \ RUN apk add --no-cache \
build-base \ build-base \
g++ \ g++ \
libpng \ libpng \
libpng-dev \ libpng-dev \
jpeg-dev \ jpeg-dev \
pango-dev \ pango-dev \
cairo-dev \ cairo-dev \
giflib-dev \ giflib-dev \
python3 \ python3 \
; ;
WORKDIR /app/cf2021 WORKDIR /app/cf2021
COPY package*.json ./ COPY package*.json ./
RUN npm ci RUN npm ci --legacy-peer-deps
COPY . . COPY . .
......
services:
app:
image: cf-online
ports:
- "3000:80"
import { fixupConfigRules, fixupPluginRules } from "@eslint/compat";
import { FlatCompat } from "@eslint/eslintrc";
import js from "@eslint/js";
import jestDom from "eslint-plugin-jest-dom";
import simpleImportSort from "eslint-plugin-simple-import-sort";
import testingLibrary from "eslint-plugin-testing-library";
import path from "node:path";
import { fileURLToPath } from "node:url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
const eslintConfig = [
...fixupConfigRules(
compat.extends(
"react-app",
"plugin:prettier/recommended",
"plugin:testing-library/dom",
"plugin:jest-dom/recommended",
),
),
{
plugins: {
"simple-import-sort": simpleImportSort,
"testing-library": fixupPluginRules(testingLibrary),
"jest-dom": fixupPluginRules(jestDom),
},
rules: {
"sort-imports": "off",
"prettier/prettier": "warn",
"react/no-unknown-property": [1],
"simple-import-sort/imports": [
"warn",
{
groups: [
["^react", "^@?\\w"],
[
"^(api|actions|config|hooks|components|containers|pages|utils|stores|keycloak|markdown|ws)(/.*|$)",
],
["^(test-utils)(/.*|$)"],
["^\\u0000"],
["^\\.\\.(?!/?$)", "^\\.\\./?$"],
["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"],
["^.+\\.s?css$"],
],
},
],
"testing-library/await-async-queries": "error",
"testing-library/no-await-sync-queries": "error",
"testing-library/no-debugging-utils": "warn",
"jest-dom/prefer-checked": "error",
"jest-dom/prefer-enabled-disabled": "error",
"jest-dom/prefer-required": "error",
"jest-dom/prefer-to-have-attribute": "error",
},
},
];
export default eslintConfig;
This diff is collapsed.
...@@ -3,21 +3,35 @@ ...@@ -3,21 +3,35 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@react-keycloak/web": "^2.1.4", "@react-keycloak/web": "^3.4.0",
"@sentry/react": "^5.23.0", "@rooks/use-interval": "^4.11.2",
"classnames": "^2.2.6", "@rooks/use-outside-click": "^4.11.2",
"date-fns": "^2.16.1", "@rooks/use-timeout": "^4.11.2",
"immer": "^7.0.15", "@rooks/use-window-size": "^4.11.2",
"keycloak-js": "^10.0.2", "@sentry/integrations": "^7.119.2",
"lodash": "^4.17.20", "@sentry/react": "^8.34.0",
"pullstate": "^1.20.5", "@sentry/tracing": "^7.119.2",
"react": "^16.13.1", "ajv": "^8.17.1",
"react-device-detect": "^1.13.1", "classnames": "^2.5.1",
"react-dom": "^16.13.1", "crypto-js": "^4.2.0",
"react-modal": "^3.12.1", "date-fns": "^4.1.0",
"react-router-dom": "^5.2.0", "keycloak-js": "^26.0.0",
"react-scripts": "3.4.3", "lodash": "^4.17.21",
"unfetch": "^4.2.0" "pullstate": "^1.25.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-helmet-async": "^2.0.5",
"react-hint": "^3.2.1",
"react-intersection-observer": "^9.13.1",
"react-joyride": "^2.9.2",
"react-mde": "^11.5.0",
"react-modal": "^3.16.1",
"react-player": "^2.16.0",
"react-router-dom": "^6.27.0",
"react-scripts": "^5.0.1",
"showdown": "^2.1.0",
"wait-queue": "^1.1.4",
"xss": "^1.0.15"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",
...@@ -25,66 +39,8 @@ ...@@ -25,66 +39,8 @@
"test": "react-scripts test --env=jsdom-fourteen", "test": "react-scripts test --env=jsdom-fourteen",
"eject": "react-scripts eject", "eject": "react-scripts eject",
"lint": "eslint --cache 'src/**/*.{js,jsx}'", "lint": "eslint --cache 'src/**/*.{js,jsx}'",
"lint:fix": "eslint --cache --fix 'src/**/*.{js,jsx}'" "lint:fix": "eslint --cache --fix 'src/**/*.{js,jsx}'",
}, "analyze": "source-map-explorer 'build/static/js/*.js'"
"eslintConfig": {
"extends": [
"react-app",
"plugin:prettier/recommended",
"plugin:testing-library/recommended",
"plugin:jest-dom/recommended"
],
"plugins": [
"simple-import-sort",
"testing-library",
"jest-dom"
],
"rules": {
"sort-imports": "off",
"prettier/prettier": "warn",
"react/no-unknown-property": [
1
],
"simple-import-sort/sort": [
"warn",
{
"groups": [
[
"^react",
"^@?\\w"
],
[
"^(api|actions|config|hooks|components|containers|pages|utils|stores|keycloak)(/.*|$)"
],
[
"^(test-utils)(/.*|$)"
],
[
"^\\u0000"
],
[
"^\\.\\.(?!/?$)",
"^\\.\\./?$"
],
[
"^\\./(?=.*/)(?!/?$)",
"^\\.(?!/?$)",
"^\\./?$"
],
[
"^.+\\.s?css$"
]
]
}
],
"testing-library/await-async-query": "error",
"testing-library/no-await-sync-query": "error",
"testing-library/no-debug": "warn",
"jest-dom/prefer-checked": "error",
"jest-dom/prefer-enabled-disabled": "error",
"jest-dom/prefer-required": "error",
"jest-dom/prefer-to-have-attribute": "error"
}
}, },
"browserslist": { "browserslist": {
"production": [ "production": [
...@@ -99,22 +55,27 @@ ...@@ -99,22 +55,27 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@testing-library/jest-dom": "^4.0.0", "@eslint/compat": "^1.2.0",
"@testing-library/react": "^10.4.4", "@eslint/eslintrc": "^3.1.0",
"@testing-library/react-hooks": "^3.4.2", "@eslint/js": "^9.12.0",
"@testing-library/user-event": "^12.1.7", "@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^16.0.1",
"@testing-library/react-hooks": "^8.0.1",
"@testing-library/user-event": "^14.5.2",
"babel-core": "^6.26.3", "babel-core": "^6.26.3",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"eslint": "^6.8.0", "eslint": "^9.12.0",
"eslint-config-airbnb": "^18.2.0", "eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^6.11.0", "eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.22.0", "eslint-plugin-import": "^2.31.0",
"eslint-plugin-jest-dom": "^3.6.3", "eslint-plugin-jest-dom": "^5.4.0",
"eslint-plugin-jsx-a11y": "^6.3.1", "eslint-plugin-jsx-a11y": "^6.10.0",
"eslint-plugin-prettier": "^3.1.4", "eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.20.6", "eslint-plugin-react": "^7.37.1",
"eslint-plugin-simple-import-sort": "^5.0.3", "eslint-plugin-simple-import-sort": "^12.1.1",
"eslint-plugin-testing-library": "^3.8.0", "eslint-plugin-testing-library": "^6.3.0",
"prettier": "^2.1.1" "prettier": "^3.3.3",
"source-map-explorer": "^2.5.3",
"typescript": "^5.6.3"
} }
} }
public/favicon.ico

3.08 KiB

File added
public/img/og2021.png

124 KiB

public/img/og2024.png

43.1 KiB

...@@ -5,18 +5,23 @@ ...@@ -5,18 +5,23 @@
<!-- Favicons --> <!-- Favicons -->
<link rel="apple-touch-icon" href="%REACT_APP_STYLEGUIDE_URL%/images/favicons/favicon-196x196.png"> <link rel="apple-touch-icon" href="%REACT_APP_STYLEGUIDE_URL%/images/favicons/favicon-196x196.png">
<link rel="icon" type="image/png" href="%REACT_APP_STYLEGUIDE_URL%/images/favicons/favicon-196x196.png" sizes="196x196"> <link rel="icon" type="image/png" href="%REACT_APP_STYLEGUIDE_URL%/images/favicons/favicon-196x196.png" sizes="196x196">
<meta name="application-name" content="CF2021"> <meta name="application-name" content="CF2023">
<meta name="msapplication-TileColor" content="#000000"> <meta name="msapplication-TileColor" content="#000000">
<meta name="msapplication-TileImage" content="%REACT_APP_STYLEGUIDE_URL%/images/favicons/mstile-144x144.png"> <meta name="msapplication-TileImage" content="%REACT_APP_STYLEGUIDE_URL%/images/favicons/mstile-144x144.png">
<meta name="msapplication-square70x70logo" content="%REACT_APP_STYLEGUIDE_URL%/images/favicons/mstile-70x70.png"> <meta name="msapplication-square70x70logo" content="%REACT_APP_STYLEGUIDE_URL%/images/favicons/mstile-70x70.png">
<meta name="msapplication-square150x150logo" content="%REACT_APP_STYLEGUIDE_URL%/images/favicons/mstile-150x150.png"> <meta name="msapplication-square150x150logo" content="%REACT_APP_STYLEGUIDE_URL%/images/favicons/mstile-150x150.png">
<meta name="msapplication-wide310x150logo" content="%REACT_APP_STYLEGUIDE_URL%/images/favicons/mstile-310x150.png"> <meta name="msapplication-wide310x150logo" content="%REACT_APP_STYLEGUIDE_URL%/images/favicons/mstile-310x150.png">
<meta name="msapplication-square310x310logo" content="%REACT_APP_STYLEGUIDE_URL%/images/favicons/mstile-310x310.png"> <meta name="msapplication-square310x310logo" content="%REACT_APP_STYLEGUIDE_URL%/images/favicons/mstile-310x310.png">
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="theme-color" content="#000000" /> <meta name="theme-color" content="#000000" />
<meta property="og:url" content="https://cf2021.pirati.cz/" /> <meta property="og:url" content="https://cf2024.online/" />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:title" content="CF 2021" /> <meta property="og:title" content="CF 2024 | Pirátská strana" />
<meta property="og:image" content="https://cf2023.online/img/og2024.png" />
<meta property="og:description" content="Oficiální stránka letošního ročníku on-line zasedání Celostátního fóra České pirátské strany, 13. 1. 2024." />
<meta name="description" content="Oficiální stránka letošního ročníku on-line zasedání Celostátního fóra České pirátské strany, 13. 1. 2024." />
<title>CF 2023 | Pirátská strana</title>
<!-- <!--
manifest.json provides metadata used when your web app is installed on a manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
...@@ -32,11 +37,11 @@ ...@@ -32,11 +37,11 @@
Learn how to configure a non-root public URL by running `npm run build`. Learn how to configure a non-root public URL by running `npm run build`.
--> -->
<link rel="stylesheet" href="%REACT_APP_STYLEGUIDE_URL%/css/styles.css" /> <link rel="stylesheet" href="%REACT_APP_STYLEGUIDE_URL%/css/styles.css" />
<title>CF 2021 | Pirátská strana</title> <!--<script src="https://polyfill.io/v3/polyfill.min.js?features=IntersectionObserver"></script>-->
</head> </head>
<body class="h-screen"> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root" class="h-screen h-full w-full"></div> <div id="root"></div>
<!-- <!--
This HTML file is a template. This HTML file is a template.
If you open it directly in the browser, you will see an empty page. If you open it directly in the browser, you will see an empty page.
...@@ -48,4 +53,19 @@ ...@@ -48,4 +53,19 @@
To create a production bundle, use `npm run build` or `yarn build`. To create a production bundle, use `npm run build` or `yarn build`.
--> -->
</body> </body>
<!-- Matomo -->
<script type="text/javascript">
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//matomo.pirati.cz/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '%REACT_APP_MATOMO_ID%']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
<!-- End Matomo Code -->
</html> </html>
public/logo192.png

5.22 KiB

public/logo512.png

9.44 KiB

{ {
"short_name": "React App", "short_name": "CF2023",
"name": "Create React App Sample", "name": "Celostátní fórum 2023",
"icons": [ "icons": [
{ {
"src": "favicon.ico", "src": "https://styleguide.pir-test.eu/latest/images/favicons/favicon-32x32.png",
"sizes": "64x64 32x32 24x24 16x16", "sizes": "32x32 24x24 16x16",
"type": "image/x-icon" "type": "image/x-icon"
}, },
{ {
"src": "logo192.png", "src": "https://styleguide.pir-test.eu/latest/images/favicons/favicon-96x96.png",
"type": "image/png", "sizes": "96x96 64x64",
"sizes": "192x192" "type": "image/x-icon"
}, },
{ {
"src": "logo512.png", "src": "https://styleguide.pir-test.eu/latest/images/favicons/favicon-196x196.png",
"type": "image/png", "type": "image/png",
"sizes": "512x512" "sizes": "192x192 196x196"
} }
], ],
"start_url": ".", "start_url": ".",
......
import React, { Suspense } from "react"; import React, { Suspense, useEffect } from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; import { Helmet, HelmetProvider } from "react-helmet-async";
import { KeycloakProvider } from "@react-keycloak/web"; import ReactHintFactory from "react-hint";
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import { ReactKeycloakProvider as KeycloakProvider } from "@react-keycloak/web";
import { extraErrorDataIntegration } from "@sentry/integrations";
import * as Sentry from "@sentry/react"; import * as Sentry from "@sentry/react";
import { browserTracingIntegration } from "@sentry/browser"
import { loadGroupMappings } from "actions/misc"; import { loadAnnouncements } from "actions/announcements";
import { loadConfig } from "actions/global-info";
import { loadPosts } from "actions/posts";
import { loadProgram } from "actions/program"; import { loadProgram } from "actions/program";
import { loadMe, refreshAccessToken } from "actions/users";
import { initializeWSChannel } from "actions/ws";
import Footer from "components/Footer"; import Footer from "components/Footer";
import Navbar from "components/Navbar"; import Navbar from "components/Navbar";
import About from "pages/About";
import Home from "pages/Home"; import Home from "pages/Home";
import NotFound from "pages/NotFound";
import Program from "pages/Program"; import Program from "pages/Program";
import { AuthStore } from "stores"; import Protocol from "pages/Protocol";
import { AuthStore, PostStore } from "stores";
import { updateWindowPosts } from "utils";
import keycloak from "./keycloak"; import keycloak from "./keycloak";
...@@ -21,53 +33,114 @@ if (process.env.REACT_APP_SENTRY_DSN) { ...@@ -21,53 +33,114 @@ if (process.env.REACT_APP_SENTRY_DSN) {
Sentry.init({ Sentry.init({
dsn: process.env.REACT_APP_SENTRY_DSN, dsn: process.env.REACT_APP_SENTRY_DSN,
tracesSampleRate: 0.1, tracesSampleRate: 0.1,
integrations: [extraErrorDataIntegration(), browserTracingIntegration()],
}); });
} }
const onKeycloakEvent = (event) => { const ReactHint = ReactHintFactory(React);
const onKeycloakEvent = async (event) => {
if (event === "onTokenExpired") {
console.warn("[auth] access token expired, attempting refresh");
refreshAccessToken();
}
if (["onAuthRefreshSuccess", "onAuthSuccess"].includes(event)) { if (["onAuthRefreshSuccess", "onAuthSuccess"].includes(event)) {
Sentry.setUser(keycloak.tokenParsed); Sentry.setUser(keycloak.tokenParsed);
const kcRoles = keycloak.tokenParsed.roles || [];
let role = null;
if (kcRoles.includes("chairman")) {
role = "chairman";
} else if (kcRoles.includes("member")) {
role = "member";
} else {
role = "regp";
}
AuthStore.update((state) => { AuthStore.update((state) => {
state.isAuthenticated = true; state.isAuthenticated = true;
state.user = { state.user = {
name: keycloak.tokenParsed.name, name: keycloak.tokenParsed.name,
username: keycloak.tokenParsed.preferred_username, username: keycloak.tokenParsed.preferred_username,
groups: keycloak.tokenParsed.groups, role,
accessToken: keycloak.token, accessToken: keycloak.token,
}; };
}); });
// Once base user details has been stored, load me details from API.
loadMe.run();
PostStore.update((state) => {
// Only display proposals verified by chairman to other users.
state.filters.showPendingProposals = role === "chairman";
updateWindowPosts(state);
});
} }
}; };
const LoadingComponent = ( const LoadingComponent = (
<div className="h-screen w-screen flex justify-center items-center"> <div className="h-screen w-screen flex justify-center items-center">
<div className="text-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"> <div className="flex flex-col md:flex-row items-center space-x-4 text-center mb-2">
<img <img
src={`${process.env.REACT_APP_STYLEGUIDE_URL}/images/logo-round-black.svg`} src={`${process.env.REACT_APP_STYLEGUIDE_URL}/images/logo-round-black.svg`}
className="w-16 mb-2" className="w-16 mb-2"
alt="Pirátská strana" alt="Pirátská strana"
/> />
<h1 className="head-alt-md md:head-alt-lg">Celostátní fórum 2021</h1> <h1 className="head-alt-md md:head-alt-lg">Celostátní fórum 2024</h1>
</div> </div>
<p className="text-center">Načítám aplikaci ...</p> <p className="text-center head-xs md:head-base">Načítám aplikaci ...</p>
</div> </div>
</div> </div>
); );
const BaseApp = () => { const BaseApp = () => {
loadGroupMappings.read(); useEffect(() => {
initializeWSChannel.run();
}, []);
return (
<HelmetProvider>
<Router>
<Helmet>
<title>CF 2024 | Pirátská strana</title>
<meta
name="description"
content="Oficiální stránka letošního ročníku on-line zasedání Celostátního fóra České pirátské strany, 13. 1. 2024."
/>
<meta property="og:title" content="CF 2024 | Pirátská strana" />
<meta
property="og:description"
content="Oficiální stránka letošního ročníku on-line zasedání Celostátního fóra České pirátské strany, 13. 1. 2024."
/>
</Helmet>
<Navbar />
<Routes>
<Route exact path="/" element={<Home />} />
<Route exact path="/program" element={<Program />} />
<Route exact path="/protocol" element={<Protocol />} />
<Route exact path="/about" element={<About />} />
<Route element={NotFound} />
</Routes>
<Footer />
</Router>
<ReactHint autoPosition events attribute="data-tip" className="tooltip" />
</HelmetProvider>
);
};
const ConfiguredApp = () => {
loadConfig.read();
loadProgram.read(); loadProgram.read();
loadAnnouncements.read();
loadPosts.read();
return ( return (
<Router> <Suspense fallback={LoadingComponent}>
<Navbar /> <BaseApp />
<Switch> </Suspense>
<Route exact path="/" children={<Home />} />
<Route exact path="/program" children={<Program />} />
</Switch>
<Footer />
</Router>
); );
}; };
...@@ -82,13 +155,14 @@ const AuthenticatedApp = () => { ...@@ -82,13 +155,14 @@ const AuthenticatedApp = () => {
return ( return (
<> <>
<KeycloakProvider <KeycloakProvider
keycloak={keycloak} authClient={keycloak}
initConfig={keycloakInitConfig} initConfig={keycloakInitConfig}
LoadingComponent={LoadingComponent} LoadingComponent={LoadingComponent}
onEvent={onKeycloakEvent} onEvent={onKeycloakEvent}
autoRefreshToken={false}
> >
<Suspense fallback={LoadingComponent}> <Suspense fallback={LoadingComponent}>
<BaseApp /> <ConfiguredApp />
</Suspense> </Suspense>
</KeycloakProvider> </KeycloakProvider>
</> </>
......
import React from "react"; import React from "react";
import { render } from "@testing-library/react"; import { render, screen } from "@testing-library/react";
import App from "./App"; import App from "./App";
test("renders learn react link", () => { test("renders learn react link", () => {
const { getByText } = render(<App />); render(<App />);
const linkElement = getByText(/learn react/i); const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument(); expect(linkElement).toBeInTheDocument();
}); });