Frontend improvements (#253)

Install vercel analytics, update dependencies, show alerts in case there
is no active stage.
This commit is contained in:
Erik Vroon
2023-09-11 11:28:50 +02:00
committed by GitHub
parent 21ffd66150
commit fd33d0d4cd
8 changed files with 1278 additions and 627 deletions

View File

@@ -5,5 +5,6 @@ module.exports = {
tabWidth: 2,
importOrder: ["^@core/(.*)$", "^@server/(.*)$", "^@ui/(.*)$", "^[./]"],
importOrderSeparation: true,
importOrderSortSpecifiers: true
};
importOrderSortSpecifiers: true,
plugins: [require.resolve("@trivago/prettier-plugin-sort-imports")]
};

View File

@@ -28,6 +28,7 @@
"@next/bundle-analyzer": "^13.3.1",
"@react-icons/all-files": "^4.1.0",
"@tabler/icons-react": "^2.17.0",
"@vercel/analytics": "^1.0.2",
"axios": "^1.4.0",
"cookies-next": "^4.0.0",
"date-fns": "^2.29.3",
@@ -39,33 +40,33 @@
"swr": "^2.1.5"
},
"devDependencies": {
"@babel/core": "^7.21.0",
"@next/eslint-plugin-next": "^13.2.3",
"@testing-library/dom": "^9.2.0",
"@testing-library/jest-dom": "^6.0.0",
"@babel/core": "^7.22.17",
"@next/eslint-plugin-next": "^13.4.19",
"@testing-library/dom": "^9.3.1",
"@testing-library/jest-dom": "^6.1.3",
"@testing-library/react": "^14.0.0",
"@testing-library/user-event": "^14.4.3",
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
"@types/jest": "^29.5.2",
"@types/node": "^20.1.0",
"@types/react": "^18.2.0",
"@typescript-eslint/eslint-plugin": "^6.2.1",
"@typescript-eslint/parser": "^6.3.0",
"babel-loader": "^9.1.2",
"eslint": "^8.39.0",
"@trivago/prettier-plugin-sort-imports": "^4.2.0",
"@types/jest": "^29.5.4",
"@types/node": "^20.6.0",
"@types/react": "^18.2.21",
"@typescript-eslint/eslint-plugin": "^6.6.0",
"@typescript-eslint/parser": "^6.6.0",
"babel-loader": "^9.1.3",
"eslint": "^8.49.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-airbnb-typescript": "^17.1.0",
"eslint-config-mantine": "^2.0.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-jest": "^27.2.3",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.32.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-testing-library": "^6.0.0",
"jest": "^29.5.0",
"jest-environment-jsdom": "^29.5.0",
"prettier": "^3.0.1",
"ts-jest": "^29.1.0",
"typescript": "^5.0.4"
"eslint-plugin-testing-library": "^6.0.1",
"jest": "^29.6.4",
"jest-environment-jsdom": "^29.6.4",
"prettier": "^3.0.3",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
}
}

View File

