-
- R: {red}
+}) {
+ return (
+
+
+ R: {red}
+
+
+ B: {blue}
+
-
- B: {blue}
-
-
-);
+ );
+}
export default AllianceFader;
diff --git a/src/components/MultiDisplay/EventRow/AllianceFader/styles.module.scss b/src/components/MultiDisplay/EventRow/AllianceFader/styles.module.scss
index 8a80b2e..6de43d3 100644
--- a/src/components/MultiDisplay/EventRow/AllianceFader/styles.module.scss
+++ b/src/components/MultiDisplay/EventRow/AllianceFader/styles.module.scss
@@ -1,5 +1,5 @@
-$teamlist-size: 5.5vh;
+$teamlist-size: 4vh;
.faderBase {
@@ -8,12 +8,13 @@ $teamlist-size: 5.5vh;
// Center items
justify-content: center;
align-items: center;
+ height: $teamlist-size;
&> div {
position: absolute;
transition: all ease .5s;
text-align: center;
- width: 30vw;
+ width: 25vw;
font-weight: bold;
border-radius: 1em;
font-size: $teamlist-size;
diff --git a/src/components/MultiDisplay/EventRow/MessageRow/index.tsx b/src/components/MultiDisplay/EventRow/MessageRow/index.tsx
index a3b072d..5fe3cfe 100644
--- a/src/components/MultiDisplay/EventRow/MessageRow/index.tsx
+++ b/src/components/MultiDisplay/EventRow/MessageRow/index.tsx
@@ -2,55 +2,35 @@ import { h } from 'preact';
import { Event } from '@shared/DbTypes';
// @ts-ignore
import { Textfit } from '@gmurph91/react-textfit';
+import { AnimatePresence } from 'motion/react';
import styles from './styles.module.scss';
+import PushInDiv from '../Shared/PushInDiv';
-const MessageRow = ({ event, showLine }: { event: Event; showLine: 0 | 1 | null }) => (
-
-
- {/* Logo/Event Name Short Fader */}
-
- {/* Logo */}
-
- {/*

*/}
-
- {/* Text */}
-
-
- {event.nameShort || event.name}
-
-
+function MessageRow({ event, overrideMessage }: { event: Event, overrideMessage?: string }) {
+ const effectiveMessage = overrideMessage || event.message || event.name;
+ return (
+
+
+
+
+
+ {effectiveMessage}
+
+
+
+ |
+ );
+}
- {/* Message */}
-
-
- {event.message || event.name}
-
-
-
-
-);
+MessageRow.defaultProps = {
+ overrideMessage: undefined,
+};
export default MessageRow;
diff --git a/src/components/MultiDisplay/EventRow/MessageRow/styles.module.scss b/src/components/MultiDisplay/EventRow/MessageRow/styles.module.scss
index a0452cf..6d3e8c0 100644
--- a/src/components/MultiDisplay/EventRow/MessageRow/styles.module.scss
+++ b/src/components/MultiDisplay/EventRow/MessageRow/styles.module.scss
@@ -1,59 +1,6 @@
-.messageContainer {
- transition: all ease .5s;
- position: relative;
- z-index: 3;
- height: 0;
- width: 0;
- left: -101vw;
-}
-
-.messageMover {
- width: 100vw;
- height: 22vh;
- background-color: black;
- display: flex;
- flex-direction: row;
- justify-content: space-around;
- align-items: center;
-
- &>span {
- width: 80%;
- }
-}
-
.messageText {
text-align: center;
- width: 75vw !important;
font-weight: bold;
- padding-left: 2vw;
-}
-
-.faderContainer {
- width: 25vw;
- height: 22vh;
-
- &>* {
- position: absolute;
- transition: all ease .5s;
- text-align: center;
- width: 25vw;
- top: 0;
- font-weight: bold;
- align-items: center;
- justify-content: center;
- }
-
- ;
-}
-
-.sponsorLogo {
- display: block;
- margin-top: 1vh;
- margin-bottom: 1vh;
- margin-left: auto;
- margin-right: auto;
- width: auto;
- height: auto;
- max-width: 15vw;
- max-height: 15vh;
+ margin-left: 2vw;
+ margin-right: 5vw;
}
\ No newline at end of file
diff --git a/src/components/MultiDisplay/EventRow/PlayoffRow/index.tsx b/src/components/MultiDisplay/EventRow/PlayoffRow/index.tsx
index ea8208b..4c056be 100644
--- a/src/components/MultiDisplay/EventRow/PlayoffRow/index.tsx
+++ b/src/components/MultiDisplay/EventRow/PlayoffRow/index.tsx
@@ -5,24 +5,36 @@ import {
ref,
onValue,
off,
- // update,
} from 'firebase/database';
-// @ts-ignore
-// import { Textfit } from '@gmurph91/react-textfit';
import { useEffect, useState } from 'preact/hooks';
import DoubleEliminationBracketMapping, {
BracketMatchNumber,
} from '@shared/DoubleEliminationBracketMapping';
+import { AnimatePresence } from 'motion/react';
import styles from '../sharedStyles.module.scss';
import { PlayoffMatchData } from '@/models/MatchData';
-import MessageRow from '../MessageRow';
import { PlayoffMatchDisplay } from '@/components/PlayoffQueueing/PlayoffMatchDisplay';
import AllianceFader from '../AllianceFader';
import getGenericText from '@/util/getGenericText';
+import PushInDiv from '../Shared/PushInDiv';
+import MessageRow from '../MessageRow';
type LoadingState = 'loading' | 'ready' | 'error' | 'noAutomatic';
-const PlayoffRow = ({
+function allianceDisplay(match: PlayoffMatchDisplay, alliance: 'red' | 'blue'): string {
+ if (alliance === 'red') {
+ if (match.result?.redAlliance) return `Alliance ${match.result.redAlliance}`;
+ return getGenericText(match.match?.participants.red);
+ }
+ if (alliance === 'blue') {
+ if (match.result?.blueAlliance) return `Alliance ${match.result.blueAlliance}`;
+ return getGenericText(match.match?.participants.blue);
+ }
+
+ return '';
+}
+
+function PlayoffRow({
event,
showLine,
season,
@@ -32,17 +44,13 @@ const PlayoffRow = ({
showLine: 0 | 1 | null;
season: string;
token: string;
-}) => {
+}) {
// Loading state
const [loadingState, setLoadingState] = useState
('loading');
// This row's matches
const [results, setResults] = useState>>({});
- // URL parameters
- const searchParams = new URLSearchParams(window.location.search);
- const useShortName = typeof searchParams.get('useShortName') === 'string';
-
// Matches to display
// eslint-disable-next-line max-len
const [displayMatches, setDisplayMatches] = useState({
@@ -104,7 +112,8 @@ const PlayoffRow = ({
// We have no way of knowing when a break is over, so to reduce confusion never show a break
// as the current match. If we're at the end of the matches we can show that
if (
- matchDisplays[currentMatchIndex].customDisplayText
+ matchDisplays[currentMatchIndex]
+ && matchDisplays[currentMatchIndex].customDisplayText
&& matchDisplays.length - 1 > currentMatchIndex
) {
currentMatchIndex += 1;
@@ -157,27 +166,12 @@ const PlayoffRow = ({
// Loading/Error Text
if (['loading', 'error'].includes(loadingState)) {
return (
- <>
- {/* Message */}
-
-
- {/* Loading */}
-
-
- {event && event.name && (
-
- {event.name}
-
-
- )}
-
- {loadingState === 'error'
- ? 'Failed to fetch matches'
- : 'Loading Matches...'}
-
- |
-
- >
+
);
}
@@ -185,67 +179,45 @@ const PlayoffRow = ({
if (loadingState === 'ready') {
return (
<>
- {/* Message */}
-
-
- {/* Quals */}
-
- {/* Field Name / Logo */}
-
- {/* Use event logo */}
- {!useShortName && (
-
- )}
-
- {/* Use event short name */}
- {useShortName && (
-
- {/* */}
- {event.nameShort || event.name}
- {/* */}
-
+ {/* Current Match */}
+ |
+
+ {currentMatch && (
+
+ {currentMatch.customDisplayText ?? currentMatch?.num === 'F'
+ ? 'F'
+ : `M${currentMatch?.num}`}
+
)}
- |
-
- {/* Current Match */}
- {currentMatch && (
-
- {currentMatch.customDisplayText ?? currentMatch?.num === 'F'
- ? 'F'
- : `M${currentMatch?.num}`}
- |
- )}
+
+
- {/* Next Match */}
-
- {/* Is a Match */}
+ {/* Next Match */}
+ |
+ {/* Is a Match */}
+
{nextMatch && (
-
+
{getDisplayText(nextMatch)}
{nextMatch?.match && showLine !== null && (
)}
-
+
)}
- |
+
+
- {/* Queueing Matches */}
-
+ {/* Queueing Matches */}
+ |
+
{/* Multiple Queueing Matches */}
{queueingMatches.length > 1
&& queueingMatches.map((x) => (
@@ -255,8 +227,8 @@ const PlayoffRow = ({
{x?.match && showLine !== null && (
)}
@@ -265,32 +237,30 @@ const PlayoffRow = ({
{/* Single Queueing Match */}
{queueingMatches.length === 1 && queueingMatches[0] && (
- <>
- {queueingMatches[0] && (
-
-
- {getDisplayText(queueingMatches[0])}
-
-
- {queueingMatches[0]?.match && showLine !== null && (
-
- )}
-
-
- )}
- >
+ queueingMatches[0] && (
+
+
+ {getDisplayText(queueingMatches[0])}
+
+
+ {queueingMatches[0]?.match && showLine !== null && (
+
+ )}
+
+
+ )
)}
- |
-
+
+
>
);
}
return null;
-};
+}
export default PlayoffRow;
diff --git a/src/components/MultiDisplay/EventRow/QualRow/index.tsx b/src/components/MultiDisplay/EventRow/QualRow/index.tsx
index 413fe4b..0256017 100644
--- a/src/components/MultiDisplay/EventRow/QualRow/index.tsx
+++ b/src/components/MultiDisplay/EventRow/QualRow/index.tsx
@@ -1,151 +1,25 @@
import { h, Fragment } from 'preact';
-import { useEffect, useState } from 'preact/hooks';
-import { QualMatch, Event } from '@shared/DbTypes';
-import {
- getDatabase,
- ref,
- onValue,
- off,
- // update,
-} from 'firebase/database';
-// @ts-ignore
-// import { Textfit } from '@gmurph91/react-textfit';
+import { Event, QualMatch } from '@shared/DbTypes';
+import { AnimatePresence } from 'motion/react';
import styles from '../sharedStyles.module.scss';
-import { Break, MatchOrBreak, QualMatchData } from '@/models/MatchData';
import AllianceFader from '../AllianceFader';
+import useQueueingQualMatches from '@/hooks/useQueueingQualMatches';
+import PushInDiv from '../Shared/PushInDiv';
import MessageRow from '../MessageRow';
-type LoadingState = 'loading' | 'ready' | 'error' | 'noAutomatic';
-
-const QualRow = ({
+function QualRow({
event,
showLine,
- season,
token,
}: {
- event: Event;
+ event: Event,
showLine: 0 | 1 | null;
- season: string;
token: string;
-}) => {
- // Loading state
- const [loadingState, setLoadingState] = useState('loading');
-
- // This row's matches
- const [qualMatches, setQualMatches] = useState([]);
-
- // URL parameters
- const searchParams = new URLSearchParams(window.location.search);
- const useShortName = typeof searchParams.get('useShortName') === 'string';
-
- // This row's breaks
- const [breaks, setBreaks] = useState([]);
-
- // Matches to display
- // eslint-disable-next-line max-len
- const [displayMatches, setDisplayMatches] = useState({
- currentMatch: null,
- nextMatch: null,
- queueingMatches: [],
+}) {
+ const queueingQualMatches = useQueueingQualMatches({
+ token,
+ numQueueing: 1,
});
-
- useEffect(() => {
- const matchesRef = ref(getDatabase(), `/seasons/${season}/qual/${token}`);
- onValue(matchesRef, (snap) => {
- setQualMatches(snap.val() as QualMatch[]);
- });
-
- const breaksRef = ref(getDatabase(), `/seasons/${season}/breaks/${token}`);
- onValue(breaksRef, (snap) => {
- setBreaks(snap.val() as Break[]);
- });
-
- return () => {
- off(matchesRef);
- off(breaksRef);
- };
- }, [season]);
-
- // eslint-disable-next-line max-len -- HOW TO MAKE THIS SHORT?
- const getMatchByNumber = (matchNumber: number): QualMatch | null => qualMatches?.find((x) => x.number === matchNumber) ?? null;
-
- const updateMatches = (e: Event): void => {
- const matchNumber = e.currentMatchNumber;
-
- // if (matchNumber === null || matchNumber === undefined) {
- // if (dbEventRef.current === undefined) return; // throw new Error('No event ref');
- // // TODO: Why does this always set the match to 1 on page load??
- // // update(dbEventRef.current, {
- // // currentMatchNumber: 1,
- // // }).catch((err) => {
- // // console.error(err);
- // // });
- // return;
- // }
-
- // Return if no match number
- if (matchNumber === null || matchNumber === undefined) return;
-
- try {
- // Make a new array of max queuing matches to display
- const maxQ = typeof e.options?.maxQueueingToShow === 'number'
- ? e.options?.maxQueueingToShow
- : 1;
- const toFill = new Array(maxQ).fill(null);
- toFill.forEach((_, i) => {
- toFill[i] = i + 2;
- });
-
- // Upcoming matches
- const upcoming: MatchOrBreak[] = [
- getMatchByNumber(matchNumber),
- getMatchByNumber(matchNumber + 1),
- ].concat(
- // Add Queueing Matches
- toFill
- .map((x) => getMatchByNumber(matchNumber + x))
- .filter((x) => x !== null) as QualMatch[],
- );
-
- // Calculate the max # of matches we should be displaying
- const maxMatches = 2 + maxQ; // current + next + queueing
-
- // See if there is an upcoming break
- breaks?.forEach((b: Break) => {
- // See if break start is inside what we're showing
- if (b.after < matchNumber + upcoming.length) {
- // Calculate the insert location
- const insertAt = (b.after - matchNumber) + 1;
- // Sanity
- if (insertAt < 0) return;
- // Insert break
- upcoming.splice(insertAt, 0, b);
- // Verify that the array is not too long
- if (upcoming.length > maxMatches) {
- upcoming.splice(maxMatches, upcoming.length - maxMatches);
- }
- }
- });
-
- const data = {
- currentMatch: upcoming[0],
- nextMatch: upcoming[1],
- queueingMatches: upcoming.slice(2),
- } as QualMatchData;
-
- setDisplayMatches(data);
- setLoadingState('ready');
- } catch (err: any) {
- setLoadingState('error');
- console.error(err);
- }
- };
-
- // On event change, check for matches
- useEffect(() => {
- if (event) updateMatches(event);
- }, [event.currentMatchNumber, qualMatches, breaks]);
-
// Calculate Red alliance string
const getRedStr = (match: QualMatch | null): string => {
if (!match) return '';
@@ -158,123 +32,90 @@ const QualRow = ({
return `${match.participants.Blue1} ${match.participants.Blue2} ${match.participants.Blue3}`;
};
- // Spread the match data
- const { currentMatch, nextMatch, queueingMatches } = displayMatches;
-
- // Message cases
- const case1 = ['loading', 'error'].includes(loadingState);
- const case2 = loadingState === 'ready' && (qualMatches?.length ?? 0) < 1;
+ const {
+ state, now, next, queueing, hasSchedule,
+ } = queueingQualMatches;
// Loading/Error Text
- if (case1 || case2) {
+ if (state !== 'ready' || !hasSchedule) {
+ let message = 'Loading Matches...';
+ if (state === 'error') {
+ message = 'Failed to fetch matches';
+ } else if (state !== 'loading' && !hasSchedule) {
+ message = 'Waiting for schedule to be posted...';
+ }
return (
- <>
- {/* Message */}
-
-
- {/* Loading */}
-
-
- {event && event.name && (
-
- {event.name}
-
-
- )}
-
- {/* eslint-disable-next-line no-nested-ternary */}
- {loadingState === 'error' && case1
- ? 'Failed to fetch matches'
- : loadingState === 'loading' && !qualMatches?.length
- ? 'Waiting for schedule to be posted...'
- : 'Loading Matches...'}
-
- |
-
- >
+
);
}
// Ready and we have matches
- if (loadingState === 'ready' && qualMatches?.length !== 0) {
+ if (state === 'ready' && hasSchedule) {
return (
<>
- {/* Message */}
-
-
- {/* Quals */}
-
- {/* Field Name / Logo */}
-
- {/* Use event logo */}
- {!useShortName && (
-
- )}
+ |
+
+ {now && (
+ <>
+ {/* Current Match */}
+ {now && now.type === 'match' && (
+
+ {now.number}
+
+ )}
- {/* Use event short name */}
- {useShortName && (
-
- {/* */}
- {event.nameShort || event.name}
- {/* */}
-
+ {/* Current Match is Break */}
+ {now && now.type === 'break' && (
+
+ {now.description}
+
+ )}
+ >
)}
- |
-
- {/* Current Match */}
- {currentMatch && (currentMatch as QualMatch)?.number && (
-
- {(currentMatch as QualMatch)?.number}
- |
- )}
-
- {/* Current Match is Break */}
- {currentMatch && (currentMatch as Break)?.message && (
-
- {(currentMatch as Break)?.message}
- |
- )}
-
- {/* Next Match */}
-
- {/* Is a Match */}
- {nextMatch && (nextMatch as QualMatch).number && (
-
+
+ |
+
+ {/* Next Match */}
+
+ {/* Is a Match */}
+
+ {next && next.type === 'match' && (
+
- {(nextMatch as QualMatch)?.number}
+ {next.number}
- {showLine !== null ? (
+ {showLine !== null && (
- ) : <>>}
-
+ )}
+
)}
{/* Is a Break */}
- {nextMatch && (nextMatch as Break).message && (
- {(nextMatch as Break).message}
+ {next && next.type === 'break' && (
+
+ {next.description}
+
)}
- |
+
+
- {/* Queueing Matches */}
-
+ {/* Queueing Matches */}
+ |
+
{/* Multiple Queueing Matches */}
- {queueingMatches.length > 1
- && queueingMatches.map((x) => {
+ {queueing && queueing.length > 1
+ && queueing.map((x) => {
// Is a match, not a break
- if (x && (x as QualMatch).number) {
+ if (x && x.type === 'match') {
const match = x as QualMatch;
return (
@@ -295,45 +136,47 @@ const QualRow = ({
// Is a break
return (
- {(x as Break).message}
+ {x.description}
);
})}
{/* Single Queueing Match */}
- {queueingMatches.length === 1 && queueingMatches[0] && (
+ {queueing?.length === 1 && queueing[0] && (
<>
- {queueingMatches[0]
- && (queueingMatches[0] as QualMatch).number && (
-
+ {queueing[0]
+ && queueing[0].type === 'match' && (
+
- {(queueingMatches[0] as QualMatch)?.number}
+ {queueing[0].number}
{showLine !== null && (
)}
-
+
)}
{/* Is a Break */}
- {nextMatch && (queueingMatches[0] as Break).message && (
- {(queueingMatches[0] as Break).message}
+ {next && queueing[0].type === 'break' && (
+
+ {queueing[0].description}
+
)}
>
)}
- |
-
+
+
>
);
}
return null;
-};
+}
export default QualRow;
diff --git a/src/components/MultiDisplay/EventRow/Shared/PushInDiv.tsx b/src/components/MultiDisplay/EventRow/Shared/PushInDiv.tsx
new file mode 100644
index 0000000..6f3309c
--- /dev/null
+++ b/src/components/MultiDisplay/EventRow/Shared/PushInDiv.tsx
@@ -0,0 +1,38 @@
+import { h } from 'preact';
+import { PropsWithChildren } from 'preact/compat';
+import { motion } from 'motion/react';
+
+export default function PushInDiv(
+ { key, className, children }: PropsWithChildren & { key: string, className?: string },
+) {
+ return (
+
+
+ {children}
+
+
+ );
+}
+
+PushInDiv.defaultProps = {
+ className: undefined,
+};
diff --git a/src/components/MultiDisplay/EventRow/index.tsx b/src/components/MultiDisplay/EventRow/index.tsx
index 00852aa..3c09bf6 100644
--- a/src/components/MultiDisplay/EventRow/index.tsx
+++ b/src/components/MultiDisplay/EventRow/index.tsx
@@ -1,18 +1,45 @@
-import { h, Fragment } from 'preact';
+import { h } from 'preact';
import {
DatabaseReference,
getDatabase,
ref,
onValue,
off,
- // update,
} from 'firebase/database';
import { useEffect, useState, useRef } from 'preact/hooks';
import { Event } from '@shared/DbTypes';
import QualRow from './QualRow';
import PlayoffRow from './PlayoffRow';
+import MessageRow from './MessageRow';
+import styles from './sharedStyles.module.scss';
-const EventRow = ({
+function EventRowDetails({
+ event,
+ token,
+ season,
+ showLine,
+}: {
+ event: Event,
+ token: string,
+ season: string,
+ showLine: 0 | 1 | null,
+}) {
+ if (event.message) {
+ return ();
+ }
+ if (event.state === 'Pending' || event.state === 'AwaitingQualSchedule') {
+ return ();
+ }
+ if (event.state === 'QualsInProgress') {
+ return ();
+ }
+ if (event.state === 'AwaitingAlliances') {
+ return ();
+ }
+ return ();
+}
+
+function EventRow({
token,
season,
showLine,
@@ -20,13 +47,16 @@ const EventRow = ({
token: string;
season: string;
showLine: 0 | 1 | null;
-}) => {
+}) {
// Ref to the event in the database
const dbEventRef = useRef();
// This row's events
const [event, setEvent] = useState();
+ const searchParams = new URLSearchParams(window.location.search);
+ const useShortName = typeof searchParams.get('useShortName') === 'string';
+
useEffect(() => {
if (!token) return () => { };
@@ -44,27 +74,30 @@ const EventRow = ({
if (!event) return null;
return (
- <>
- {/* Beginning of Event */}
- {['Pending', 'AwaitingQualSchedule', 'QualsInProgress'].includes(
- event.state,
- ) ? (
-
- ) : (
-
+
+ {/* Use event logo */}
+ {!useShortName && (
+
)}
- >
+
+ {/* Use event short name */}
+ {useShortName && (
+
+ {event.nameShort || event.name}
+
+ )}
+ |
+
+
+
);
-};
+}
export default EventRow;
diff --git a/src/components/MultiDisplay/EventRow/sharedStyles.module.scss b/src/components/MultiDisplay/EventRow/sharedStyles.module.scss
index d9edffe..132059c 100644
--- a/src/components/MultiDisplay/EventRow/sharedStyles.module.scss
+++ b/src/components/MultiDisplay/EventRow/sharedStyles.module.scss
@@ -3,7 +3,7 @@ $border-color: #fafafa;
$teamlist-size: 5.5vh;
$matchnumber-size: 18vh;
-$cell-vertical-negative: -3vh;
+$cell-vertical-negative: 0; //-3vh;
.textCenter {
text-align: center;
diff --git a/src/components/MultiDisplay/index.tsx b/src/components/MultiDisplay/index.tsx
index d287f50..6dc1443 100644
--- a/src/components/MultiDisplay/index.tsx
+++ b/src/components/MultiDisplay/index.tsx
@@ -4,7 +4,7 @@ import EventRow from './EventRow';
import styles from './styles.module.scss';
import sharedStyles from './EventRow/sharedStyles.module.scss';
-const MultiQueueing = () => {
+function MultiQueueing() {
const searchParams = new URLSearchParams(window.location.search);
const events = searchParams.getAll('e');
const season = searchParams.get('s') ?? new Date().getFullYear().toString();
@@ -64,6 +64,6 @@ const MultiQueueing = () => {
);
-};
+}
export default MultiQueueing;
diff --git a/src/components/PlayoffBracket/TournamentBracket/DoubleEliminationBracket.tsx b/src/components/PlayoffBracket/TournamentBracket/DoubleEliminationBracket.tsx
index c2abcc5..09e5ee5 100644
--- a/src/components/PlayoffBracket/TournamentBracket/DoubleEliminationBracket.tsx
+++ b/src/components/PlayoffBracket/TournamentBracket/DoubleEliminationBracket.tsx
@@ -10,7 +10,7 @@ import MatchWrapper from './MatchWrapper';
import { defaultStyle, getCalculatedStyles } from './settings';
import { MatchComponentProps } from './Match';
-const DoubleEliminationBracket = ({
+function DoubleEliminationBracket({
matchResults,
matchComponent,
alliances,
@@ -18,7 +18,7 @@ const DoubleEliminationBracket = ({
matchResults: Record
| undefined,
matchComponent: FunctionalComponent,
alliances: Alliance[],
-}) => {
+}) {
// TODO: I really do not like this whole calculated styles thing, and I don't
// think we're even using it. Consider removing for a simpler solution.
const calculatedStyles = getCalculatedStyles(defaultStyle);
@@ -157,6 +157,6 @@ const DoubleEliminationBracket = ({
);
-};
+}
export default DoubleEliminationBracket;
diff --git a/src/components/PlayoffBracket/TournamentBracket/Match/index.tsx b/src/components/PlayoffBracket/TournamentBracket/Match/index.tsx
index 1b0f849..2e8e64c 100644
--- a/src/components/PlayoffBracket/TournamentBracket/Match/index.tsx
+++ b/src/components/PlayoffBracket/TournamentBracket/Match/index.tsx
@@ -1,4 +1,4 @@
-import { Fragment, FunctionalComponent, h } from 'preact';
+import { Fragment, h } from 'preact';
import { ParticipantSource } from '@shared/DoubleEliminationBracketMapping';
import { DriverStation, PlayoffMatch } from '@shared/DbTypes';
@@ -14,13 +14,13 @@ export type MatchComponentProps = {
alliances: Alliance[]
};
-const Match: FunctionalComponent