diff --git a/js/redux/tournamentApi.js b/js/redux/tournamentApi.js index 84e1085..ddb883a 100644 --- a/js/redux/tournamentApi.js +++ b/js/redux/tournamentApi.js @@ -25,6 +25,27 @@ export function getStage(stageId, successCallback, errorCallback) { .catch(errorCallback); } +export function getTournamentMeta(tournamentId, successCallback, errorCallback) { + getRequest(getState(), '/tournaments/' + tournamentId + '?simple=true') + .then(response => { + successCallback(response.status, response.data); + }) + .catch(errorCallback); +} + +export function getTournamentMatches(tournamentId, successCallback, errorCallback, matchState=null) { + let matchFilter = ''; + if (matchState) { + matchFilter = '?state=' + matchState; + } + getRequest(getState(), '/tournaments/' + tournamentId + '/matches' + matchFilter) + .then(response => { + successCallback(response.status, response.data.map(match => convertMatch(match))); + }) + .catch(errorCallback); +} + + function convertTournament(apiTournament) { let groupStage = null; const playoffStages = []; diff --git a/pages/tournament-fullscreen.js b/pages/tournament-fullscreen.js index 3df8089..9b23f9c 100644 --- a/pages/tournament-fullscreen.js +++ b/pages/tournament-fullscreen.js @@ -1,20 +1,182 @@ import Head from 'next/head'; import React from 'react'; +import {ErrorPageComponent} from '../js/components/ErrorComponents'; +import 'bootstrap/dist/css/bootstrap.min.css'; +import '../static/css/everypage.css'; +import '../static/css/tournament-fullscreen.css'; +import {getTournamentMatches, getTournamentMeta} from '../js/redux/tournamentApi'; +import { + Col, Container, DropdownItem, DropdownMenu, DropdownToggle, Navbar, NavbarBrand, NavItem, Row, UncontrolledDropdown +} from 'reactstrap'; +import {Match} from '../js/components/Match'; +import {Spinner} from 'react-bootstrap'; -class FullscreenTournamentPage extends React.Component { + +function FullscreenPage(props) { + return (
+ + +
); +} + +function Matches(props) { + let matches; + if (props.matches == null) { + matches = (
+ + lade Matches +
); + } else if (props.matches.length === 0) { + matches = (
keine Matches
); + } else { + matches = ( + {props.matches.map(match => )} + ); + } + return (
+ {matches} +
); +} + +function FilterDropdown(props) { + return ( + Match-Filter: + + {props.selected.label} + + + {Object.keys(matchFilters).map(matchFilter => props.select(matchFilters[matchFilter])}> + {matchFilters[matchFilter].label} + )} + + ); +} + + +function FullscreenPageHeader(props) { + return ( + + {props.title} + + Turnier-Code: {props.code} + + ); +} + +const matchFilters = { + 'all': {backend: null, label: 'alle'}, + 'in_progress': {backend: 'in_progress', label: 'laufend'}, + 'upcoming': {backend: 'upcoming', label: 'kommend'}, + 'not_started': {backend: 'not_started', label: 'bereit zum Starten'}, + 'finished': {backend: 'finished', label: 'beendet'}, + 'single_team': {backend: 'single_team', label: 'ohne Gegner'}, + 'not_ready': {backend: 'not_ready', label: 'noch nicht festgelegt'} +}; + +class Main extends React.Component { static async getInitialProps({query}) { return {query}; } + constructor(props) { + super(props); + + this.state = { + tournamentMeta: null, matches: [], matchFilter: matchFilters.all, loadedMeta: false, loadedMatches: false + }; + this.onTournamentRequestSuccess = this.onTournamentRequestSuccess.bind(this); + this.onTournamentRequestError = this.onTournamentRequestError.bind(this); + this.onTournamentMatchesRequestSuccess = this.onTournamentMatchesRequestSuccess.bind(this); + this.onTournamentMatchesRequestError = this.onTournamentMatchesRequestError.bind(this); + this.updateMatches = this.updateMatches.bind(this); + this.selectFilter = this.selectFilter.bind(this); + } + + selectFilter(filter) { + this.setState({matchFilter: filter, loadedMatches: false}); + this.updateMatches(); + } + + componentDidMount() { + const tournamentId = this.props.query.code; + getTournamentMeta(tournamentId, this.onTournamentRequestSuccess, this.onTournamentRequestError); + this.updateMatches(); + const intervalId = setInterval(this.updateMatches, 3000); + this.setState({intervalId: intervalId}); + } + + componentWillUnmount() { + clearInterval(this.state.intervalId); + } + + updateMatches() { + const tournamentId = this.props.query.code; + getTournamentMatches(tournamentId, this.onTournamentMatchesRequestSuccess, this.onTournamentMatchesRequestError, + this.state.matchFilter.backend); + } + + + onTournamentRequestSuccess(requestStatus, tournament) { + this.setState({metaStatus: requestStatus, tournamentMeta: tournament, loadedMeta: true}); + } + + onTournamentRequestError(error) { + if (error.response) { + this.setState({metaStatus: error.response.status, loadedMeta: true}); + } else { + this.setState({metaStatus: -1, loadedMeta: true}); + } + } + + onTournamentMatchesRequestSuccess(requestStatus, matches) { + this.setState({matchesStatus: requestStatus, matches: matches, loadedMatches: true}); + } + + onTournamentMatchesRequestError(error) { + if (error.response) { + this.setState({matchesStatus: error.response.status, loadedMatches: true}); + } else { + this.setState({matchesStatus: -1, loadedMatches: true}); + } + } + + render() { - return (
- - Turnie.re - Turnieranzeige (Vollbild) - -

Turnieranzeige (Vollbild)

-

Code: {this.props.query.code}

-
); + const {metaStatus, matchesStatus, tournamentMeta, matches} = this.state; + const filter = { + selected: this.state.matchFilter, select: this.selectFilter + }; + if (!this.state.loadedMeta) { + return (
+ + Vollbild-Ansicht: turnie.re + + + + lade Vollbild-Ansicht + +
); + } + if (!this.state.loadedMatches) { + return (
+ + {tournamentMeta.name}: turnie.re + + +
); + } + if (metaStatus === 200 && matchesStatus === 200) { + return (
+ + {tournamentMeta.name}: turnie.re + + +
); + } else { + return ; + } } } -export default FullscreenTournamentPage; +export default Main; diff --git a/pages/tournament-statistics.js b/pages/tournament-statistics.js index afbfbc2..dcea4b6 100644 --- a/pages/tournament-statistics.js +++ b/pages/tournament-statistics.js @@ -45,6 +45,9 @@ class StatisticsTournamentPage extends React.Component { zurück zum Turnier + + Turnier-Vollbild-Ansicht +
diff --git a/pages/tournament.js b/pages/tournament.js index 7fa6b53..80aed4a 100644 --- a/pages/tournament.js +++ b/pages/tournament.js @@ -45,6 +45,7 @@ function StatusBar(props) { {props.tournament.name} + ); } @@ -55,6 +56,12 @@ function StatisticsButton(props) { ); } +function FullscreenButton(props) { + return ( + Vollbild-Ansicht + ); +} + function mapStateToTournamentPageProperties(state) { const {isSignedIn, username} = state.userinfo; diff --git a/static/css/tournament-fullscreen.css b/static/css/tournament-fullscreen.css new file mode 100644 index 0000000..c606da3 --- /dev/null +++ b/static/css/tournament-fullscreen.css @@ -0,0 +1,3 @@ +nav li { + list-style-type: none; +}