Compare commits
3 commits
1f99528511
...
f6b4af7f04
Author | SHA1 | Date | |
---|---|---|---|
f6b4af7f04 | |||
146e3dd6c2 | |||
79399032d6 |
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 |
|
@ -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
35
src/components/Header.tsx
Normal 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
9
src/css/Header.css
Normal file
|
@ -0,0 +1,9 @@
|
|||
.header-container {
|
||||
gap: 40px;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
height: 50px;
|
||||
display: block;
|
||||
}
|
|
@ -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;
|
||||
},
|
||||
});
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -11,16 +11,14 @@ export default function PageTemplate(props: { children: JSX.Element }) {
|
|||
const { children } = props;
|
||||
|
||||
return (
|
||||
<ContextWrapper>
|
||||
<LocalizationProviderWrapper>
|
||||
<Container
|
||||
sx={{ marginTop: '50px' }}
|
||||
className='root-container'
|
||||
maxWidth='lg'
|
||||
>
|
||||
{children}
|
||||
</Container>
|
||||
</LocalizationProviderWrapper>
|
||||
</ContextWrapper>
|
||||
<LocalizationProviderWrapper>
|
||||
<Container
|
||||
sx={{ marginTop: '16px' }}
|
||||
className='root-container'
|
||||
maxWidth='lg'
|
||||
>
|
||||
{children}
|
||||
</Container>
|
||||
</LocalizationProviderWrapper>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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,15 +12,20 @@ import PageTemplate from './PageTemplate';
|
|||
export default function Routing() {
|
||||
return (
|
||||
<HashRouter>
|
||||
<PageTemplate>
|
||||
<Routes>
|
||||
<Route path='/' element={<CalendarPage />} />
|
||||
<Route
|
||||
path='/speed-flowchart/:competitionId/:categoryId'
|
||||
element={<SpeedFlowchartPage />}
|
||||
></Route>
|
||||
</Routes>
|
||||
</PageTemplate>
|
||||
<ContextWrapper>
|
||||
<>
|
||||
<Header />
|
||||
<PageTemplate>
|
||||
<Routes>
|
||||
<Route path='/' element={<CalendarPage />} />
|
||||
<Route
|
||||
path='/speed-flowchart/:competitionId/:categoryId'
|
||||
element={<SpeedFlowchartPage />}
|
||||
></Route>
|
||||
</Routes>
|
||||
</PageTemplate>
|
||||
</>
|
||||
</ContextWrapper>
|
||||
</HashRouter>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue