From e2569b30c8759cb2f4452b158136a7e5d7b2a8ef Mon Sep 17 00:00:00 2001 From: JP1998 Date: Wed, 10 Apr 2019 18:37:32 +0200 Subject: [PATCH 1/7] Add API method for creating a tournament --- js/api.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/js/api.js b/js/api.js index 84ae430..b94dae9 100644 --- a/js/api.js +++ b/js/api.js @@ -49,6 +49,8 @@ const actiontypes_tournamentinfo = { 'REQUEST_TOURNAMENT' : 'REQUEST_TOURNAMENT', 'REQUEST_TOURNAMENT_SUCCESS' : 'REQUEST_TOURNAMENT_SUCCESS', + 'CREATE_TOURNAMENT' : 'CREATE_TOURNAMENT', + 'MODIFY_TOURNAMENT' : 'MODIFY_TOURNAMENT', 'MODIFY_TOURNAMENT_SUCCESS' : 'MODIFY_TOURNAMENT_SUCCESS', 'MODIFY_TOURNAMENT_ERROR' : 'MODIFY_TOURNAMENT_ERROR', @@ -260,6 +262,14 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => { const reducer_tournamentinfo = (state = defaultstate_tournamentinfo, action) => { switch(action.type) { + case actiontypes_tournamentinfo.CREATE_TOURNAMENT: + postRequest(action.state, '/tournaments', action.parameters.tournament).then((resp) => { + storeOptionalToken(resp); + action.parameters.successCallback(); + }).catch(() => { + action.parameters.errorCallback(); + }) + return Object.assign({}, state, {}); case actiontypes_tournamentinfo.REQUEST_TOURNAMENT: getRequest(action.state, '/tournaments/' + action.parameters.code).then((resp) => { __store.dispatch({ @@ -302,7 +312,6 @@ const reducer_tournamentinfo = (state = defaultstate_tournamentinfo, action) => case actiontypes_tournamentinfo.MODIFY_TOURNAMENT_ERROR: return Object.assign({}, state, {}); - case actiontypes_tournamentinfo.REHYDRATE: return Object.assign({}, state, {}); @@ -378,6 +387,18 @@ export function logout() { }); } +export function createTournament(data, successCallback, errorCallback) { + __store.dispatch({ + type: actiontypes_tournamentinfo.CREATE_TOURNAMENT, + parameters: { + tournament: data, + successCallback: successCallback, + errorCallback: errorCallback + }, + state: __store.getState() + }); +} + export function requestTournament(code, successCallback, errorCallback) { __store.dispatch({ type: actiontypes_tournamentinfo.REQUEST_TOURNAMENT, From 0a1678ed51159f1fa76560b93a7cc1184161bc30 Mon Sep 17 00:00:00 2001 From: JP1998 Date: Wed, 10 Apr 2019 20:10:48 +0200 Subject: [PATCH 2/7] Make the create-page actually send the data to the api --- js/api.js | 4 ---- pages/create.js | 56 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/js/api.js b/js/api.js index b94dae9..0ec46b8 100644 --- a/js/api.js +++ b/js/api.js @@ -444,7 +444,3 @@ function rehydrateApplicationState() { }); } } - - - - diff --git a/pages/create.js b/pages/create.js index b8ad288..40d4ca1 100644 --- a/pages/create.js +++ b/pages/create.js @@ -1,5 +1,6 @@ import Head from 'next/head'; import React from 'react'; +import { notify } from 'react-notify-toast'; import { connect } from 'react-redux'; import { @@ -19,8 +20,11 @@ import { TurniereNavigation } from '../js/components/Navigation'; import { Footer } from '../js/components/Footer'; import { UserRestrictor, Option } from '../js/components/UserRestrictor'; import { Login } from '../js/components/Login'; -import { verifyCredentials } from '../js/api'; import EditableStringList from '../js/components/EditableStringList'; +import { + verifyCredentials, + createTournament +} from '../js/api'; import '../static/everypage.css'; @@ -91,9 +95,22 @@ function CreateTournamentCard() { class CreateTournamentForm extends React.Component { constructor(props) { super(props); - this.state = {fadeIn: false, teams: []}; + this.state = { + fadeIn: false, + + name: '', + description: '', + public: false, + teams: [] + }; this.toggle = this.toggle.bind(this); this.teamListUpdate = this.teamListUpdate.bind(this); + this.create = this.create.bind(this); + this.handleNameInput = this.handleNameInput.bind(this); + this.handleDescriptionInput = this.handleDescriptionInput.bind(this); + this.handlePublicInput = this.handlePublicInput.bind(this); + + this.create = this.create.bind(this); } render() { @@ -102,15 +119,15 @@ class CreateTournamentForm extends React.Component {
- + - + + label="Turnier öffentlich anzeigen (schreibgeschützt)" checked={this.state.public} onChange={this.handlePublicInput}/> @@ -130,7 +147,7 @@ class CreateTournamentForm extends React.Component {

Teams

- + ); } @@ -144,4 +161,29 @@ class CreateTournamentForm extends React.Component { fadeIn: !this.state.fadeIn }); } -} \ No newline at end of file + + handleNameInput(input) { + this.setState({ name: input.target.value }); + } + + handleDescriptionInput(input) { + this.setState({ description: input.target.value }); + } + + handlePublicInput(input) { + this.setState({ public: input.target.checked }); + } + + create() { + createTournament({ + 'name': this.state.name, + 'description': this.state.description, + 'public': this.state.public, + 'teams': this.state.teams + }, () => { + notify.show('Das Turnier wurde erfolgreich erstellt.', 'success', 5000); + }, () => { + notify.show('Das Turnier konnte nicht erstellt werden.', 'warning', 5000); + }); + } +} From 4964040ad8fc0171b17bbd3e74cd8a417716af32 Mon Sep 17 00:00:00 2001 From: JP1998 Date: Wed, 10 Apr 2019 20:11:22 +0200 Subject: [PATCH 3/7] Fix bug showing public tournaments as private --- js/api.js | 2 +- pages/tournament.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/js/api.js b/js/api.js index 0ec46b8..1484cc9 100644 --- a/js/api.js +++ b/js/api.js @@ -268,7 +268,7 @@ const reducer_tournamentinfo = (state = defaultstate_tournamentinfo, action) => action.parameters.successCallback(); }).catch(() => { action.parameters.errorCallback(); - }) + }); return Object.assign({}, state, {}); case actiontypes_tournamentinfo.REQUEST_TOURNAMENT: getRequest(action.state, '/tournaments/' + action.parameters.code).then((resp) => { diff --git a/pages/tournament.js b/pages/tournament.js index 343192f..d37c5f8 100644 --- a/pages/tournament.js +++ b/pages/tournament.js @@ -345,7 +345,7 @@ function convertTournament(apiTournament) { code: apiTournament.code, description: apiTournament.description, name: apiTournament.name, - public: apiTournament.public, + isPublic: apiTournament.public, ownerUsername: apiTournament.owner_username, groupStage: groupStage, playoffStages: playoffStages From 9525aa68d50a08dbb2ce11d5923d49ac03ff2077 Mon Sep 17 00:00:00 2001 From: JP1998 Date: Thu, 11 Apr 2019 15:35:37 +0200 Subject: [PATCH 4/7] Correctly format the sent data --- pages/create.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pages/create.js b/pages/create.js index 40d4ca1..0beb477 100644 --- a/pages/create.js +++ b/pages/create.js @@ -179,11 +179,21 @@ class CreateTournamentForm extends React.Component { 'name': this.state.name, 'description': this.state.description, 'public': this.state.public, - 'teams': this.state.teams + 'teams': this.createTeamArray(this.state.teams) }, () => { notify.show('Das Turnier wurde erfolgreich erstellt.', 'success', 5000); }, () => { notify.show('Das Turnier konnte nicht erstellt werden.', 'warning', 5000); }); } + + createTeamArray(teamnames) { + var result = []; + + for(var i = 0; i < teamnames.length; i++) { + result[i] = { 'name': teamnames[i] }; + } + + return result; + } } From 2e93076d798778b55bb4d3264f8a3f7a712efe4c Mon Sep 17 00:00:00 2001 From: JP1998 Date: Thu, 11 Apr 2019 15:49:45 +0200 Subject: [PATCH 5/7] Fix a bug where you are logged out after reloading the /create page --- pages/_app.js | 17 +++++++++++------ pages/create.js | 9 +-------- pages/faq.js | 5 ----- pages/imprint.js | 5 ----- pages/index.js | 7 ------- pages/list.js | 7 +------ pages/login.js | 5 ----- pages/privacy.js | 5 ----- pages/register.js | 5 ----- pages/tournament-edit.js | 6 +----- pages/tournament-fullscreen.js | 8 -------- pages/tournament.js | 5 +---- 12 files changed, 15 insertions(+), 69 deletions(-) diff --git a/pages/_app.js b/pages/_app.js index 1b508c4..e0e8f7c 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -1,13 +1,18 @@ -import App, { Container } from 'next/app'; -import React from 'react'; -import { Provider } from 'react-redux'; -import Notifications from 'react-notify-toast'; -import Favicon from 'react-favicon'; +import App, { Container } from 'next/app'; +import React from 'react'; +import { Provider } from 'react-redux'; +import Notifications from 'react-notify-toast'; +import Favicon from 'react-favicon'; -import withReduxStore from '../js/redux/reduxStoreBinder'; +import withReduxStore from '../js/redux/reduxStoreBinder'; +import { verifyCredentials } from '../js/api.js'; class TurniereApp extends App { + componentDidMount() { + verifyCredentials(); + } + render () { const {Component, pageProps, reduxStore} = this.props; return ( diff --git a/pages/create.js b/pages/create.js index 0beb477..2565c7c 100644 --- a/pages/create.js +++ b/pages/create.js @@ -21,19 +21,12 @@ import { Footer } from '../js/components/Footer'; import { UserRestrictor, Option } from '../js/components/UserRestrictor'; import { Login } from '../js/components/Login'; import EditableStringList from '../js/components/EditableStringList'; -import { - verifyCredentials, - createTournament -} from '../js/api'; +import { createTournament } from '../js/api'; import '../static/everypage.css'; class PrivateCreatePage extends React.Component { - componentDidMount() { - verifyCredentials(); - } - render() { const { isSignedIn } = this.props; diff --git a/pages/faq.js b/pages/faq.js index c861b13..a635842 100644 --- a/pages/faq.js +++ b/pages/faq.js @@ -5,7 +5,6 @@ import { Col, Container, Row } from 'reactstrap'; import { TurniereNavigation } from '../js/components/Navigation'; import { BigImage } from '../js/components/BigImage'; import { Footer } from '../js/components/Footer'; -import { verifyCredentials } from '../js/api'; import 'bootstrap/dist/css/bootstrap.min.css'; @@ -224,10 +223,6 @@ function TournamentFaq() { export default class FaqPage extends React.Component { - componentDidMount() { - verifyCredentials(); - } - render() { return (
diff --git a/pages/imprint.js b/pages/imprint.js index 40d58a9..4ade366 100644 --- a/pages/imprint.js +++ b/pages/imprint.js @@ -5,7 +5,6 @@ import { Container } from 'reactstrap'; import { TurniereNavigation } from '../js/components/Navigation'; import { BigImage } from '../js/components/BigImage'; import { Footer } from '../js/components/Footer'; -import { verifyCredentials } from '../js/api'; import 'bootstrap/dist/css/bootstrap.min.css'; import '../static/everypage.css'; @@ -76,10 +75,6 @@ function ImprintText(){ export default class ImprintPage extends React.Component { - componentDidMount() { - verifyCredentials(); - } - render() { return (
diff --git a/pages/index.js b/pages/index.js index 77c93eb..f81153d 100644 --- a/pages/index.js +++ b/pages/index.js @@ -11,9 +11,6 @@ import { import { TurniereNavigation } from '../js/components/Navigation'; import { BigImage } from '../js/components/BigImage'; import { Footer } from '../js/components/Footer'; -import { - verifyCredentials -} from '../js/api'; import 'bootstrap/dist/css/bootstrap.min.css'; @@ -174,10 +171,6 @@ function PromotedLinkCreateTournament() { class Index extends React.Component { - componentDidMount() { - verifyCredentials(); - } - render () { return (
diff --git a/pages/list.js b/pages/list.js index 7e9f018..768b105 100644 --- a/pages/list.js +++ b/pages/list.js @@ -10,17 +10,12 @@ import { TurniereNavigation } from '../js/components/Navigation'; import { Footer } from '../js/components/Footer'; import { getRequest, - getState, - verifyCredentials + getState } from '../js/api'; import '../static/everypage.css'; export default class ListPage extends React.Component { - - componentDidMount() { - verifyCredentials(); - } render() { return ( diff --git a/pages/login.js b/pages/login.js index 4bed1e0..73e7279 100644 --- a/pages/login.js +++ b/pages/login.js @@ -4,16 +4,11 @@ import React from 'react'; import { TurniereNavigation } from '../js/components/Navigation'; import { Footer } from '../js/components/Footer'; import { Login } from '../js/components/Login'; -import { verifyCredentials } from '../js/api'; import '../static/everypage.css'; export default class LoginPage extends React.Component { - componentDidMount() { - verifyCredentials(); - } - render() { return (
diff --git a/pages/privacy.js b/pages/privacy.js index 42dca7f..219ef4c 100644 --- a/pages/privacy.js +++ b/pages/privacy.js @@ -5,7 +5,6 @@ import { Container } from 'reactstrap'; import { TurniereNavigation } from '../js/components/Navigation'; import { BigImage } from '../js/components/BigImage'; import { Footer } from '../js/components/Footer'; -import { verifyCredentials } from '../js/api'; import 'bootstrap/dist/css/bootstrap.min.css'; @@ -496,10 +495,6 @@ function PrivacyText(){ export default class PrivacyPage extends React.Component { - componentDidMount() { - verifyCredentials(); - } - render() { return (
diff --git a/pages/register.js b/pages/register.js index 91ebc81..75e1c2a 100644 --- a/pages/register.js +++ b/pages/register.js @@ -16,16 +16,11 @@ import { import { TurniereNavigation } from '../js/components/Navigation'; import { Footer } from '../js/components/Footer'; import { register } from '../js/api'; -import { verifyCredentials } from '../js/api'; import '../static/everypage.css'; export default class RegisterPage extends React.Component { - componentDidMount() { - verifyCredentials(); - } - render() { return (
diff --git a/pages/tournament-edit.js b/pages/tournament-edit.js index 8b0dfae..e0b0fcd 100644 --- a/pages/tournament-edit.js +++ b/pages/tournament-edit.js @@ -17,10 +17,7 @@ import { UserRestrictor, Option } from '../js/components/UserRestrictor'; import { Footer } from '../js/components/Footer'; import { Login } from '../js/components/Login'; import { ErrorPageComponent } from '../js/components/ErrorComponents'; -import { - verifyCredentials, - updateTeamName -} from '../js/api'; +import { updateTeamName } from '../js/api'; import 'bootstrap/dist/css/bootstrap.min.css'; @@ -42,7 +39,6 @@ class EditTournamentPage extends React.Component { } componentDidMount() { - verifyCredentials(); requestTournament(this.props.query.code, () => { this.setState({ validCode: true }); diff --git a/pages/tournament-fullscreen.js b/pages/tournament-fullscreen.js index a7b79d3..037e696 100644 --- a/pages/tournament-fullscreen.js +++ b/pages/tournament-fullscreen.js @@ -1,19 +1,11 @@ import Head from 'next/head'; import React from 'react'; -import { - verifyCredentials -} from '../js/api'; - class FullscreenTournamentPage extends React.Component { static async getInitialProps({query}) { return {query}; } - - componentDidMount() { - verifyCredentials(); - } render() { return ( diff --git a/pages/tournament.js b/pages/tournament.js index d37c5f8..547fcf8 100644 --- a/pages/tournament.js +++ b/pages/tournament.js @@ -26,8 +26,7 @@ import { TurniereNavigation } from '../js/components/Navigation'; import { BigImage } from '../js/components/BigImage'; import { getRequest, - getState, - verifyCredentials + getState } from '../js/api'; import 'bootstrap/dist/css/bootstrap.min.css'; @@ -387,8 +386,6 @@ class Main extends React.Component { } componentDidMount() { - verifyCredentials(); - const code = this.props.query.code; getRequest(getState(), '/tournaments/' + code) From 980d2eac3de373978c8b0af54d05c8060d8f44cb Mon Sep 17 00:00:00 2001 From: JP1998 Date: Thu, 11 Apr 2019 16:19:17 +0200 Subject: [PATCH 6/7] Fix a bug, which causes the tournament site to crash Whenever a match in the play off stage of a tournament has not had a team determined yet the tournament site would crash on it since it expected two team objects attached. --- pages/tournament.js | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/pages/tournament.js b/pages/tournament.js index 547fcf8..1f8797e 100644 --- a/pages/tournament.js +++ b/pages/tournament.js @@ -361,14 +361,29 @@ function convertGroup(apiGroup) { } function convertMatch(apiMatch) { - return { + var result = { id: apiMatch.id, - state: apiMatch.state, - team1: apiMatch.match_scores[0].team.name, - team2: apiMatch.match_scores[1].team.name, - scoreTeam1: apiMatch.match_scores[0].points, - scoreTeam2: apiMatch.match_scores[1].points + state: apiMatch.state }; + + if(apiMatch.match_scores.length == 2) { + result.team1 = apiMatch.match_scores[0].team.name; + result.scoreTeam1 = apiMatch.match_scores[0].points; + result.team2 = apiMatch.match_scores[1].team.name; + result.scoreTeam2 = apiMatch.match_scores[1].points; + } else if(apiMatch.match_scores.length == 1) { + result.team1 = apiMatch.match_scores[0].team.name; + result.scoreTeam1 = apiMatch.match_scores[0].points; + result.team2 = 'TBD'; + result.scoreTeam2 = 0; + } else { + result.team1 = 'TBD'; + result.scoreTeam1 = 0; + result.team2 = 'TBD'; + result.scoreTeam2 = 0; + } + + return result; } class Main extends React.Component { From 148686b7c15f9f1b9183ecd4b855a712ea4b2b97 Mon Sep 17 00:00:00 2001 From: JP1998 Date: Thu, 11 Apr 2019 16:25:24 +0200 Subject: [PATCH 7/7] Fix bug preventing the owner of a tournament from starting / editing matches --- pages/tournament.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pages/tournament.js b/pages/tournament.js index 1f8797e..da0c919 100644 --- a/pages/tournament.js +++ b/pages/tournament.js @@ -94,12 +94,14 @@ function getLevelName(levelNumber) { } function Stage(props) { + const { isSignedIn, isOwner } = props; + return (

{props.level}

{props.matches.map((match => ( - + )))}