Merge branch 'master' into 'production'

dev to prod: styling, added fopas etc

See merge request sahkoinsinoorikilta/vtmk/web2.0-frontend!74
This commit is contained in:
Toni Lyttinen
2021-06-29 16:04:22 +00:00
31 changed files with 2001 additions and 1632 deletions
+2 -1
View File
@@ -4,4 +4,5 @@ node_modules
.next
# don't lint nyc coverage output
coverage
next-env.d.ts
next-env.d.ts
.eslintrc.js
+33
View File
@@ -0,0 +1,33 @@
module.exports = {
parserOptions: {
project: "./tsconfig.json"
},
extends: [
"plugin:@typescript-eslint/recommended",
"airbnb-typescript",
"next",
"next/core-web-vitals"
],
rules: {
"max-len": [
"warn",
240
],
"@typescript-eslint/quotes": [
"error",
"double"
],
"import/prefer-default-export": "warn",
"react/jsx-props-no-spreading": "off",
"react/prop-types": "off",
"react/jsx-one-expression-per-line": "off",
"eslintreact/jsx-one-expression-per-line": "off",
// Temp
"import/no-cycle": "warn",
"react/no-array-index-key": "warn",
"jsx-a11y/label-has-associated-control": "off",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-noninteractive-element-interactions": "off",
"jsx-a11y/no-static-element-interactions": "off",
}
}
-61
View File
@@ -1,61 +0,0 @@
{
"root": true,
"env": {
"browser": true,
"commonjs": true,
"es6": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:import/errors",
"plugin:import/warnings",
"plugin:jsx-a11y/recommended",
"plugin:react-hooks/recommended",
"plugin:@typescript-eslint/recommended",
"airbnb-typescript"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module",
"project": "./tsconfig.json"
},
"plugins": [],
"settings": {
"react": {
"version": "detect"
}
},
"rules": {
"@typescript-eslint/naming-convention": "off",
"max-len": [
"warn",
240
],
"@typescript-eslint/quotes": [
"error",
"double"
],
"import/prefer-default-export": "warn",
"react/jsx-props-no-spreading": "off",
"react/prop-types": "off",
// Temp
"react/jsx-one-expression-per-line": "off",
"react/no-array-index-key": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"jsx-a11y/label-has-associated-control": "off",
"jsx-a11y/click-events-have-key-events": "off",
"jsx-a11y/no-noninteractive-element-interactions": "off",
"jsx-a11y/no-static-element-interactions": "off"
}
}
+3
View File
@@ -12,6 +12,9 @@ install:
stage: setup
script:
- npm ci
after_script:
- node -v
- npm -v
artifacts:
paths:
- node_modules
+1
View File
@@ -1,2 +1,3 @@
/// <reference types="next" />
/// <reference types="next/types/global" />
/// <reference types="next/image-types/global" />
+1 -4
View File
@@ -10,8 +10,5 @@ module.exports = withBundleAnalyzer({
"static.sahkoinsinoorikilta.fi",
"api.dev.sahkoinsinoorikilta.fi",
],
},
future: {
webpack5: true,
},
}
});
+1833 -1457
View File
File diff suppressed because it is too large Load Diff
+9 -13
View File
@@ -20,8 +20,8 @@
"postbuild": "next-sitemap",
"export": "next export",
"lint": "npm run lint:es && npm run lint:css",
"lint:es": "eslint . --ext .ts,.tsx",
"lint:es:fix": "eslint --fix . --ext .ts,.tsx",
"lint:es": "next lint",
"lint:es:fix": "next lint --fix",
"lint:css": "stylelint \"./src/**/*.{ts,tsx}\"",
"dev": "next dev",
"start": "next dev",
@@ -37,21 +37,17 @@
"@types/react": "^17.0.11",
"@types/react-beautiful-dnd": "^13.0.0",
"@types/react-csv": "^1.1.1",
"@types/react-dom": "^17.0.7",
"@types/react-dom": "^17.0.8",
"@types/react-jsonschema-form": "^1.7.5",
"@types/shortid": "^0.0.29",
"@types/styled-components": "^5.1.10",
"@typescript-eslint/eslint-plugin": "^4.27.0",
"@typescript-eslint/parser": "^4.27.0",
"@typescript-eslint/eslint-plugin": "^4.28.1",
"babel-plugin-styled-components": "^1.12.0",
"eslint": "^7.28.0",
"eslint": "^7.29.0",
"eslint-config-airbnb-typescript": "^12.3.1",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.24.0",
"eslint-plugin-react-hooks": "^4.2.0",
"eslint-config-next": "^11.0.1",
"husky": "^6.0.0",
"next-sitemap": "^1.6.116",
"next-sitemap": "^1.6.124",
"npm-run-all": "^4.1.5",
"stylelint": "^13.13.1",
"stylelint-config-standard": "^22.0.0",
@@ -60,13 +56,13 @@
"typescript": "^4.3.2"
},
"dependencies": {
"@next/bundle-analyzer": "^10.2.3",
"@next/bundle-analyzer": "^11.0.1",
"axios": "^0.21.1",
"date-fns": "^2.22.1",
"fast-deep-equal": "^3.1.3",
"js-cookie": "^2.2.1",
"lodash": "^4.17.21",
"next": "^10.2.3",
"next": "^11.0.1",
"normalize.css": "^8.0.1",
"react": "^17.0.2",
"react-beautiful-dnd": "^13.1.0",
+3 -2
View File
@@ -1,7 +1,6 @@
import React from "react";
// eslint-disable-next-line react/display-name
export default (): JSX.Element => (
const Icons = (): JSX.Element => (
<>
<link rel="shortcut icon" href="/favicons/favicon.ico" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicons/favicon-16x16.png" />
@@ -54,3 +53,5 @@ export default (): JSX.Element => (
<link rel="yandex-tableau-widget" href="/favicons/yandex-browser-manifest.json" />
</>
);
export default Icons;
+3 -2
View File
@@ -1,7 +1,6 @@
import React from "react";
// eslint-disable-next-line react/display-name
export default (): JSX.Element => (
const Logo = (): JSX.Element => (
// eslint-disable-next-line react/no-danger
<head dangerouslySetInnerHTML={{
__html:
@@ -55,3 +54,5 @@ export default (): JSX.Element => (
}}
/>
);
export default Logo;
@@ -8,6 +8,7 @@ const Container = styled.label`
padding-left: 2rem;
cursor: pointer;
font-size: 1.5rem; /* 24px */
line-height: 1;
user-select: none;
/* On mouse-over, add a grey background color */
@@ -22,7 +22,7 @@ type CheckboxesProps = Omit<WidgetProps, "options"> & {
};
const CheckboxContainer = styled.div`
margin-bottom: 0.5rem;
margin-bottom: 1rem;
`;
const Checkboxes: React.FC<CheckboxesProps> = ({
@@ -7,6 +7,7 @@ const Container = styled.label`
padding-left: 2rem;
cursor: pointer;
font-size: 1.5rem; /* 24px */
line-height: 1;
user-select: none;
/* On mouse-over, add a grey background color */
@@ -8,7 +8,7 @@ type RadioButtonWidgetProps = Omit<WidgetProps, "options"> & {
};
const RadioButtonContainer = styled.div`
margin-bottom: 0.5rem;
margin-bottom: 1rem;
`;
const RadioButtonWidget: React.FC<RadioButtonWidgetProps> = (props) => {
@@ -27,7 +27,9 @@ const Heading = styled.h3`
const SectionDividerWidget: React.FC<SectionDividerWidgetProps> = ({ label }) => (
<Heading>
{label}&nbsp;{getIconByLabel(label)}
{label}
&nbsp;
{getIconByLabel(label)}
</Heading>
);
@@ -13,7 +13,7 @@ class OptionsWidget extends React.Component<OptionsWidgetProps> {
handleListOptionsChange = (questions: Question[], index: number): React.ChangeEventHandler<HTMLInputElement> => (event) => {
const { onChange } = this.props;
const val = event.target.value;
const lst = val.split(",").map((p) => p.trimLeft());
const lst = val.split(";").map((p) => p.trimLeft());
// eslint-disable-next-line no-param-reassign
questions[index].options = lst;
onChange(questions);
@@ -31,7 +31,7 @@ class OptionsWidget extends React.Component<OptionsWidgetProps> {
const { onChange } = this.props;
const val = event.target.value;
if (val !== "") {
const lst = val.split(",").map((p) => p.trimLeft());
const lst = val.split(";").map((p) => p.trimLeft());
// Ignore everything else but the two first values
// eslint-disable-next-line no-param-reassign
questions[index].options = lst.splice(0, 2);
@@ -51,19 +51,20 @@ class OptionsWidget extends React.Component<OptionsWidgetProps> {
onChange(questions);
};
requiredField() {
requiredField(): JSX.Element {
const { inputProps } = this.props;
const { questions, index } = inputProps;
return (
<Checkbox
checked={questions[index].required}
onChange={this.handleRequiredChange(questions, index)}
>Required?
>
Required?
</Checkbox>
);
}
render() {
render(): JSX.Element {
const { inputProps } = this.props;
const {
type, value, questions, index,
@@ -92,12 +93,12 @@ class OptionsWidget extends React.Component<OptionsWidgetProps> {
if (type === "integer") {
const lst = value as string[];
const joinedValue = lst.join(",");
const joinedValue = lst.join(";");
return (
<>
<input
type="text"
placeholder="Minimum,Maximum"
placeholder="Minimum;Maximum"
value={joinedValue}
onChange={this.handleIntegerOptionsChange(questions, index)}
/>
@@ -108,12 +109,12 @@ class OptionsWidget extends React.Component<OptionsWidgetProps> {
if (type === "radiobutton") {
const lst = value as string[];
const joinedValue = lst.join(",");
const joinedValue = lst.join(";");
return (
<>
<input
type="text"
placeholder="Yes,no,maybe"
placeholder="Yes;no;maybe"
value={joinedValue}
onChange={this.handleListOptionsChange(questions, index)}
/>
@@ -124,12 +125,12 @@ class OptionsWidget extends React.Component<OptionsWidgetProps> {
if (type === "checkbox") {
const lst = value as string[];
const joinedValue = lst.join(",");
const joinedValue = lst.join(";");
return (
<>
<input
type="text"
placeholder="A,B,C"
placeholder="A;B;C"
value={joinedValue}
onChange={this.handleListOptionsChange(questions, index)}
/>
+3 -1
View File
@@ -26,7 +26,9 @@ const NotFoundPage: NextPage = () => (
<Header />
<NotFound id="not-found">
<p>
<strong>404</strong> | Ei&nbsp;vaan&nbsp;löydy
<strong>404</strong>
{" "}
| Ei&nbsp;vaan&nbsp;löydy
</p>
</NotFound>
</>
+1 -2
View File
@@ -126,11 +126,10 @@ const AppContainer = styled.div`
background-color: ${colors.white};
`;
const Web20App = ({ Component, pageProps }: AppProps) => (
const Web20App = ({ Component, pageProps }: AppProps): JSX.Element => (
<>
<Head>
<meta httpEquiv="Content-Type" content="text/html; charset=utf-8" />
<link href="https://fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,800,900&display=swap" rel="stylesheet" />
<meta httpEquiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Aalto-yliopiston Sähköinsinöörikilta ry</title>
+2 -1
View File
@@ -29,12 +29,13 @@ export default class MyDocument extends Document<{ styleTags: unknown }> {
}
}
render() {
render(): JSX.Element {
const { styleTags } = this.props;
return (
<Html lang="fi">
<Head>
<HTMLLogo />
<link href="https://fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,800,900&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.0/normalize.min.css" />
<Favicons />
</Head>
+4 -2
View File
@@ -46,7 +46,8 @@ const AdminLoginPage: NextPage = () => {
<div className="error">You have to log in first.</div>
)}
<form className="admin-login-form" onSubmit={handleSubmit}>
<label>Username
<label>
Username
<input
id="login-username"
type="text"
@@ -57,7 +58,8 @@ const AdminLoginPage: NextPage = () => {
}}
/>
</label>
<label>Password
<label>
Password
<input
id="login-password"
type="password"
+4 -1
View File
@@ -61,7 +61,10 @@ const SignupEmailPage: NextPage = () => {
return (
<AdminListCommon>
<h1>{title}: Sign-ups</h1>
<h1>
{title}
: Sign-ups
</h1>
<table>
<thead>
<tr>
+7 -18
View File
@@ -4,38 +4,27 @@ import Head from "next/head";
import { useRouter } from "next/router";
import Event from "@models/Event";
import EventApi from "@api/eventApi";
import useFetchEvents from "@hooks/useFetchEvents";
import EventPageView from "@views/EventPage/EventPageView";
import PageWrapper from "@views/common/PageWrapper";
import LoadingView from "@views/common/LoadingView";
import NotFoundPage from "@pages/404";
interface InitialProps {
initialEvent: Event;
event: Event;
}
const EventPage: NextPage<InitialProps> = ({ initialEvent }) => {
const EventPage: NextPage<InitialProps> = ({ event }) => {
const router = useRouter();
const { id } = router.query;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { data, error } = useFetchEvents({ initialData: initialEvent, id: id as string });
if (router.isFallback) return <LoadingView />;
if (!data) {
return (
<NotFoundPage />
);
}
return (
<>
<Head>
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/events/${id}`} />
</Head>
<PageWrapper>
<EventPageView event={data as Event} />
<EventPageView event={event} />
</PageWrapper>
</>
);
@@ -58,17 +47,17 @@ export const getStaticPaths: GetStaticPaths = async () => {
export const getStaticProps: GetStaticProps<InitialProps> = async ({ params }) => {
const { id } = params;
let notFound = false;
let initialEvent: Event;
let event: Event;
try {
initialEvent = await EventApi.getEvent(Number(id));
event = await EventApi.getEvent(Number(id));
} catch (err) {
notFound = true;
}
return {
props: {
initialEvent,
event,
},
revalidate: 10,
revalidate: 10, // Required for deleting hidden pages
notFound,
};
};
+7 -18
View File
@@ -4,38 +4,27 @@ import Head from "next/head";
import { useRouter } from "next/router";
import Post from "@models/Feed";
import FeedApi from "@api/feedApi";
import useFetchFeed from "@hooks/useFetchFeed";
import FeedPageView from "@views/FeedPage/FeedPageView";
import PageWrapper from "@views/common/PageWrapper";
import LoadingView from "@views/common/LoadingView";
import NotFoundPage from "@pages/404";
interface InitialProps {
initialPost: Post;
post: Post;
}
const FeedPage: NextPage<InitialProps> = ({ initialPost }) => {
const FeedPage: NextPage<InitialProps> = ({ post }) => {
const router = useRouter();
const { id } = router.query;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { data, error } = useFetchFeed({ initialData: initialPost, id: id as string });
if (router.isFallback) return <LoadingView />;
if (!data) {
return (
<NotFoundPage />
);
}
return (
<>
<Head>
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/feed/${id}`} />
</Head>
<PageWrapper>
<FeedPageView post={data} />
<FeedPageView post={post} />
</PageWrapper>
</>
);
@@ -58,18 +47,18 @@ export const getStaticPaths: GetStaticPaths = async () => {
export const getStaticProps: GetStaticProps<InitialProps> = async ({ params }) => {
const { id } = params;
let notFound = false;
let initialPost: Post;
let post: Post;
try {
initialPost = await FeedApi.getPost(Number(id));
post = await FeedApi.getPost(Number(id));
} catch (err) {
notFound = true;
}
return {
props: {
initialPost,
post,
},
revalidate: 10,
revalidate: 10, // Required for deleting hidden pages
notFound,
};
};
+30 -17
View File
@@ -2,7 +2,10 @@ import React from "react";
import { NextPage, GetStaticProps, GetStaticPaths } from "next";
import Head from "next/head";
import { useRouter } from "next/router";
import { ISubmitEvent } from "react-jsonschema-form";
import { toast } from "react-toastify";
import axios from "axios";
import useSWR, { mutate } from "swr";
import { Signup, SignupForm } from "@models/Signup";
import SignupApi from "@api/signupApi";
import SignUpPageView from "@views/SignUpPage/SignUpPageView";
@@ -12,34 +15,44 @@ import noop from "@utils/noop";
import NotFoundPage from "@pages/404";
type InitialProps = {
form: SignupForm;
initialForm: SignupForm;
};
const SignUpPage: NextPage<InitialProps> = ({ form }) => {
const router = useRouter();
const FORM_URL = `${process.env.NEXT_PUBLIC_API_URL}/signupForm/`;
if (router.isFallback) {
const SignUpPage: NextPage<InitialProps> = ({ initialForm }) => {
const router = useRouter();
const id = String(initialForm?.id ?? "");
const URL = `${FORM_URL}${id}/`;
const { data, error } = useSWR<SignupForm>(URL, (url) => axios.get(url).then((res) => res.data), { initialData: initialForm });
if (error) {
console.error(error);
}
// TODO: Shows LoadingView on client-side fetch error. Maybe something else preferred?
if (router.isFallback || error) {
return <LoadingView />;
}
if (!form) {
if (!data) {
return (
<NotFoundPage />
);
}
const onSubmit = async (data) => {
const onSubmit = async ({ formData }: ISubmitEvent<string>) => {
const payload: Signup = {
signupForm_id: form.id,
answer: data.formData,
signupForm_id: data.id,
answer: formData,
};
try {
await SignupApi.createSignup(payload);
toast.success("Sign-up submitted successfully 😎");
router.push(window.location.href); // TODO: Fetch/update signup list, so user sees the signup in the list
} catch (error) {
console.error(error);
mutate(URL);
} catch (err) {
console.error(err);
toast.error("Uh oh! Sign-up failed! 😟");
}
};
@@ -47,11 +60,11 @@ const SignUpPage: NextPage<InitialProps> = ({ form }) => {
return (
<>
<Head>
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/signup/${form.id}`} />
<link rel="canonical" href={`${process.env.NEXT_PUBLIC_SITE_URL}/signup/${data.id}`} />
</Head>
<PageWrapper>
<SignUpPageView
signUpForm={form}
signUpForm={data}
formData={{}}
onChange={noop}
onSubmit={onSubmit}
@@ -78,17 +91,17 @@ export const getStaticPaths: GetStaticPaths = async () => {
export const getStaticProps: GetStaticProps<InitialProps> = async ({ params }) => {
const { id } = params;
let notFound = false;
let form: SignupForm;
let initialForm: SignupForm;
try {
form = await SignupApi.getForm(Number(id));
initialForm = await SignupApi.getForm(Number(id));
} catch {
notFound = true;
}
return {
props: {
form,
initialForm,
},
revalidate: 10,
revalidate: 10, // Required for deleting hidden pages
notFound,
};
};
-1
View File
@@ -60,7 +60,6 @@ const EditSignUpPage: NextPage = () => {
try {
await SignupApi.updateSignup(payload, uuid);
// TODO: Update signup list, so user sees possible changes in the list
toast.success("Sign-up updated successfully 😎");
} catch (error) {
console.error(error);
+4 -3
View File
@@ -30,7 +30,7 @@ const orderedCommittees = [
Others,
];
const blank_profile = "/img/blank_profile.png";
const blankProfile = "/img/blank_profile.png";
const BlueLink = styled(Link)`
color: ${colors.blue1};
@@ -91,7 +91,7 @@ const CommitteeContainer: React.FC<{
name={representative.name}
phone={representative.phone_number}
email={representative.email}
image={(committee.name_en === "Board") ? (representative.image || blank_profile) : null}
image={(committee.name_en === "Board") ? (representative.image || blankProfile) : null}
role_fi={role.name_fi}
role_en={role.name_en}
/>
@@ -126,7 +126,8 @@ const ContactsPageView: React.FC = () => (
<TextSection>
<h1>Yhteystiedot</h1>
<p>
Asiaa olisi, mutta kehen ottaa yhteyttä?<br />
Asiaa olisi, mutta kehen ottaa yhteyttä?
<br />
Tämä sivu yrittää valottaa sen oikean ihmisen puhelinnumeroa ja sähköpostiosoitetta.
</p>
<aside>
@@ -11,6 +11,11 @@ const FreshmenPageHero: React.FC = () => (
/>
<HeroAside bgColor="lightTurquoise">
<HeroAsideItem
header="Lue killan fuksiopas"
link="https://static.sahkoinsinoorikilta.fi/FTMK/Fuksiopas2021.pdf"
linkText="lue fuksiopas täältä!"
/>
<HeroAsideItem
header="Seuraa killan tiedotusta"
link="https://t.me/joinchat/rKg3rCtAVkkyNTdk"
+23 -12
View File
@@ -15,6 +15,17 @@ const EMAIL_LINK_MAILTO = `mailto:${EMAIL_LINK}`;
const ImageContainer = styled.div`
width: 100%;
display: block;
margin: auto;
`;
const QRImages = styled.img`
width: 10em;
height: 10em;
`;
const FopasImage = styled.img`
width: 15em;
margin-bottom: 1em;
`;
const FreshmenPageView: React.FC = () => (
@@ -92,6 +103,16 @@ const FreshmenPageView: React.FC = () => (
</div>
<div>
<InfoBox>
<Link to="https://static.sahkoinsinoorikilta.fi/FTMK/Fuksiopas2021.pdf">
<FopasImage
src="https://static.sahkoinsinoorikilta.fi/FTMK/Fuksiopas2021-kansi.png"
/>
</Link>
<h6>Killan Fuksiopas</h6>
<p>Ennen opintojen alkua on hyvä tutustua killan fuksioppaaseen. Sitä pääset selailemaan
<Link to="https://static.sahkoinsinoorikilta.fi/FTMK/Fuksiopas2021.pdf"> tästä.</Link>
</p>
<br/>
<h6>Telegram?</h6>
<p>
Telegram on pikaviestinpalvelu, jota käytetään otaniemessä paljon.
@@ -101,23 +122,13 @@ const FreshmenPageView: React.FC = () => (
<p>
SIK:n fukseilla on oma Telegram-ryhmä, jonne pääset liitymään tästä:
</p>
<Image
<QRImages
src="https://static.sahkoinsinoorikilta.fi/FTMK/sik-fuksit-2021-tg.png"
alt="SIK-Fuksit 2021 TG"
layout="responsive"
width={0}
height={0}
objectFit="contain"
/>
<p>tai <Link to="https://tinyurl.com/sik-fuksit-2021">tästä</Link></p>
<p>Liity myös samalla SIK-fuksien tiedotuskanavalle tästä:</p>
<Image
<QRImages
src="https://static.sahkoinsinoorikilta.fi/FTMK/sik-fuksit-2021-tiedotus-tg.png"
alt="SIK-Fuksit 2021 Tiedotus TG"
layout="responsive"
width={0}
height={0}
objectFit="contain"
/>
<p>tai <Link to="https://tinyurl.com/sik-fuksit-2021-tiedotus">tästä</Link></p>
</InfoBox>
+1 -1
View File
@@ -76,7 +76,7 @@ const SignUpPageView: React.FC<SignUpPageViewProps> = ({
<h6>
{t("Ilmoittautuneet")} {signUpForm.quota > 0 && (` (${signUpForm.signups.length}/${signUpForm.quota})`)}:
</h6>
<ol>
<ol data-e2e="signup-list">
{signUpForm.signups.map((s, idx) => (
<li key={idx} className={signUpForm.quota && idx + 1 > signUpForm.quota ? "reserved" : ""}>{s}</li>
))}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"src": "tests/testcafe",
"browsers": "all",
"browsers": "chrome",
"concurrency": 1,
"screenshots": {
"path": "e2e-screenshots/",
+2
View File
@@ -58,4 +58,6 @@ test("User signups to event from front page", async (t) => {
.expect(
statusMessage.innerText,
).eql("Sign-up submitted successfully 😎");
await t.expect(Selector("[data-e2e=\"signup-list\"] > li").nth(0).innerText).eql("Testi Testeri");
});