Merge branch 'master' into ticket/TURNIERE-121

This commit is contained in:
betanummeric 2019-04-16 10:34:40 +02:00 committed by GitHub
commit c2dcd5946c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 118 additions and 85 deletions

View File

@ -51,6 +51,8 @@ const actiontypes_tournamentinfo = {
'REQUEST_TOURNAMENT' : 'REQUEST_TOURNAMENT', 'REQUEST_TOURNAMENT' : 'REQUEST_TOURNAMENT',
'REQUEST_TOURNAMENT_SUCCESS' : 'REQUEST_TOURNAMENT_SUCCESS', 'REQUEST_TOURNAMENT_SUCCESS' : 'REQUEST_TOURNAMENT_SUCCESS',
'CREATE_TOURNAMENT' : 'CREATE_TOURNAMENT',
'MODIFY_TOURNAMENT' : 'MODIFY_TOURNAMENT', 'MODIFY_TOURNAMENT' : 'MODIFY_TOURNAMENT',
'MODIFY_TOURNAMENT_SUCCESS' : 'MODIFY_TOURNAMENT_SUCCESS', 'MODIFY_TOURNAMENT_SUCCESS' : 'MODIFY_TOURNAMENT_SUCCESS',
'MODIFY_TOURNAMENT_ERROR' : 'MODIFY_TOURNAMENT_ERROR', 'MODIFY_TOURNAMENT_ERROR' : 'MODIFY_TOURNAMENT_ERROR',
@ -267,6 +269,14 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => {
const reducer_tournamentinfo = (state = defaultstate_tournamentinfo, action) => { const reducer_tournamentinfo = (state = defaultstate_tournamentinfo, action) => {
switch(action.type) { 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: case actiontypes_tournamentinfo.REQUEST_TOURNAMENT:
getRequest(action.state, '/tournaments/' + action.parameters.code).then((resp) => { getRequest(action.state, '/tournaments/' + action.parameters.code).then((resp) => {
__store.dispatch({ __store.dispatch({
@ -309,7 +319,6 @@ const reducer_tournamentinfo = (state = defaultstate_tournamentinfo, action) =>
case actiontypes_tournamentinfo.MODIFY_TOURNAMENT_ERROR: case actiontypes_tournamentinfo.MODIFY_TOURNAMENT_ERROR:
return Object.assign({}, state, {}); return Object.assign({}, state, {});
case actiontypes_tournamentinfo.REHYDRATE: case actiontypes_tournamentinfo.REHYDRATE:
return Object.assign({}, state, {}); return Object.assign({}, state, {});
@ -391,6 +400,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) { export function requestTournament(code, successCallback, errorCallback) {
__store.dispatch({ __store.dispatch({
type: actiontypes_tournamentinfo.REQUEST_TOURNAMENT, type: actiontypes_tournamentinfo.REQUEST_TOURNAMENT,
@ -436,7 +457,3 @@ function rehydrateApplicationState() {
}); });
} }
} }

View File

@ -1,13 +1,18 @@
import App, { Container } from 'next/app'; import App, { Container } from 'next/app';
import React from 'react'; import React from 'react';
import { Provider } from 'react-redux'; import { Provider } from 'react-redux';
import Notifications from 'react-notify-toast'; import Notifications from 'react-notify-toast';
import Favicon from 'react-favicon'; 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 { class TurniereApp extends App {
componentDidMount() {
verifyCredentials();
}
render () { render () {
const {Component, pageProps, reduxStore} = this.props; const {Component, pageProps, reduxStore} = this.props;
return ( return (

View File

@ -1,5 +1,6 @@
import Head from 'next/head'; import Head from 'next/head';
import React from 'react'; import React from 'react';
import { notify } from 'react-notify-toast';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import {
@ -19,17 +20,13 @@ import { TurniereNavigation } from '../js/components/Navigation';
import { Footer } from '../js/components/Footer'; import { Footer } from '../js/components/Footer';
import { UserRestrictor, Option } from '../js/components/UserRestrictor'; import { UserRestrictor, Option } from '../js/components/UserRestrictor';
import { Login } from '../js/components/Login'; import { Login } from '../js/components/Login';
import { verifyCredentials } from '../js/api';
import EditableStringList from '../js/components/EditableStringList'; import EditableStringList from '../js/components/EditableStringList';
import { createTournament } from '../js/api';
import '../static/everypage.css'; import '../static/everypage.css';
class PrivateCreatePage extends React.Component { class PrivateCreatePage extends React.Component {
componentDidMount() {
verifyCredentials();
}
render() { render() {
const { isSignedIn } = this.props; const { isSignedIn } = this.props;
@ -91,9 +88,22 @@ function CreateTournamentCard() {
class CreateTournamentForm extends React.Component { class CreateTournamentForm extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = {fadeIn: false, teams: []}; this.state = {
fadeIn: false,
name: '',
description: '',
public: false,
teams: []
};
this.toggle = this.toggle.bind(this); this.toggle = this.toggle.bind(this);
this.teamListUpdate = this.teamListUpdate.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() { render() {
@ -102,15 +112,15 @@ class CreateTournamentForm extends React.Component {
<Form> <Form>
<FormGroup> <FormGroup>
<Label for="name">Name des Turniers</Label> <Label for="name">Name des Turniers</Label>
<Input type="text" name="name" size="255" required/> <Input type="text" name="name" size="255" required value={this.state.name} onChange={this.handleNameInput}/>
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<Label for="description">Beschreibung (optional)</Label> <Label for="description">Beschreibung (optional)</Label>
<Input type="text" name="description" size="255"/> <Input type="text" name="description" size="255" value={this.state.description} onChange={this.handleDescriptionInput}/>
</FormGroup> </FormGroup>
<FormGroup> <FormGroup>
<CustomInput type="checkbox" id="public" <CustomInput type="checkbox" id="public"
label="Turnier öffentlich anzeigen (schreibgeschützt)"/> label="Turnier öffentlich anzeigen (schreibgeschützt)" checked={this.state.public} onChange={this.handlePublicInput}/>
<CustomInput type="checkbox" id="mix-teams" label="Teams mischen"/> <CustomInput type="checkbox" id="mix-teams" label="Teams mischen"/>
<CustomInput type="checkbox" id="group-phase" label="Gruppenphase" onClick={this.toggle}/> <CustomInput type="checkbox" id="group-phase" label="Gruppenphase" onClick={this.toggle}/>
</FormGroup> </FormGroup>
@ -130,7 +140,7 @@ class CreateTournamentForm extends React.Component {
<h3 className="custom-font mt-4">Teams</h3> <h3 className="custom-font mt-4">Teams</h3>
<EditableStringList addButtonText="hinzufügen" placeholder="Keine Teams hinzugefügt!" entries={[]} <EditableStringList addButtonText="hinzufügen" placeholder="Keine Teams hinzugefügt!" entries={[]}
onChange={this.teamListUpdate} inputPlaceholder="Teamname"/> onChange={this.teamListUpdate} inputPlaceholder="Teamname"/>
<Button color="success" size="lg" className="w-100 shadow-sm mt-4">Turnier erstellen</Button> <Button color="success" size="lg" className="w-100 shadow-sm mt-4" onClick={this.create}>Turnier erstellen</Button>
</div> </div>
); );
} }
@ -144,4 +154,39 @@ class CreateTournamentForm extends React.Component {
fadeIn: !this.state.fadeIn fadeIn: !this.state.fadeIn
}); });
} }
}
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.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;
}
}

View File

@ -5,7 +5,6 @@ import { Col, Container, Row } from 'reactstrap';
import { TurniereNavigation } from '../js/components/Navigation'; import { TurniereNavigation } from '../js/components/Navigation';
import { BigImage } from '../js/components/BigImage'; import { BigImage } from '../js/components/BigImage';
import { Footer } from '../js/components/Footer'; import { Footer } from '../js/components/Footer';
import { verifyCredentials } from '../js/api';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
@ -224,10 +223,6 @@ function TournamentFaq() {
export default class FaqPage extends React.Component { export default class FaqPage extends React.Component {
componentDidMount() {
verifyCredentials();
}
render() { render() {
return ( return (
<div> <div>

View File

@ -5,7 +5,6 @@ import { Container } from 'reactstrap';
import { TurniereNavigation } from '../js/components/Navigation'; import { TurniereNavigation } from '../js/components/Navigation';
import { BigImage } from '../js/components/BigImage'; import { BigImage } from '../js/components/BigImage';
import { Footer } from '../js/components/Footer'; import { Footer } from '../js/components/Footer';
import { verifyCredentials } from '../js/api';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
import '../static/everypage.css'; import '../static/everypage.css';
@ -76,10 +75,6 @@ function ImprintText(){
export default class ImprintPage extends React.Component { export default class ImprintPage extends React.Component {
componentDidMount() {
verifyCredentials();
}
render() { render() {
return ( return (
<div> <div>

View File

@ -11,9 +11,6 @@ import {
import { TurniereNavigation } from '../js/components/Navigation'; import { TurniereNavigation } from '../js/components/Navigation';
import { BigImage } from '../js/components/BigImage'; import { BigImage } from '../js/components/BigImage';
import { Footer } from '../js/components/Footer'; import { Footer } from '../js/components/Footer';
import {
verifyCredentials
} from '../js/api';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
@ -174,10 +171,6 @@ function PromotedLinkCreateTournament() {
class Index extends React.Component { class Index extends React.Component {
componentDidMount() {
verifyCredentials();
}
render () { render () {
return ( return (
<div> <div>

View File

@ -10,17 +10,12 @@ import { TurniereNavigation } from '../js/components/Navigation';
import { Footer } from '../js/components/Footer'; import { Footer } from '../js/components/Footer';
import { import {
getRequest, getRequest,
getState, getState
verifyCredentials
} from '../js/api'; } from '../js/api';
import '../static/everypage.css'; import '../static/everypage.css';
export default class ListPage extends React.Component { export default class ListPage extends React.Component {
componentDidMount() {
verifyCredentials();
}
render() { render() {
return ( return (

View File

@ -4,16 +4,11 @@ import React from 'react';
import { TurniereNavigation } from '../js/components/Navigation'; import { TurniereNavigation } from '../js/components/Navigation';
import { Footer } from '../js/components/Footer'; import { Footer } from '../js/components/Footer';
import { Login } from '../js/components/Login'; import { Login } from '../js/components/Login';
import { verifyCredentials } from '../js/api';
import '../static/everypage.css'; import '../static/everypage.css';
export default class LoginPage extends React.Component { export default class LoginPage extends React.Component {
componentDidMount() {
verifyCredentials();
}
render() { render() {
return ( return (
<div className="main generic-fullpage-bg"> <div className="main generic-fullpage-bg">

View File

@ -5,7 +5,6 @@ import { Container } from 'reactstrap';
import { TurniereNavigation } from '../js/components/Navigation'; import { TurniereNavigation } from '../js/components/Navigation';
import { BigImage } from '../js/components/BigImage'; import { BigImage } from '../js/components/BigImage';
import { Footer } from '../js/components/Footer'; import { Footer } from '../js/components/Footer';
import { verifyCredentials } from '../js/api';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
@ -496,10 +495,6 @@ function PrivacyText(){
export default class PrivacyPage extends React.Component { export default class PrivacyPage extends React.Component {
componentDidMount() {
verifyCredentials();
}
render() { render() {
return ( return (
<div> <div>

View File

@ -15,8 +15,8 @@ import {
import { TurniereNavigation } from '../js/components/Navigation'; import { TurniereNavigation } from '../js/components/Navigation';
import { Footer } from '../js/components/Footer'; import { Footer } from '../js/components/Footer';
import { register } from '../js/api';
import { import {
register,
verifyCredentials, verifyCredentials,
clearErrors clearErrors
} from '../js/api'; } from '../js/api';
@ -25,10 +25,6 @@ import '../static/everypage.css';
export default class RegisterPage extends React.Component { export default class RegisterPage extends React.Component {
componentDidMount() {
verifyCredentials();
}
render() { render() {
return ( return (
<div className="main generic-fullpage-bg"> <div className="main generic-fullpage-bg">

View File

@ -17,10 +17,7 @@ import { UserRestrictor, Option } from '../js/components/UserRestrictor';
import { Footer } from '../js/components/Footer'; import { Footer } from '../js/components/Footer';
import { Login } from '../js/components/Login'; import { Login } from '../js/components/Login';
import { ErrorPageComponent } from '../js/components/ErrorComponents'; import { ErrorPageComponent } from '../js/components/ErrorComponents';
import { import { updateTeamName } from '../js/api';
verifyCredentials,
updateTeamName
} from '../js/api';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
@ -42,7 +39,6 @@ class EditTournamentPage extends React.Component {
} }
componentDidMount() { componentDidMount() {
verifyCredentials();
requestTournament(this.props.query.code, () => { requestTournament(this.props.query.code, () => {
this.setState({ validCode: true }); this.setState({ validCode: true });

View File

@ -1,19 +1,11 @@
import Head from 'next/head'; import Head from 'next/head';
import React from 'react'; import React from 'react';
import {
verifyCredentials
} from '../js/api';
class FullscreenTournamentPage extends React.Component { class FullscreenTournamentPage extends React.Component {
static async getInitialProps({query}) { static async getInitialProps({query}) {
return {query}; return {query};
} }
componentDidMount() {
verifyCredentials();
}
render() { render() {
return ( return (

View File

@ -26,8 +26,7 @@ import { TurniereNavigation } from '../js/components/Navigation';
import { BigImage } from '../js/components/BigImage'; import { BigImage } from '../js/components/BigImage';
import { import {
getRequest, getRequest,
getState, getState
verifyCredentials
} from '../js/api'; } from '../js/api';
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
@ -95,12 +94,14 @@ function getLevelName(levelNumber) {
} }
function Stage(props) { function Stage(props) {
const { isSignedIn, isOwner } = props;
return (<div> return (<div>
<Container className='py-5'> <Container className='py-5'>
<h1 className='custom-font'>{props.level}</h1> <h1 className='custom-font'>{props.level}</h1>
<Row> <Row>
{props.matches.map((match => ( {props.matches.map((match => (
<Col className='minw-25' key={match.id}><Match match={match}/></Col> <Col className='minw-25' key={match.id}><Match match={match} isSignedIn={isSignedIn} isOwner={isOwner}/></Col>
)))} )))}
</Row> </Row>
</Container> </Container>
@ -345,7 +346,7 @@ function convertTournament(apiTournament) {
code: apiTournament.code, code: apiTournament.code,
description: apiTournament.description, description: apiTournament.description,
name: apiTournament.name, name: apiTournament.name,
public: apiTournament.public, isPublic: apiTournament.public,
ownerUsername: apiTournament.owner_username, ownerUsername: apiTournament.owner_username,
groupStage: groupStage, groupStage: groupStage,
playoffStages: playoffStages playoffStages: playoffStages
@ -362,14 +363,29 @@ function convertGroup(apiGroup) {
} }
function convertMatch(apiMatch) { function convertMatch(apiMatch) {
return { var result = {
id: apiMatch.id, id: apiMatch.id,
state: apiMatch.state, 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
}; };
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 { class Main extends React.Component {
@ -387,8 +403,6 @@ class Main extends React.Component {
} }
componentDidMount() { componentDidMount() {
verifyCredentials();
const code = this.props.query.code; const code = this.props.query.code;
getRequest(getState(), '/tournaments/' + code) getRequest(getState(), '/tournaments/' + code)