Compare commits

...

3 commits

Author SHA1 Message Date
f6b4af7f04
Fix: comps starting at 1/2 final
Some checks failed
continuous-integration/drone/push Build is failing
2022-07-28 19:50:18 +02:00
146e3dd6c2
Fix: show error 2022-07-28 19:48:17 +02:00
79399032d6
Feat: dynamic title 2022-07-28 19:39:06 +02:00
14 changed files with 118 additions and 30 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 128 KiB

View file

@ -7,7 +7,7 @@
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
content="Web site to view flowcharts of german speedclimbing competitions"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
@ -24,7 +24,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
<title>blueROCK speed-flowchart</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 170 KiB

35
src/components/Header.tsx Normal file
View file

@ -0,0 +1,35 @@
import {
AppBar,
Toolbar,
Stepper,
Step,
Box,
Container,
StepButton,
Typography,
} from '@mui/material';
import { useContext, useEffect, useState } from 'react';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import '../css/Header.css';
import { Context } from '../data/Context';
/**
* Creates a Header Component that displays the reservation steps
* @return {JSX.Element}
*/
export default function Header() {
const { title } = useContext(Context);
return (
<AppBar position='sticky'>
<Container maxWidth='lg'>
<Toolbar className='header-container'>
<Link to='/' style={{ textDecoration: 'none', color: 'inherit' }}>
<img src='/logo192.png' className='header-icon'></img>
</Link>
<Typography variant='h6'>{title}</Typography>
</Toolbar>
</Container>
</AppBar>
);
}

9
src/css/Header.css Normal file
View file

@ -0,0 +1,9 @@
.header-container {
gap: 40px;
flex-direction: row;
}
.header-icon {
height: 50px;
display: block;
}

View file

@ -7,6 +7,14 @@ import { DigitalrockAPi } from './DigitalrockApi';
*/
export const Context = createContext<{
api: DigitalrockAPi;
title: string;
setTitle: (title: string) => void;
}>({
api: new DigitalrockAPi(),
title: '',
setTitle: () => {
return;
},
});

View file

@ -212,11 +212,12 @@ export function convertResultsToSpeedFlowchartResult(
// - 1, 4, 2, 3 for firstRoundNumber=4
// - 1, 2 for firstRoundNumber=2
// TODO: come up with a proper alogorithm maybe
console.log('First round rank: ', firstRoundRank);
const ranksOfLaneAInOrder = [
[1, 2],
[1, 4, 2, 3],
[1, 8, 4, 5, 2, 7, 3, 6],
][firstRoundRank / 4];
][Math.floor(firstRoundRank / 4)];
const firstRoundPairs = ranksOfLaneAInOrder.map(rank => {
return {

View file

@ -5,9 +5,12 @@ export interface Competiton {
WetId: string;
rkey: string;
name: string;
comp_name: string;
date_span: string;
discipline?: string;
cats: Category[];
categorys: Category[];
date: string;
}
export interface RouteNames {
@ -25,4 +28,5 @@ export interface RouteNames {
export interface SpeedCompetitionCategoryResult extends Competiton {
route_names: RouteNames;
participants: ParticipantFromApi[];
route_order: string;
}

View file

@ -23,9 +23,13 @@ export default function CalendarPage() {
React.useState<Competiton[]>();
const [filter, setFilter] = React.useState<string>();
const { api } = React.useContext(Context);
const { api, setTitle } = React.useContext(Context);
const navigate = useNavigate();
React.useEffect(() => {
setTitle('DAV calendar');
}, []);
React.useEffect(() => {
api.getCompetitions('GER').then(result => {
console.log(result.competitions.filter);
@ -42,9 +46,14 @@ export default function CalendarPage() {
}, [filter]);
const filterCompetitions = (competitions: Competiton[]) => {
return competitions.filter(c =>
c.name.toLowerCase().includes(filter?.toLocaleLowerCase() ?? ''),
);
return competitions.filter(c => {
const queryMatches = c.name
.toLowerCase()
.includes(filter?.toLocaleLowerCase() ?? '');
const date = new Date(c.date).getTime();
const currentDate = new Date().getTime();
return queryMatches && currentDate - date > 24 * 60 * 60 * 1000;
});
};
const openCompetition = (competitionId: string, categoryId: string) => {

View file

@ -13,7 +13,7 @@ import { Card, CardContent, Grid, Typography } from '@mui/material';
*/
export default function SpeedFlowchartPage() {
const { competitionId, categoryId } = useParams();
const { api } = useContext(Context);
const { api, setTitle } = useContext(Context);
const [flowchartResult, setFlowchartResult] =
useState<SpeedFlowchartResult>();
@ -24,6 +24,12 @@ export default function SpeedFlowchartPage() {
}
api.getCompetitionResults(competitionId, categoryId).then(r => {
setTitle(
`${r.comp_name} - ${
r.categorys.filter(cat => cat.GrpId === categoryId)[0].name
}`,
);
const flowchartResult = convertResultsToSpeedFlowchartResult(r);
console.log(flowchartResult);
setFlowchartResult(flowchartResult);
@ -32,7 +38,6 @@ export default function SpeedFlowchartPage() {
return (
<>
<h1>RESULT:</h1>
<Grid container spacing={2}>
{flowchartResult?.rounds.map((round, roundKey) => (
<Grid key={`flowchart-column-${roundKey}`} item xs={12 / 5}>
@ -71,6 +76,12 @@ export default function SpeedFlowchartPage() {
</Grid>
</Grid>
))}
{flowchartResult === undefined && (
<Grid item xs={12} className={'center-children'}>
This competition or category does not have a speed tree!
</Grid>
)}
</Grid>
</>
);

View file

@ -1,3 +1,4 @@
import React from 'react';
import { Context } from '../data/Context';
import { DigitalrockAPi } from '../data/DigitalrockApi';
@ -10,6 +11,11 @@ export default function ContextWrapper(props: { children: JSX.Element }) {
const { children } = props;
const api = new DigitalrockAPi();
const [title, setTitle] = React.useState('');
return <Context.Provider value={{ api }}>{children}</Context.Provider>;
return (
<Context.Provider value={{ api, title, setTitle }}>
{children}
</Context.Provider>
);
}

View file

@ -11,16 +11,14 @@ export default function PageTemplate(props: { children: JSX.Element }) {
const { children } = props;
return (
<ContextWrapper>
<LocalizationProviderWrapper>
<Container
sx={{ marginTop: '50px' }}
sx={{ marginTop: '16px' }}
className='root-container'
maxWidth='lg'
>
{children}
</Container>
</LocalizationProviderWrapper>
</ContextWrapper>
);
}

View file

@ -1,6 +1,8 @@
import { Routes, Route, HashRouter } from 'react-router-dom';
import Header from '../components/Header';
import CalendarPage from '../pages/CalendarPage';
import SpeedFlowchartPage from '../pages/SpeedFlowchartPage';
import ContextWrapper from './ContextWrapper';
import PageTemplate from './PageTemplate';
/**
@ -10,6 +12,9 @@ import PageTemplate from './PageTemplate';
export default function Routing() {
return (
<HashRouter>
<ContextWrapper>
<>
<Header />
<PageTemplate>
<Routes>
<Route path='/' element={<CalendarPage />} />
@ -19,6 +24,8 @@ export default function Routing() {
></Route>
</Routes>
</PageTemplate>
</>
</ContextWrapper>
</HashRouter>
);
}