Move timer into separate class
This commit is contained in:
parent
bcba2a0727
commit
42b2003336
|
|
@ -0,0 +1,33 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export function Timer({timerEnd}) {
|
||||||
|
const [timeLeft, setTimeLeft] = React.useState(null);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (timerEnd) {
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
const now = new Date();
|
||||||
|
const timeLeft = timerEnd - now;
|
||||||
|
setTimeLeft(timeLeft > 0 ? timeLeft : 0);
|
||||||
|
}, 1000);
|
||||||
|
return () => clearInterval(intervalId);
|
||||||
|
}
|
||||||
|
}, [timerEnd]);
|
||||||
|
|
||||||
|
const formatTimeLeft = timeLeft => {
|
||||||
|
if (timeLeft === null) return '';
|
||||||
|
const hours = Math.floor(timeLeft / (1000 * 60 * 60));
|
||||||
|
const minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60));
|
||||||
|
const seconds = Math.floor((timeLeft % (1000 * 60)) / 1000);
|
||||||
|
const formattedSeconds = seconds < 10 ? '0' + seconds : seconds;
|
||||||
|
|
||||||
|
let formattedTimeLeft = '';
|
||||||
|
if (hours > 0) {
|
||||||
|
formattedTimeLeft += hours + 'h ';
|
||||||
|
}
|
||||||
|
formattedTimeLeft += minutes + ':' + formattedSeconds;
|
||||||
|
return formattedTimeLeft;
|
||||||
|
};
|
||||||
|
|
||||||
|
return <span>{formatTimeLeft(timeLeft)}</span>;
|
||||||
|
}
|
||||||
|
|
@ -8,11 +8,13 @@ import {
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
import {Match} from '../js/components/Match';
|
import {Match} from '../js/components/Match';
|
||||||
import {sortMatchesByPositionAscending} from '../js/utils/sorting';
|
import {sortMatchesByPositionAscending} from '../js/utils/sorting';
|
||||||
|
import {Timer} from '../js/components/Timer';
|
||||||
|
|
||||||
|
|
||||||
function FullscreenPage(props) {
|
function FullscreenPage(props) {
|
||||||
return (<div>
|
return (<div>
|
||||||
<FullscreenPageHeader title={props.tournamentMeta.name} code={props.tournamentMeta.code} filter={props.filter} timerEnd={props.timerEnd}/>
|
<FullscreenPageHeader title={props.tournamentMeta.name} code={props.tournamentMeta.code} filter={props.filter}
|
||||||
|
timerEnd={props.timerEnd}/>
|
||||||
<Matches matches={props.matches}/>
|
<Matches matches={props.matches}/>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
@ -20,20 +22,20 @@ function FullscreenPage(props) {
|
||||||
function Matches(props) {
|
function Matches(props) {
|
||||||
let matches;
|
let matches;
|
||||||
if (props.matches == null) {
|
if (props.matches == null) {
|
||||||
matches = (<div className='text-center text-secondary'>
|
matches = (<div className="text-center text-secondary">
|
||||||
<Spinner animation='border' role='status' size='sm'/>
|
<Spinner animation="border" role="status" size="sm"/>
|
||||||
<span className='ml-3'>lade Matches</span>
|
<span className="ml-3">lade Matches</span>
|
||||||
</div>);
|
</div>);
|
||||||
} else if (props.matches.length === 0) {
|
} else if (props.matches.length === 0) {
|
||||||
matches = (<div className='text-center text-secondary font-italic'>keine Matches</div>);
|
matches = (<div className="text-center text-secondary font-italic">keine Matches</div>);
|
||||||
} else {
|
} else {
|
||||||
matches = (<Row>
|
matches = (<Row>
|
||||||
{props.matches.sort(sortMatchesByPositionAscending()).map(
|
{props.matches.sort(sortMatchesByPositionAscending()).map(
|
||||||
match => <Col md='auto'><Match key={match.id} match={match}/></Col>
|
match => <Col md="auto"><Match key={match.id} match={match}/></Col>
|
||||||
)}
|
)}
|
||||||
</Row>);
|
</Row>);
|
||||||
}
|
}
|
||||||
return (<div className='mx-4 h5'>
|
return (<div className="mx-4 h5">
|
||||||
{matches}
|
{matches}
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
@ -41,7 +43,7 @@ function Matches(props) {
|
||||||
function FilterDropdown(props) {
|
function FilterDropdown(props) {
|
||||||
return (<UncontrolledDropdown>
|
return (<UncontrolledDropdown>
|
||||||
<i>Match-Filter: </i>
|
<i>Match-Filter: </i>
|
||||||
<DropdownToggle color='light' caret>
|
<DropdownToggle color="light" caret>
|
||||||
{props.selected.label}
|
{props.selected.label}
|
||||||
</DropdownToggle>
|
</DropdownToggle>
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
|
|
@ -55,39 +57,14 @@ function FilterDropdown(props) {
|
||||||
|
|
||||||
|
|
||||||
function FullscreenPageHeader(props) {
|
function FullscreenPageHeader(props) {
|
||||||
const [timeLeft, setTimeLeft] = React.useState(null);
|
return (
|
||||||
|
<Navbar color="light" className="mb-4 border-bottom py-0">
|
||||||
React.useEffect(() => {
|
|
||||||
if (props.timerEnd) {
|
|
||||||
const intervalId = setInterval(() => {
|
|
||||||
const now = new Date();
|
|
||||||
const timeLeft = props.timerEnd - now;
|
|
||||||
setTimeLeft(timeLeft > 0 ? timeLeft : 0);
|
|
||||||
}, 1000);
|
|
||||||
return () => clearInterval(intervalId);
|
|
||||||
}
|
|
||||||
}, [props.timerEnd]);
|
|
||||||
|
|
||||||
const formatTimeLeft = timeLeft => {
|
|
||||||
if (timeLeft === null) return '';
|
|
||||||
const hours = Math.floor(timeLeft / (1000 * 60 * 60));
|
|
||||||
const minutes = Math.floor((timeLeft % (1000 * 60 * 60)) / (1000 * 60));
|
|
||||||
const seconds = Math.floor((timeLeft % (1000 * 60)) / 1000);
|
|
||||||
const formattedSeconds = seconds < 10 ? '0' + seconds : seconds;
|
|
||||||
|
|
||||||
let formattedTimeLeft = '';
|
|
||||||
if (hours > 0) {
|
|
||||||
formattedTimeLeft += hours + 'h ';
|
|
||||||
}
|
|
||||||
formattedTimeLeft += minutes + ':' + formattedSeconds;
|
|
||||||
return formattedTimeLeft;
|
|
||||||
};
|
|
||||||
|
|
||||||
return (<Navbar color='light' className='mb-4 border-bottom py-0'>
|
|
||||||
<FilterDropdown {...props.filter} />
|
<FilterDropdown {...props.filter} />
|
||||||
<NavbarBrand>{props.title}</NavbarBrand>
|
<NavbarBrand>{props.title}</NavbarBrand>
|
||||||
{props.timerEnd && <div className='ml-auto'>Spielzeit: <NavbarBrand>{formatTimeLeft(timeLeft)}</NavbarBrand></div>}
|
{props.timerEnd &&
|
||||||
</Navbar>);
|
<div className="ml-auto">Spielzeit: <NavbarBrand><Timer timerEnd={props.timerEnd}/></NavbarBrand></div>}
|
||||||
|
</Navbar>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const matchFilters = {
|
const matchFilters = {
|
||||||
|
|
@ -195,9 +172,9 @@ class Main extends React.Component {
|
||||||
<Head>
|
<Head>
|
||||||
<title>Vollbild-Ansicht: turnie.re</title>
|
<title>Vollbild-Ansicht: turnie.re</title>
|
||||||
</Head>
|
</Head>
|
||||||
<Container className='p-5 text-center text-secondary'>
|
<Container className="p-5 text-center text-secondary">
|
||||||
<Spinner size='sm'/>
|
<Spinner size="sm"/>
|
||||||
<span className='ml-3'>lade Vollbild-Ansicht</span>
|
<span className="ml-3">lade Vollbild-Ansicht</span>
|
||||||
</Container>
|
</Container>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue