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
  • cf2023-euro
  • cf2023-offline
  • cf2024
  • cf2025
  • main
5 results

Target

Select target project
  • to/cf-online-ui
  • vpfafrin/cf2021
2 results
Select Git revision
  • master
1 result
Show changes
Commits on Source (102)
REACT_APP_STYLEGUIDE_URL=https://styleguide.pir-test.eu/2.0.1 REACT_APP_STYLEGUIDE_URL=https://styleguide.pirati.cz/2.11.0
REACT_APP_API_BASE_URL=https://cf2021.pir-test.eu/api REACT_APP_API_BASE_URL=https://cf2024.online/api
REACT_APP_MATOMO_ID=135 REACT_APP_MATOMO_ID=135
REACT_APP_SENTRY_DSN=https://aa80453ff4d54b9a9c1b49e79060498a@sentry.pir-test.eu/14 REACT_APP_SENTRY_DSN=https://aa80453ff4d54b9a9c1b49e79060498a@sentry.pirati.cz/14
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_API_BASE_URL: /api REACT_APP_API_BASE_URL: /api
WEBHOOK_URL: https://ha-web.pirati.cz WEBHOOK_URL: https://ha-web.pirati.cz
...@@ -12,13 +13,13 @@ before_script: ...@@ -12,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,28 +3,35 @@ ...@@ -3,28 +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",
"@rooks/use-window-size": "^4.5.0", "@rooks/use-interval": "^4.11.2",
"@sentry/react": "^5.29.2", "@rooks/use-outside-click": "^4.11.2",
"classnames": "^2.2.6", "@rooks/use-timeout": "^4.11.2",
"crypto-js": "^4.0.0", "@rooks/use-window-size": "^4.11.2",
"date-fns": "^2.16.1", "@sentry/integrations": "^7.119.2",
"immer": "^7.0.15", "@sentry/react": "^8.34.0",
"keycloak-js": "^10.0.2", "@sentry/tracing": "^7.119.2",
"lodash": "^4.17.20", "ajv": "^8.17.1",
"pullstate": "^1.20.5", "classnames": "^2.5.1",
"react": "^16.13.1", "crypto-js": "^4.2.0",
"react-dom": "^16.13.1", "date-fns": "^4.1.0",
"react-intersection-observer": "^8.31.0", "keycloak-js": "^26.0.0",
"react-mde": "^11.0.0", "lodash": "^4.17.21",
"react-modal": "^3.12.1", "pullstate": "^1.25.0",
"react-player": "^2.7.2", "react": "^18.3.1",
"react-router-dom": "^5.2.0", "react-dom": "^18.3.1",
"react-scripts": "3.4.3", "react-helmet-async": "^2.0.5",
"showdown": "^1.9.1", "react-hint": "^3.2.1",
"unfetch": "^4.2.0", "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", "wait-queue": "^1.1.4",
"xss": "^1.0.8" "xss": "^1.0.15"
}, },
"scripts": { "scripts": {
"start": "react-scripts start", "start": "react-scripts start",
...@@ -35,65 +42,6 @@ ...@@ -35,65 +42,6 @@
"lint:fix": "eslint --cache --fix 'src/**/*.{js,jsx}'", "lint:fix": "eslint --cache --fix 'src/**/*.{js,jsx}'",
"analyze": "source-map-explorer 'build/static/js/*.js'" "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|markdown|ws)(/.*|$)"
],
[
"^(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": [
">0.2%", ">0.2%",
...@@ -107,23 +55,27 @@ ...@@ -107,23 +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.1" "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,12 +37,11 @@ ...@@ -32,12 +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>-->
<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.
......
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 { loadAnnouncements } from "actions/announcements";
import { loadConfig } from "actions/global-info"; import { loadConfig } from "actions/global-info";
import { loadMe } from "actions/users"; import { loadPosts } from "actions/posts";
import { loadProgram } from "actions/program";
import { loadMe, refreshAccessToken } from "actions/users";
import { initializeWSChannel } from "actions/ws"; import { initializeWSChannel } from "actions/ws";
import Button from "components/Button";
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 Protocol from "pages/Protocol";
import { AuthStore, PostStore } from "stores"; import { AuthStore, PostStore } from "stores";
import { updateWindowPosts } from "utils"; import { updateWindowPosts } from "utils";
...@@ -24,14 +33,22 @@ if (process.env.REACT_APP_SENTRY_DSN) { ...@@ -24,14 +33,22 @@ 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; const kcRoles = keycloak.tokenParsed.roles || [];
let role = null; let role = null;
if (kcRoles.includes("chairman")) { if (kcRoles.includes("chairman")) {
...@@ -72,47 +89,53 @@ const LoadingComponent = ( ...@@ -72,47 +89,53 @@ const LoadingComponent = (
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 head-xs md:head-base">Načítám aplikaci ...</p> <p className="text-center head-xs md:head-base">Načítám aplikaci ...</p>
</div> </div>
</div> </div>
); );
const NotFound = () => (
<article className="container container--default py-8 lg:py-24">
<h1 className="head-alt-base lg:head-alt-lg mb-8">
404ka: Tahle stránka tu není
</h1>
<p className="text-base lg:text-xl mb-8">
Dostali jste se na takzvanou „<strong>čtyřystačtyřku</strong>“, což
znamená, že stránka, kterou jste se pokusili navštívit, na tomhle webu
není.
</p>
<Button routerTo="/" className="text-base lg:text-xl" hoverActive fullwidth>
Přejít na hlavní stránku
</Button>
</article>
);
const BaseApp = () => { const BaseApp = () => {
initializeWSChannel.read(); useEffect(() => {
initializeWSChannel.run();
}, []);
return ( return (
<Router> <HelmetProvider>
<Navbar /> <Router>
<Switch> <Helmet>
<Route exact path="/" children={<Home />} /> <title>CF 2024 | Pirátská strana</title>
<Route exact path="/program" children={<Program />} /> <meta
<Route component={NotFound} /> name="description"
</Switch> 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."
<Footer /> />
</Router> <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 = () => { const ConfiguredApp = () => {
loadConfig.read(); loadConfig.read();
loadProgram.read();
loadAnnouncements.read();
loadPosts.read();
return ( return (
<Suspense fallback={LoadingComponent}> <Suspense fallback={LoadingComponent}>
...@@ -132,10 +155,11 @@ const AuthenticatedApp = () => { ...@@ -132,10 +155,11 @@ 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}>
<ConfiguredApp /> <ConfiguredApp />
......
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();
}); });
...@@ -2,7 +2,7 @@ import keyBy from "lodash/keyBy"; ...@@ -2,7 +2,7 @@ import keyBy from "lodash/keyBy";
import property from "lodash/property"; import property from "lodash/property";
import { createAsyncAction, errorResult, successResult } from "pullstate"; import { createAsyncAction, errorResult, successResult } from "pullstate";
import { fetch } from "api"; import { fetchApi } from "api";
import { AnnouncementStore } from "stores"; import { AnnouncementStore } from "stores";
import { import {
announcementTypeMappingRev, announcementTypeMappingRev,
...@@ -15,7 +15,7 @@ import { ...@@ -15,7 +15,7 @@ import {
export const loadAnnouncements = createAsyncAction( export const loadAnnouncements = createAsyncAction(
async () => { async () => {
try { try {
const resp = await fetch("/announcements"); const resp = await fetchApi("/announcements");
const data = await resp.json(); const data = await resp.json();
return successResult(data.data); return successResult(data.data);
} catch (err) { } catch (err) {
...@@ -33,7 +33,7 @@ export const loadAnnouncements = createAsyncAction( ...@@ -33,7 +33,7 @@ export const loadAnnouncements = createAsyncAction(
}); });
} }
}, },
} },
); );
/** /**
...@@ -47,7 +47,7 @@ export const addAnnouncement = createAsyncAction( ...@@ -47,7 +47,7 @@ export const addAnnouncement = createAsyncAction(
link, link,
type: announcementTypeMappingRev[type], type: announcementTypeMappingRev[type],
}); });
const resp = await fetch("/announcements", { const resp = await fetchApi("/announcements", {
method: "POST", method: "POST",
body, body,
expectedStatus: 201, expectedStatus: 201,
...@@ -57,7 +57,7 @@ export const addAnnouncement = createAsyncAction( ...@@ -57,7 +57,7 @@ export const addAnnouncement = createAsyncAction(
} catch (err) { } catch (err) {
return errorResult([], err.toString()); return errorResult([], err.toString());
} }
} },
); );
/** /**
...@@ -70,7 +70,7 @@ export const deleteAnnouncement = createAsyncAction( ...@@ -70,7 +70,7 @@ export const deleteAnnouncement = createAsyncAction(
*/ */
async (item) => { async (item) => {
try { try {
await fetch(`/announcements/${item.id}`, { await fetchApi(`/announcements/${item.id}`, {
method: "DELETE", method: "DELETE",
expectedStatus: 204, expectedStatus: 204,
}); });
...@@ -78,7 +78,7 @@ export const deleteAnnouncement = createAsyncAction( ...@@ -78,7 +78,7 @@ export const deleteAnnouncement = createAsyncAction(
} catch (err) { } catch (err) {
return errorResult([], err.toString()); return errorResult([], err.toString());
} }
} },
); );
/** /**
...@@ -93,7 +93,7 @@ export const updateAnnouncement = createAsyncAction( ...@@ -93,7 +93,7 @@ export const updateAnnouncement = createAsyncAction(
async ({ item, payload }) => { async ({ item, payload }) => {
try { try {
const body = JSON.stringify(payload); const body = JSON.stringify(payload);
await fetch(`/announcements/${item.id}`, { await fetchApi(`/announcements/${item.id}`, {
method: "PUT", method: "PUT",
body, body,
expectedStatus: 204, expectedStatus: 204,
...@@ -102,7 +102,7 @@ export const updateAnnouncement = createAsyncAction( ...@@ -102,7 +102,7 @@ export const updateAnnouncement = createAsyncAction(
} catch (err) { } catch (err) {
return errorResult([], err.toString()); return errorResult([], err.toString());
} }
} },
); );
const { markSeen: storeSeen } = createSeenWriter(seenAnnouncementsLSKey); const { markSeen: storeSeen } = createSeenWriter(seenAnnouncementsLSKey);
......