@@ -49,6 +49,18 @@ export default function Brackets({
activeStageId == null ||
(!swrStagesResponse.isLoading && !responseIsValid(swrStagesResponse))
) {
if (readOnly) {
return (
<Alert
icon={<IconAlertCircle size={16} />}
title="No rounds found"
color="blue"
radius="lg"
>
Please wait for the organiser to add them.
</Alert>
);
}
return (
<Alert icon={<IconAlertCircle size={16} />} title="No rounds found" color="blue" radius="lg">
Add a round using the top right button.

View File

@@ -7,6 +7,7 @@ import { StageWithRounds } from '../../interfaces/stage';
import { Tournament } from '../../interfaces/tournament';
import UpcomingMatchesTable from '../tables/upcoming_matches';
import LadderFixed from './settings/ladder_fixed';
import SchedulingPlaceholder from './settings/placeholder';
import RoundRobin from './settings/round_robin';
function StageSettings({
@@ -16,7 +17,10 @@ function StageSettings({
activeStage?: StageWithRounds;
schedulerSettings: SchedulerSettings;
}) {
if (activeStage != null && activeStage.type === 'ROUND_ROBIN') {
if (activeStage == null) {
return <SchedulingPlaceholder />;
}
if (activeStage.type === 'ROUND_ROBIN') {
return <RoundRobin />;
}
return <LadderFixed schedulerSettings={schedulerSettings} />;

View File

@@ -0,0 +1,11 @@
import { Alert } from '@mantine/core';
import { IconAlertCircle } from '@tabler/icons-react';
import React from 'react';
export default function SchedulingPlaceholder() {
return (
<Alert icon={<IconAlertCircle size={16} />} title="No options" color="yellow" radius="lg">
There is no active stage.
</Alert>
);
}

View File

@@ -1,5 +1,6 @@
import { ColorScheme, ColorSchemeProvider, MantineProvider } from '@mantine/core';
import { Notifications } from '@mantine/notifications';
import { Analytics } from '@vercel/analytics/react';
import { getCookie, setCookie } from 'cookies-next';
import NextApp, { AppContext, AppProps } from 'next/app';
import Head from 'next/head';
@@ -31,6 +32,8 @@ export default function App(props: AppProps & { colorScheme: ColorScheme }) {
<Component {...pageProps} />
</MantineProvider>
</ColorSchemeProvider>
<Analytics />
</>
);
}

View File

@@ -15,7 +15,7 @@ import {
} from '@mantine/core';
import { FaGithub } from '@react-icons/all-files/fa/FaGithub';
import { IconMoonStars, IconSun } from '@tabler/icons-react';
import { useRouter } from 'next/router';
import { NextRouter, useRouter } from 'next/router';
import React, { Component, ReactNode } from 'react';
import { Brand } from '../components/navbar/_brand';
@@ -26,7 +26,7 @@ const LINKS = [
{ link: '/', label: 'Tournaments', links: null },
{ link: '/user', label: 'User', links: [{ link: '/user', label: 'Logout', icon: null }] },
{
link: '/docs',
link: null,
label: 'More',
links: [
{ link: 'https://evroon.github.io/bracket/', label: 'Website', icon: null },
@@ -78,15 +78,52 @@ const useStyles = createStyles((theme) => ({
},
}));
interface HeaderActionLink {
link: string | null;
label: string;
icon?: Component | null;
links?: { link: string; label: string; icon?: ReactNode }[] | null;
}
interface HeaderActionProps {
links: {
link: string;
label: string;
icon?: Component | null;
links?: { link: string; label: string; icon?: ReactNode }[] | null;
}[];
links: HeaderActionLink[];
navbarState: any;
}
function getMenuItemsForLink(link: HeaderActionLink, classes: any, router: NextRouter) {
const menuItems = link.links?.map((item) => (
<UnstyledButton
key={item.label}
className={classes.link}
onClick={async () => {
await router.push(item.link);
}}
>
{item.label}
</UnstyledButton>
));
return (
<Menu key={link.label} trigger="hover" transitionProps={{ exitDuration: 0 }} withinPortal>
<Menu.Target>
<UnstyledButton
className={classes.link}
onClick={async () => {
if (link.link) await router.push(link.link);
}}
>
<>
{link.icon}
<Text span className={classes.linkLabel}>
{link.label}
</Text>
</>
</UnstyledButton>
</Menu.Target>
<Menu.Dropdown>{menuItems}</Menu.Dropdown>
</Menu>
);
}
export function HeaderAction({ links, navbarState }: HeaderActionProps) {
const { classes } = useStyles();
@@ -96,37 +133,7 @@ export function HeaderAction({ links, navbarState }: HeaderActionProps) {
const items = links.map((link) => {
if (link.links) {
const menuItems = link.links?.map((item) => (
<UnstyledButton
key={item.label}
className={classes.link}
onClick={async () => {
await router.push(item.link);
}}
>
{item.label}
</UnstyledButton>
));
return (
<Menu key={link.label} trigger="hover" transitionProps={{ exitDuration: 0 }} withinPortal>
<Menu.Target>
<UnstyledButton
className={classes.link}
onClick={async () => {
await router.push(link.link);
}}
>
<>
{link.icon}
<Text span className={classes.linkLabel}>
{link.label}
</Text>
</>
</UnstyledButton>
</Menu.Target>
<Menu.Dropdown>{menuItems}</Menu.Dropdown>
</Menu>
);
return getMenuItemsForLink(link, classes, router);
}
return (
@@ -134,7 +141,7 @@ export function HeaderAction({ links, navbarState }: HeaderActionProps) {
key={link.label}
className={classes.link}
onClick={async () => {
await router.push(link.link);
if (link.link) await router.push(link.link);
}}
>
{link.label}

View File

File diff suppressed because it is too large Load Diff