Refactor: reimplement flowchart calculation
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
parent
cb63919d40
commit
476cd0bd61
6 changed files with 329 additions and 241 deletions
|
@ -15,6 +15,7 @@ interface CompetitionList {
|
|||
*/
|
||||
export class DigitalrockAPi {
|
||||
private BASE_URL = 'https://www.digitalrock.de/egroupware/ranking/json.php?';
|
||||
// private BASE_URL = '/test.json?';
|
||||
|
||||
/**
|
||||
* function to get competitions
|
||||
|
|
|
@ -1,9 +1,22 @@
|
|||
import { SpeedCompetitionCategoryResult } from '../models/Competition';
|
||||
import { Participant } from '../models/Participant';
|
||||
import {
|
||||
RouteNames,
|
||||
SpeedCompetitionCategoryResult,
|
||||
} from '../models/Competition';
|
||||
import {
|
||||
Participant,
|
||||
participantFromApiParticipant,
|
||||
} from '../models/Participant';
|
||||
|
||||
export interface SpeedRoundParticipant {
|
||||
id: string;
|
||||
firstName: string;
|
||||
hasWon: boolean;
|
||||
}
|
||||
|
||||
export interface SpeedRoundPair {
|
||||
laneA?: Participant;
|
||||
laneB?: Participant;
|
||||
winner?: 'A' | 'B';
|
||||
}
|
||||
|
||||
export interface SpeedRound {
|
||||
|
@ -12,217 +25,217 @@ export interface SpeedRound {
|
|||
roundName?: string;
|
||||
}
|
||||
|
||||
export interface SpeedFlowchartResult {
|
||||
rounds: SpeedRound[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for use with speed flowcharts
|
||||
*/
|
||||
export class SpeedFlowchart {
|
||||
private _result: SpeedCompetitionCategoryResult;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {SpeedCompetitionCategoryResult} result
|
||||
* @param {number} roundNumber
|
||||
* @param {RouteNames} routeNames
|
||||
* @return {string | undefined}
|
||||
*/
|
||||
constructor(result: SpeedCompetitionCategoryResult) {
|
||||
this._result = result;
|
||||
}
|
||||
function getRoundName(
|
||||
roundNumber: number,
|
||||
routeNames: RouteNames,
|
||||
): string | undefined {
|
||||
if (roundNumber < 2 || roundNumber > 6) return undefined;
|
||||
|
||||
/**
|
||||
return routeNames[roundNumber];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return {SpeedRound[]} list of speed rounds
|
||||
* @param {string} name
|
||||
* @return {number}
|
||||
*/
|
||||
public _convert() {
|
||||
const allData: SpeedRound[] = [];
|
||||
function getRoundRank(name: string): number {
|
||||
const match = name.match(/1\/([842])/);
|
||||
console.log(match);
|
||||
if (match === undefined || match === null || match.length !== 2) {
|
||||
return 2;
|
||||
}
|
||||
return parseInt(match[1]);
|
||||
}
|
||||
|
||||
const rounds =
|
||||
Object.keys(this._result.route_names).length > 2
|
||||
? this._result.route_names['2']?.includes('8')
|
||||
? 2
|
||||
: 1
|
||||
: 0;
|
||||
|
||||
const setAorB = (pair: SpeedRoundPair, participant: Participant) => {
|
||||
if (pair.laneA === undefined) pair.laneA = participant;
|
||||
else pair.laneB = participant;
|
||||
};
|
||||
// console.log(this._result.route_names);
|
||||
|
||||
for (const round in this._result.route_names) {
|
||||
/**
|
||||
*
|
||||
* @param {SpeedRoundPair} pair
|
||||
* @param {number} roundIndex
|
||||
*/
|
||||
function computeWinnerOfPair(pair: SpeedRoundPair, roundIndex: number) {
|
||||
if (
|
||||
Object.keys(this._result.route_names).indexOf(round) >= 0 &&
|
||||
parseInt(round) >= 0
|
||||
) {
|
||||
// console.log(round);
|
||||
pair.laneA?.results[roundIndex]?.rank === undefined ||
|
||||
pair.laneB?.results[roundIndex]?.rank === undefined
|
||||
)
|
||||
return;
|
||||
|
||||
if (parseInt(round) === 0) {
|
||||
// this is the first round
|
||||
|
||||
// find pairs (always worse vs. best (1-16; 1-15; ...)) (they are sorted by the rank of the better athlete (1-2-3-4-5-6-7-8)
|
||||
|
||||
const qualificationResults: Participant[] = [];
|
||||
|
||||
for (let x = 0; x < this._result.participants.length; x++) {
|
||||
qualificationResults.push(this._result.participants[x]);
|
||||
}
|
||||
|
||||
qualificationResults.sort(function (a, b) {
|
||||
return (
|
||||
parseInt(a.result_rank0 ?? '') - parseInt(b.result_rank0 ?? '')
|
||||
);
|
||||
});
|
||||
|
||||
const nextRoundPairs: SpeedRoundPair[] = [];
|
||||
const totalMatches =
|
||||
(Object.keys(this._result.route_names).length > 2
|
||||
? this._result.route_names['2']?.includes('8')
|
||||
? 2
|
||||
: 1
|
||||
: 0) + 2;
|
||||
const nextRoundMatches = Math.pow(2, totalMatches - 1);
|
||||
|
||||
for (let i = 0; i < nextRoundMatches; i++) {
|
||||
nextRoundPairs.push({
|
||||
laneA: qualificationResults[i],
|
||||
laneB: qualificationResults[nextRoundMatches * 2 - i - 1],
|
||||
});
|
||||
}
|
||||
|
||||
// build second round pairs (sorted by the rank of the better athlete and worst vs. best (1-8; 2-7; ... ))
|
||||
|
||||
const sortedFirstRoundPairs: [SpeedRoundPair?, SpeedRoundPair?][] =
|
||||
[];
|
||||
|
||||
for (let i = 0; i < nextRoundMatches; i += 1) {
|
||||
sortedFirstRoundPairs.push([
|
||||
nextRoundPairs.shift(),
|
||||
nextRoundPairs.pop(),
|
||||
]);
|
||||
}
|
||||
|
||||
// sort these pairs (containing two pairs of athletes) by the rank of the better athlete (1-4;2-3)
|
||||
|
||||
const finalSortedFirstRoundPairs = [];
|
||||
|
||||
for (let i = 0; i < nextRoundMatches / 4; i++) {
|
||||
finalSortedFirstRoundPairs.push(sortedFirstRoundPairs[i]);
|
||||
finalSortedFirstRoundPairs.push(
|
||||
sortedFirstRoundPairs[nextRoundMatches / 2 - i - 1],
|
||||
);
|
||||
}
|
||||
|
||||
// convert the list of pairs of pairs of athletes back to a single list of pairs of athletes
|
||||
|
||||
const finalFirstRoundPairs: SpeedRoundPair[] = [];
|
||||
|
||||
for (let i = 0; i < finalSortedFirstRoundPairs.length; i++) {
|
||||
const [laneA, laneB] = finalSortedFirstRoundPairs[i];
|
||||
if (laneA !== undefined) finalFirstRoundPairs.push(laneA);
|
||||
if (laneB !== undefined) finalFirstRoundPairs.push(laneB);
|
||||
}
|
||||
|
||||
// push the first round to all data
|
||||
allData.push({
|
||||
pairs: finalFirstRoundPairs,
|
||||
roundIndex: 2,
|
||||
roundName: this._result.route_names[2] ?? '',
|
||||
});
|
||||
|
||||
// console.log(allData);
|
||||
} else if (parseInt(round) > 0) {
|
||||
// this is not the first round
|
||||
const nextRound: SpeedRound = {
|
||||
pairs: [],
|
||||
roundIndex: -1,
|
||||
roundName: '',
|
||||
};
|
||||
|
||||
// only used when the current round is the 1/2 final
|
||||
const smallFinal: SpeedRoundPair = {};
|
||||
const Final: SpeedRoundPair = {};
|
||||
|
||||
for (
|
||||
let i = 0;
|
||||
i < allData[allData.length - 1].pairs.length;
|
||||
i += 1
|
||||
) {
|
||||
const thisPair: SpeedRoundPair =
|
||||
allData[allData.length - 1].pairs[i];
|
||||
let thisWinner;
|
||||
let thisLooser;
|
||||
const thisWinnerIsFirstOfNewPair = i % 2 === 0;
|
||||
|
||||
if (thisPair.laneA === undefined || thisPair.laneB === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (thisWinnerIsFirstOfNewPair) {
|
||||
nextRound.pairs.push({});
|
||||
}
|
||||
|
||||
if (
|
||||
Object.keys(thisPair.laneA).indexOf('result_rank' + round) < 0 ||
|
||||
Object.keys(thisPair.laneB).indexOf('result_rank' + round) < 0
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (
|
||||
parseInt(thisPair.laneA['result_rank' + round] as string) <
|
||||
parseInt(thisPair.laneB['result_rank' + round] as string)
|
||||
) {
|
||||
thisWinner = thisPair.laneA;
|
||||
thisLooser = thisPair.laneB;
|
||||
} else if (
|
||||
parseInt(thisPair.laneA['result_rank' + round] as string) >
|
||||
parseInt(thisPair.laneB['result_rank' + round] as string)
|
||||
) {
|
||||
thisWinner = thisPair.laneB;
|
||||
thisLooser = thisPair.laneA;
|
||||
} else {
|
||||
// no result yet!!
|
||||
/* console.log(
|
||||
'got no winner yet, rank 0: ' +
|
||||
thisPair.laneA['result_rank' + round] +
|
||||
' rank 1: ' +
|
||||
thisPair.laneB['result_rank' + round],
|
||||
);*/
|
||||
continue;
|
||||
}
|
||||
|
||||
// console.log(thisWinner['firstname'] + ' has won in round ' + round);
|
||||
|
||||
if (parseInt(round) - rounds === 2) {
|
||||
// if we are in the 1/2 final
|
||||
setAorB(Final, thisWinner);
|
||||
setAorB(smallFinal, thisLooser);
|
||||
} else {
|
||||
setAorB(nextRound.pairs[nextRound.pairs.length - 1], thisWinner);
|
||||
}
|
||||
}
|
||||
|
||||
if (smallFinal.laneA !== undefined && Final.laneA !== undefined) {
|
||||
// Final
|
||||
allData.push({
|
||||
pairs: [Final],
|
||||
roundIndex: parseInt(round) + 2,
|
||||
roundName:
|
||||
this._result.route_names[String(parseInt(round) + 2)] +
|
||||
' / ' +
|
||||
this._result.route_names[String(parseInt(round) + 1)],
|
||||
});
|
||||
// small Final
|
||||
allData.push({
|
||||
pairs: [smallFinal],
|
||||
roundIndex: parseInt(round) + 1,
|
||||
});
|
||||
} else {
|
||||
nextRound.roundIndex = parseInt(round) + 1;
|
||||
nextRound.roundName = this._result.route_names[parseInt(round) + 1];
|
||||
allData.push(nextRound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return allData;
|
||||
if (pair.winner === undefined) {
|
||||
pair.winner =
|
||||
pair.laneA.results[roundIndex].rank > pair.laneB.results[roundIndex].rank
|
||||
? 'B'
|
||||
: 'A';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {SpeedRoundPair} pair
|
||||
* @param {number} roundNumber
|
||||
* @return {Participant | undefined}
|
||||
*/
|
||||
function getWinnerOfPair(
|
||||
pair: SpeedRoundPair,
|
||||
roundNumber: number,
|
||||
): Participant | undefined {
|
||||
computeWinnerOfPair(pair, roundNumber);
|
||||
return pair.winner === 'A' ? pair.laneA : pair.laneB;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {SpeedRoundPair} pair
|
||||
* @param {number} roundNumber
|
||||
* @return {Participant | undefined}
|
||||
*/
|
||||
function getLooserOfPair(
|
||||
pair: SpeedRoundPair,
|
||||
roundNumber: number,
|
||||
): Participant | undefined {
|
||||
computeWinnerOfPair(pair, roundNumber);
|
||||
return pair.winner === 'A' ? pair.laneB : pair.laneA;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {number} roundIndex index of the new round
|
||||
* @param {string} roundName name of the new round
|
||||
* @param {SpeedRound} previousRound
|
||||
* @param {boolean} takeLooser
|
||||
* @return {SpeedRound}
|
||||
*/
|
||||
function computeRoundFromPreviousRound(
|
||||
roundIndex: number,
|
||||
roundName: string,
|
||||
previousRound: SpeedRound,
|
||||
takeLooser = false,
|
||||
): SpeedRound {
|
||||
const getAdvancingParticipant = takeLooser
|
||||
? getLooserOfPair
|
||||
: getWinnerOfPair;
|
||||
const nextRoundPairs = new Array(previousRound.pairs.length / 2)
|
||||
.fill(0)
|
||||
.map((_, i) => {
|
||||
return {
|
||||
laneA: getAdvancingParticipant(
|
||||
previousRound.pairs[i * 2],
|
||||
previousRound.roundIndex,
|
||||
),
|
||||
laneB: getAdvancingParticipant(
|
||||
previousRound.pairs[i * 2 + 1],
|
||||
previousRound.roundIndex,
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
pairs: nextRoundPairs,
|
||||
roundIndex: roundIndex,
|
||||
roundName: roundName,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {SpeedCompetitionCategoryResult} result The result to process
|
||||
* @return {SpeedFlowchartResult}
|
||||
*/
|
||||
export function convertResultsToSpeedFlowchartResult(
|
||||
result: SpeedCompetitionCategoryResult,
|
||||
): SpeedFlowchartResult {
|
||||
const rounds: SpeedRound[] = [];
|
||||
const convertedParticipants = result.participants
|
||||
.map(fromApi => participantFromApiParticipant(fromApi))
|
||||
// sort by qualification result
|
||||
.sort((a, b) => a.results[0].rank - b.results[0].rank);
|
||||
|
||||
const roundIndices = Object.keys(result.route_names)
|
||||
.map(number => parseInt(number))
|
||||
.filter(number => number > 0);
|
||||
|
||||
console.log(`Have final rounds:`, roundIndices);
|
||||
|
||||
// process first round
|
||||
const firstRoundName = getRoundName(roundIndices[0], result.route_names);
|
||||
const firstRoundNumber = getRoundRank(
|
||||
getRoundName(roundIndices[0], result.route_names) ?? '',
|
||||
);
|
||||
|
||||
const getOpponent = (ofRank: number): Participant => {
|
||||
return convertedParticipants[firstRoundNumber * 2 - 1 - ofRank];
|
||||
};
|
||||
|
||||
// Should be:
|
||||
// 0, 1, 2, 3, 4, 5, 6, 7
|
||||
// - 1,16, 8, 9, 4,13, 5,12, 2,15, 7,10, 3,14, 6,11
|
||||
// - 1, 8, 4, 5, 2, 7, 3, 6 for firstRoundNumber=8
|
||||
// - 1, 4, 2, 3 for firstRoundNumber=4
|
||||
// - 1, 2 for firstRoundNumber=2
|
||||
// TODO: come up with a proper alogorithm maybe
|
||||
const ranksOfLaneAInOrder = [
|
||||
[1, 2],
|
||||
[1, 4, 2, 3],
|
||||
[1, 8, 4, 5, 2, 7, 3, 6],
|
||||
][firstRoundNumber / 4];
|
||||
console.log(ranksOfLaneAInOrder);
|
||||
|
||||
const firstRoundPairs = ranksOfLaneAInOrder.map(rank => {
|
||||
return {
|
||||
laneA: convertedParticipants[rank - 1],
|
||||
laneB: getOpponent(rank - 1),
|
||||
};
|
||||
});
|
||||
|
||||
const firstRound: SpeedRound = {
|
||||
pairs: firstRoundPairs,
|
||||
roundIndex: roundIndices[0],
|
||||
roundName: firstRoundName,
|
||||
};
|
||||
|
||||
rounds.push(firstRound);
|
||||
|
||||
// compute following rounds
|
||||
for (let i = 1; i < roundIndices.length - 2; i++) {
|
||||
rounds.push(
|
||||
computeRoundFromPreviousRound(
|
||||
roundIndices[i],
|
||||
result.route_names[roundIndices[i]] ?? '',
|
||||
rounds[i - 1],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// compute final and semi final
|
||||
const semifinalRoundIndex = roundIndices[roundIndices.length - 2];
|
||||
const semifinal = computeRoundFromPreviousRound(
|
||||
semifinalRoundIndex,
|
||||
result.route_names[semifinalRoundIndex] ?? '',
|
||||
rounds[rounds.length - 1],
|
||||
true,
|
||||
);
|
||||
computeWinnerOfPair(semifinal.pairs[0], semifinalRoundIndex);
|
||||
rounds.push(semifinal);
|
||||
|
||||
const finalRoundIndex = roundIndices[roundIndices.length - 1];
|
||||
const final = computeRoundFromPreviousRound(
|
||||
finalRoundIndex,
|
||||
result.route_names[finalRoundIndex] ?? '',
|
||||
rounds[rounds.length - 2],
|
||||
);
|
||||
computeWinnerOfPair(final.pairs[0], finalRoundIndex);
|
||||
rounds.push(final);
|
||||
|
||||
return {
|
||||
rounds: rounds,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Category } from './Category';
|
||||
import { Participant } from './Participant';
|
||||
import { ParticipantFromApi } from './Participant';
|
||||
|
||||
export interface Competiton {
|
||||
WetId: string;
|
||||
|
@ -10,8 +10,7 @@ export interface Competiton {
|
|||
cats: Category[];
|
||||
}
|
||||
|
||||
export interface SpeedCompetitionCategoryResult extends Competiton {
|
||||
route_names: {
|
||||
export interface RouteNames {
|
||||
'0'?: string; // Qualification
|
||||
'1'?: string; // 1/16 - Final
|
||||
'2'?: string; // 1/8 - Final
|
||||
|
@ -21,6 +20,9 @@ export interface SpeedCompetitionCategoryResult extends Competiton {
|
|||
'6'?: string; // Final
|
||||
'-1'?: string; // General result
|
||||
[key: string]: string | undefined;
|
||||
};
|
||||
participants: Participant[];
|
||||
}
|
||||
|
||||
export interface SpeedCompetitionCategoryResult extends Competiton {
|
||||
route_names: RouteNames;
|
||||
participants: ParticipantFromApi[];
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/**
|
||||
* A pariticpant of a competition
|
||||
*/
|
||||
export interface Participant {
|
||||
export interface ParticipantFromApi {
|
||||
PerId: string;
|
||||
firstname: string;
|
||||
lastname: string;
|
||||
|
@ -13,5 +13,65 @@ export interface Participant {
|
|||
['result_rank4']?: string;
|
||||
['result_rank5']?: string;
|
||||
['result_rank6']?: string;
|
||||
[key: string]: string | number | undefined;
|
||||
[key: string]: string | number | boolean | undefined;
|
||||
}
|
||||
export interface Participant {
|
||||
id: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
results: Result[];
|
||||
overallRank?: number;
|
||||
}
|
||||
|
||||
export interface Result {
|
||||
rank: number;
|
||||
result: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to extract results from PartiipantFromApi
|
||||
* @param {ParticipantFromApi} fromApi
|
||||
* @return {Result[]}
|
||||
*/
|
||||
function _extractResults(fromApi: ParticipantFromApi): Result[] {
|
||||
const results: Result[] = Array(7);
|
||||
|
||||
const existingResults = Object.keys(fromApi).filter(key =>
|
||||
key.match(/result[0-9]/),
|
||||
);
|
||||
|
||||
for (const result of existingResults) {
|
||||
let roundNumber = 0;
|
||||
const match = result.match(/result([0-9])/);
|
||||
if (match !== undefined && match !== null) {
|
||||
roundNumber = parseInt(match[1]);
|
||||
}
|
||||
if (roundNumber < 0) {
|
||||
continue;
|
||||
}
|
||||
results[roundNumber] = {
|
||||
rank: parseInt(fromApi[`result_rank${roundNumber}`] as string),
|
||||
result: fromApi[`result${roundNumber}`] as string,
|
||||
};
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to clean up participants from the api
|
||||
* @param {ParticipantFromApi} fromApi
|
||||
* @return {Participant}
|
||||
*/
|
||||
export function participantFromApiParticipant(
|
||||
fromApi: ParticipantFromApi,
|
||||
): Participant {
|
||||
const results = _extractResults(fromApi);
|
||||
|
||||
return {
|
||||
id: fromApi.PerId,
|
||||
firstName: fromApi.firstname,
|
||||
lastName: fromApi.lastname,
|
||||
results: results,
|
||||
overallRank: fromApi.result_rank,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { Context } from '../data/Context';
|
||||
import { useContext, useEffect, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { SpeedFlowchart, SpeedRound } from '../data/SpeedFlowchart';
|
||||
import { Card, CardContent, Grid } from '@mui/material';
|
||||
import {
|
||||
convertResultsToSpeedFlowchartResult,
|
||||
SpeedFlowchartResult,
|
||||
} from '../data/SpeedFlowchart';
|
||||
import { Card, CardContent, Grid, Typography } from '@mui/material';
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -12,7 +15,8 @@ export default function SpeedFlowchartPage() {
|
|||
const { competitionId, categoryId } = useParams();
|
||||
const { api } = useContext(Context);
|
||||
|
||||
const [rounds, setRounds] = useState<SpeedRound[]>([]);
|
||||
const [flowchartResult, setFlowchartResult] =
|
||||
useState<SpeedFlowchartResult>();
|
||||
|
||||
useEffect(() => {
|
||||
if (competitionId === undefined || categoryId === undefined) {
|
||||
|
@ -20,12 +24,9 @@ export default function SpeedFlowchartPage() {
|
|||
}
|
||||
|
||||
api.getCompetitionResults(competitionId, categoryId).then(r => {
|
||||
const flowchart = new SpeedFlowchart(r);
|
||||
const rounds = flowchart
|
||||
._convert()
|
||||
.filter(round => round.roundName !== undefined && round.pairs.length);
|
||||
console.log(rounds);
|
||||
setRounds(rounds);
|
||||
const flowchartResult = convertResultsToSpeedFlowchartResult(r);
|
||||
console.log(flowchartResult);
|
||||
setFlowchartResult(flowchartResult);
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
@ -33,7 +34,7 @@ export default function SpeedFlowchartPage() {
|
|||
<>
|
||||
<h1>RESULT:</h1>
|
||||
<Grid container spacing={2}>
|
||||
{rounds.map((round, roundKey) => (
|
||||
{flowchartResult?.rounds.map((round, roundKey) => (
|
||||
<Grid key={`flowchart-column-${roundKey}`} item xs={12 / 5}>
|
||||
<h3>{round.roundName}</h3>
|
||||
<Grid container spacing={2}>
|
||||
|
@ -45,9 +46,20 @@ export default function SpeedFlowchartPage() {
|
|||
>
|
||||
<Card>
|
||||
<CardContent>
|
||||
A: {pair.laneA?.firstname} {pair.laneA?.lastname}
|
||||
<br />
|
||||
B: {pair.laneB?.firstname} {pair.laneB?.lastname}
|
||||
<Typography
|
||||
sx={{
|
||||
fontWeight: pair.winner === 'A' ? 'bold' : 'plain',
|
||||
}}
|
||||
>
|
||||
A: {pair.laneA?.firstName} {pair.laneA?.lastName}
|
||||
</Typography>
|
||||
<Typography
|
||||
sx={{
|
||||
fontWeight: pair.winner === 'B' ? 'bold' : 'plain',
|
||||
}}
|
||||
>
|
||||
B: {pair.laneB?.firstName} {pair.laneB?.lastName}
|
||||
</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</Grid>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { BrowserRouter, Routes, Route } from 'react-router-dom';
|
||||
import { BrowserRouter, Routes, Route, HashRouter } from 'react-router-dom';
|
||||
import CalendarPage from '../pages/CalendarPage';
|
||||
import SpeedFlowchartPage from '../pages/SpeedFlowchartPage';
|
||||
import PageTemplate from './PageTemplate';
|
||||
|
@ -9,16 +9,16 @@ import PageTemplate from './PageTemplate';
|
|||
*/
|
||||
export default function Routing() {
|
||||
return (
|
||||
<BrowserRouter>
|
||||
<HashRouter>
|
||||
<PageTemplate>
|
||||
<Routes>
|
||||
<Route path='/' element={<CalendarPage />} />
|
||||
<Route
|
||||
path='/#/speed-flowchart/:competitionId/:categoryId'
|
||||
path='/speed-flowchart/:competitionId/:categoryId'
|
||||
element={<SpeedFlowchartPage />}
|
||||
></Route>
|
||||
</Routes>
|
||||
</PageTemplate>
|
||||
</BrowserRouter>
|
||||
</HashRouter>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue