Merge pull request #5 from turniere/ticket/TURNIERE-113
Make "Edit Tournament"-Page with working editing of team names
This commit is contained in:
commit
e7004de3c3
149
js/api.js
149
js/api.js
|
|
@ -40,6 +40,28 @@ const defaultstate_userinfo = {
|
||||||
uid : null
|
uid : null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const actiontypes_tournamentinfo = {
|
||||||
|
'REQUEST_TOURNAMENT' : 'REQUEST_TOURNAMENT',
|
||||||
|
'REQUEST_TOURNAMENT_SUCCESS' : 'REQUEST_TOURNAMENT_SUCCESS',
|
||||||
|
|
||||||
|
'MODIFY_TOURNAMENT' : 'MODIFY_TOURNAMENT',
|
||||||
|
'MODIFY_TOURNAMENT_SUCCESS' : 'MODIFY_TOURNAMENT_SUCCESS',
|
||||||
|
'MODIFY_TOURNAMENT_ERROR' : 'MODIFY_TOURNAMENT_ERROR',
|
||||||
|
|
||||||
|
'REHYDRATE' : 'TOURNAMENTINFO_REHYDRATE',
|
||||||
|
'CLEAR' : 'TOURNAMENTINFO_CLEAR',
|
||||||
|
};
|
||||||
|
|
||||||
|
const defaultstate_tournamentinfo = {
|
||||||
|
code : '',
|
||||||
|
description : '',
|
||||||
|
id : -1,
|
||||||
|
name : '',
|
||||||
|
isPublic : '',
|
||||||
|
stages: [],
|
||||||
|
teams : []
|
||||||
|
};
|
||||||
|
|
||||||
export function postRequest(state, url, data) {
|
export function postRequest(state, url, data) {
|
||||||
return axios.post(api_url + url, data, {
|
return axios.post(api_url + url, data, {
|
||||||
headers : generateHeaders(state)
|
headers : generateHeaders(state)
|
||||||
|
|
@ -58,12 +80,18 @@ export function deleteRequest(state, url) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function patchRequest(state, url, data) {
|
||||||
|
return axios.patch(api_url + url, data, {
|
||||||
|
headers : generateHeaders(state)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function generateHeaders(state) {
|
function generateHeaders(state) {
|
||||||
if(state.isSignedIn) {
|
if(state.userinfo.isSignedIn) {
|
||||||
return {
|
return {
|
||||||
'access-token' : state.accesstoken,
|
'access-token' : state.userinfo.accesstoken,
|
||||||
'client' : state.client,
|
'client' : state.userinfo.client,
|
||||||
'uid' : state.uid
|
'uid' : state.userinfo.uid
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -102,7 +130,7 @@ function checkForAuthenticationHeaders(response) {
|
||||||
const reducer_userinfo = (state = defaultstate_userinfo, action) => {
|
const reducer_userinfo = (state = defaultstate_userinfo, action) => {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case actiontypes_userinfo.REGISTER:
|
case actiontypes_userinfo.REGISTER:
|
||||||
postRequest(state, '/users', {
|
postRequest(action.state, '/users', {
|
||||||
'username' : action.parameters.username,
|
'username' : action.parameters.username,
|
||||||
'email' : action.parameters.email,
|
'email' : action.parameters.email,
|
||||||
'password' : action.parameters.password
|
'password' : action.parameters.password
|
||||||
|
|
@ -143,7 +171,7 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => {
|
||||||
errorMessages : action.parameters.errorMessages
|
errorMessages : action.parameters.errorMessages
|
||||||
});
|
});
|
||||||
case actiontypes_userinfo.LOGIN:
|
case actiontypes_userinfo.LOGIN:
|
||||||
postRequest(state, '/users/sign_in', {
|
postRequest(action.state, '/users/sign_in', {
|
||||||
email : action.parameters.email,
|
email : action.parameters.email,
|
||||||
password : action.parameters.password
|
password : action.parameters.password
|
||||||
}).then((resp) => {
|
}).then((resp) => {
|
||||||
|
|
@ -186,7 +214,7 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => {
|
||||||
errorMessages : action.parameters.errorMessages
|
errorMessages : action.parameters.errorMessages
|
||||||
});
|
});
|
||||||
case actiontypes_userinfo.LOGOUT:
|
case actiontypes_userinfo.LOGOUT:
|
||||||
deleteRequest(state, '/users/sign_out').then(() => {
|
deleteRequest(action.state, '/users/sign_out').then(() => {
|
||||||
__store.dispatch({ type : actiontypes_userinfo.CLEAR });
|
__store.dispatch({ type : actiontypes_userinfo.CLEAR });
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
__store.dispatch({ type : actiontypes_userinfo.CLEAR });
|
__store.dispatch({ type : actiontypes_userinfo.CLEAR });
|
||||||
|
|
@ -200,7 +228,7 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => {
|
||||||
uid : action.parameters.uid
|
uid : action.parameters.uid
|
||||||
});
|
});
|
||||||
case actiontypes_userinfo.VERIFY_CREDENTIALS:
|
case actiontypes_userinfo.VERIFY_CREDENTIALS:
|
||||||
getRequest(state, '/users/validate_token').then((resp) => {
|
getRequest(action.state, '/users/validate_token').then((resp) => {
|
||||||
storeOptionalToken(resp);
|
storeOptionalToken(resp);
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
__store.dispatch({ type: actiontypes_userinfo.CLEAR });
|
__store.dispatch({ type: actiontypes_userinfo.CLEAR });
|
||||||
|
|
@ -224,12 +252,68 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const reducer_tournamentinfo = (state = defaultstate_tournamentinfo, action) => {
|
||||||
|
switch(action.type) {
|
||||||
|
case actiontypes_tournamentinfo.REQUEST_TOURNAMENT:
|
||||||
|
getRequest(action.state, '/tournaments/' + action.parameters.code).then((resp) => {
|
||||||
|
__store.dispatch({
|
||||||
|
type: actiontypes_tournamentinfo.REQUEST_TOURNAMENT_SUCCESS,
|
||||||
|
parameters: resp.data
|
||||||
|
});
|
||||||
|
storeOptionalToken(resp);
|
||||||
|
action.parameters.successCallback();
|
||||||
|
}).catch(() => {
|
||||||
|
action.parameters.errorCallback();
|
||||||
|
});
|
||||||
|
return Object.assign({}, state, {});
|
||||||
|
case actiontypes_tournamentinfo.REQUEST_TOURNAMENT_SUCCESS:
|
||||||
|
return Object.assign({}, state, {
|
||||||
|
code : action.parameters.code,
|
||||||
|
description : action.parameters.description,
|
||||||
|
id : action.parameters.id,
|
||||||
|
name : action.parameters.name,
|
||||||
|
isPublic : action.parameters.public,
|
||||||
|
stages: action.parameters.stages,
|
||||||
|
teams : action.parameters.teams
|
||||||
|
});
|
||||||
|
case actiontypes_tournamentinfo.MODIFY_TOURNAMENT:
|
||||||
|
patchRequest(action.state, '/teams/' + action.parameters.teamid, {
|
||||||
|
name: action.parameters.name
|
||||||
|
}).then((resp) => {
|
||||||
|
storeOptionalToken(resp);
|
||||||
|
action.parameters.onSuccess();
|
||||||
|
}).catch((error) => {
|
||||||
|
if(error.response) {
|
||||||
|
storeOptionalToken(error.response);
|
||||||
|
}
|
||||||
|
action.parameters.onError();
|
||||||
|
});
|
||||||
|
return Object.assign({}, state, {});
|
||||||
|
case actiontypes_tournamentinfo.MODIFY_TOURNAMENT_SUCCESS:
|
||||||
|
|
||||||
|
return Object.assign({}, state, {});
|
||||||
|
case actiontypes_tournamentinfo.MODIFY_TOURNAMENT_ERROR:
|
||||||
|
|
||||||
|
return Object.assign({}, state, {});
|
||||||
|
|
||||||
|
case actiontypes_tournamentinfo.REHYDRATE:
|
||||||
|
|
||||||
|
return Object.assign({}, state, {});
|
||||||
|
case actiontypes_tournamentinfo.CLEAR:
|
||||||
|
|
||||||
|
return Object.assign({}, state, {});
|
||||||
|
default: return state;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const reducers = {
|
const reducers = {
|
||||||
userinfo: reducer_userinfo
|
userinfo: reducer_userinfo,
|
||||||
|
tournamentinfo: reducer_tournamentinfo
|
||||||
};
|
};
|
||||||
|
|
||||||
const default_applicationstate = {
|
const default_applicationstate = {
|
||||||
userinfo : defaultstate_userinfo
|
userinfo : defaultstate_userinfo,
|
||||||
|
tournamentinfo: defaultstate_tournamentinfo
|
||||||
};
|
};
|
||||||
|
|
||||||
var __store;
|
var __store;
|
||||||
|
|
@ -250,7 +334,10 @@ export function verifyCredentials() {
|
||||||
rehydrateApplicationState();
|
rehydrateApplicationState();
|
||||||
|
|
||||||
if(__store.getState().userinfo.isSignedIn) {
|
if(__store.getState().userinfo.isSignedIn) {
|
||||||
__store.dispatch({ type: actiontypes_userinfo.VERIFY_CREDENTIALS });
|
__store.dispatch({
|
||||||
|
type: actiontypes_userinfo.VERIFY_CREDENTIALS,
|
||||||
|
state: __store.getState()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -261,7 +348,8 @@ export function register(username, email, password) {
|
||||||
username: username,
|
username: username,
|
||||||
email: email,
|
email: email,
|
||||||
password: password
|
password: password
|
||||||
}
|
},
|
||||||
|
state: __store.getState()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -271,12 +359,41 @@ export function login(email, password) {
|
||||||
parameters: {
|
parameters: {
|
||||||
email: email,
|
email: email,
|
||||||
password: password
|
password: password
|
||||||
}
|
},
|
||||||
|
state: __store.getState()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logout() {
|
export function logout() {
|
||||||
__store.dispatch({ type : actiontypes_userinfo.LOGOUT });
|
__store.dispatch({
|
||||||
|
type : actiontypes_userinfo.LOGOUT,
|
||||||
|
state: __store.getState()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function requestTournament(code, successCallback, errorCallback) {
|
||||||
|
__store.dispatch({
|
||||||
|
type: actiontypes_tournamentinfo.REQUEST_TOURNAMENT,
|
||||||
|
parameters: {
|
||||||
|
code: code,
|
||||||
|
successCallback: successCallback,
|
||||||
|
errorCallback: errorCallback
|
||||||
|
},
|
||||||
|
state: __store.getState()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateTeamName(team, successCB, errorCB) {
|
||||||
|
__store.dispatch({
|
||||||
|
type: actiontypes_tournamentinfo.MODIFY_TOURNAMENT,
|
||||||
|
parameters: {
|
||||||
|
teamid: team.id,
|
||||||
|
name: team.name,
|
||||||
|
onSuccess : successCB,
|
||||||
|
onError : errorCB
|
||||||
|
},
|
||||||
|
state: __store.getState()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getState() {
|
export function getState() {
|
||||||
|
|
@ -293,6 +410,10 @@ function rehydrateApplicationState() {
|
||||||
type : actiontypes_userinfo.REHYDRATE,
|
type : actiontypes_userinfo.REHYDRATE,
|
||||||
parameters : Object.assign({}, persistedState.userinfo, {})
|
parameters : Object.assign({}, persistedState.userinfo, {})
|
||||||
});
|
});
|
||||||
|
__store.dispatch({
|
||||||
|
type : actiontypes_tournamentinfo.REHYDRATE,
|
||||||
|
parameters : Object.assign({}, persistedState.tournamentinfo, {})
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,86 @@
|
||||||
|
import Head from 'next/head';
|
||||||
|
import React from 'react';
|
||||||
|
import {Footer, TurniereNavigation} from '../CommonComponents';
|
||||||
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
import {Container} from 'reactstrap';
|
||||||
|
import '../../static/everypage.css';
|
||||||
|
import '../../static/css/error.css';
|
||||||
|
|
||||||
|
export class ErrorPageComponent extends React.Component {
|
||||||
|
|
||||||
|
static getInitialProps({ statusCode }) {
|
||||||
|
return { statusCode };
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Head>
|
||||||
|
<title>turnie.re - Error {this.props.statusCode}</title>
|
||||||
|
</Head>
|
||||||
|
<TurniereNavigation/>
|
||||||
|
<ErrorPage statusCode={this.props.statusCode}/>
|
||||||
|
<Footer/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ErrorPage(props){
|
||||||
|
return (
|
||||||
|
<Container className="mb-5">
|
||||||
|
<div className="row mb-5">
|
||||||
|
<div className="col-lg text-center">
|
||||||
|
<img src="/static/images/logo-questionmark.png" className="w-75 img-fluid"/>
|
||||||
|
</div>
|
||||||
|
<div className="col-lg error-code-box">
|
||||||
|
<h1 className="custom-font py-5">{props.statusCode}</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ErrorMessage code={props.statusCode}/>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ErrorMessage(props) {
|
||||||
|
switch (props.code) {
|
||||||
|
case 400:
|
||||||
|
return (<div className="running-text">
|
||||||
|
<h2>Deine Anfrage ist fehlerhaft.</h2>
|
||||||
|
<p>
|
||||||
|
Wir empfehlen, die eingegebene Seite über die <a href="/">Startseite</a> zu suchen.
|
||||||
|
</p>
|
||||||
|
</div>);
|
||||||
|
case 403:
|
||||||
|
return (<div className="running-text">
|
||||||
|
<h2>Du bist nicht autorisiert, diese Seite aufzurufen.</h2>
|
||||||
|
<p>
|
||||||
|
Bitte stelle sicher, dass Du angemeldet bist und auf dieses Turnier oder dieses Match zugreifen darfst.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Wir empfehlen, die eingegebene Seite über die <a href="/">Startseite</a> zu suchen.
|
||||||
|
</p>
|
||||||
|
</div>);
|
||||||
|
case 404:
|
||||||
|
return (<div className="running-text">
|
||||||
|
<h2>Die aufgerufene Seite wurde leider nicht gefunden.</h2>
|
||||||
|
<p>
|
||||||
|
Entweder hast Du dich vertippt, oder die gesuchte Seite gibt es nicht.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Wir empfehlen, die eingegebene Seite über die <a href="/">Startseite</a> zu suchen.
|
||||||
|
</p>
|
||||||
|
</div>);
|
||||||
|
case 500:
|
||||||
|
return (<div className="running-text">
|
||||||
|
<h2>Diese Seite funktioniert nicht.</h2>
|
||||||
|
<p>
|
||||||
|
turnie.re kann Deine Anfrage im Moment nicht verarbeiten. Bitte versuche es später erneut.
|
||||||
|
</p>
|
||||||
|
</div>);
|
||||||
|
default:
|
||||||
|
return (<div>
|
||||||
|
<h2>Ein unbekannter Fehler ist aufgetreten.</h2>
|
||||||
|
</div>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
"next": "^7.0.2",
|
"next": "^7.0.2",
|
||||||
"react": "^16.6.1",
|
"react": "^16.6.1",
|
||||||
"react-dom": "^16.6.1",
|
"react-dom": "^16.6.1",
|
||||||
|
"react-notify-toast": "^0.5.0",
|
||||||
"react-redux": "^5.1.1",
|
"react-redux": "^5.1.1",
|
||||||
"reactstrap": "^6.5.0",
|
"reactstrap": "^6.5.0",
|
||||||
"redux": "^4.0.1",
|
"redux": "^4.0.1",
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,15 @@ 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 withReduxStore from '../js/redux/reduxStoreBinder';
|
import withReduxStore from '../js/redux/reduxStoreBinder';
|
||||||
import { verifyCredentials } from '../js/api';
|
import Notifications from 'react-notify-toast';
|
||||||
|
|
||||||
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 (
|
||||||
<Container>
|
<Container>
|
||||||
|
<Notifications />
|
||||||
<Provider store={reduxStore}>
|
<Provider store={reduxStore}>
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
</Provider>
|
</Provider>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,9 @@
|
||||||
import Head from 'next/head';
|
import { ErrorPageComponent } from '../js/components/ErrorComponents.js';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {Footer, TurniereNavigation} from '../js/CommonComponents';
|
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import {
|
||||||
import {Container} from 'reactstrap';
|
verifyCredentials
|
||||||
import '../static/everypage.css';
|
} from '../js/api';
|
||||||
import '../static/css/error.css';
|
|
||||||
|
|
||||||
export default class Error extends React.Component {
|
export default class Error extends React.Component {
|
||||||
static getInitialProps({ res, err }) {
|
static getInitialProps({ res, err }) {
|
||||||
|
|
@ -12,75 +11,13 @@ export default class Error extends React.Component {
|
||||||
return { statusCode };
|
return { statusCode };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
verifyCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<ErrorPageComponent statusCode={this.props.statusCode}/>
|
||||||
<Head>
|
|
||||||
<title>turnie.re - Error {this.props.statusCode}</title>
|
|
||||||
</Head>
|
|
||||||
<TurniereNavigation/>
|
|
||||||
<ErrorPage statusCode={this.props.statusCode}/>
|
|
||||||
<Footer/>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ErrorPage(props){
|
|
||||||
return (
|
|
||||||
<Container className="mb-5">
|
|
||||||
<div className="row mb-5">
|
|
||||||
<div className="col-lg text-center">
|
|
||||||
<img src="/static/images/logo-questionmark.png" className="w-75 img-fluid"/>
|
|
||||||
</div>
|
|
||||||
<div className="col-lg error-code-box">
|
|
||||||
<h1 className="custom-font py-5">{props.statusCode}</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ErrorMessage code={props.statusCode}/>
|
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ErrorMessage(props) {
|
|
||||||
switch (props.code) {
|
|
||||||
case 400:
|
|
||||||
return (<div className="running-text">
|
|
||||||
<h2>Deine Anfrage ist fehlerhaft.</h2>
|
|
||||||
<p>
|
|
||||||
Wir empfehlen, die eingegebene Seite über die <a href="/">Startseite</a> zu suchen.
|
|
||||||
</p>
|
|
||||||
</div>);
|
|
||||||
case 403:
|
|
||||||
return (<div className="running-text">
|
|
||||||
<h2>Du bist nicht autorisiert, diese Seite aufzurufen.</h2>
|
|
||||||
<p>
|
|
||||||
Bitte stelle sicher, dass Du angemeldet bist und auf dieses Turnier oder dieses Match zugreifen darfst.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Wir empfehlen, die eingegebene Seite über die <a href="/">Startseite</a> zu suchen.
|
|
||||||
</p>
|
|
||||||
</div>);
|
|
||||||
case 404:
|
|
||||||
return (<div className="running-text">
|
|
||||||
<h2>Die aufgerufene Seite wurde leider nicht gefunden.</h2>
|
|
||||||
<p>
|
|
||||||
Entweder hast Du dich vertippt, oder die gesuchte Seite gibt es nicht.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
Wir empfehlen, die eingegebene Seite über die <a href="/">Startseite</a> zu suchen.
|
|
||||||
</p>
|
|
||||||
</div>);
|
|
||||||
case 500:
|
|
||||||
return (<div className="running-text">
|
|
||||||
<h2>Diese Seite funktioniert nicht.</h2>
|
|
||||||
<p>
|
|
||||||
turnie.re kann Deine Anfrage im Moment nicht verarbeiten. Bitte versuche es später erneut.
|
|
||||||
</p>
|
|
||||||
</div>);
|
|
||||||
default:
|
|
||||||
return (<div>
|
|
||||||
<h2>Ein unbekannter Fehler ist aufgetreten.</h2>
|
|
||||||
</div>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -16,9 +16,20 @@ import {
|
||||||
Label
|
Label
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
|
|
||||||
|
import {
|
||||||
|
verifyCredentials
|
||||||
|
} from '../js/api';
|
||||||
|
|
||||||
import EditableStringList from '../js/EditableStringList';
|
import EditableStringList from '../js/EditableStringList';
|
||||||
|
|
||||||
export default () => (
|
export default class CreatePage extends React.Component {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
verifyCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
<div className="main generic-fullpage-bg">
|
<div className="main generic-fullpage-bg">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Turnier erstellen: turnie.re</title>
|
<title>Turnier erstellen: turnie.re</title>
|
||||||
|
|
@ -29,7 +40,10 @@ export default () => (
|
||||||
</div>
|
</div>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function CreateTournamentCard() {
|
function CreateTournamentCard() {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
17
pages/faq.js
17
pages/faq.js
|
|
@ -5,6 +5,10 @@ import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import { BigImage, Footer, TurniereNavigation } from '../js/CommonComponents.js';
|
import { BigImage, Footer, TurniereNavigation } from '../js/CommonComponents.js';
|
||||||
import '../static/everypage.css';
|
import '../static/everypage.css';
|
||||||
|
|
||||||
|
import {
|
||||||
|
verifyCredentials
|
||||||
|
} from '../js/api';
|
||||||
|
|
||||||
function Main() {
|
function Main() {
|
||||||
return (
|
return (
|
||||||
<div className="main">
|
<div className="main">
|
||||||
|
|
@ -216,7 +220,14 @@ function TournamentFaq() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default () => (
|
export default class FaqPage extends React.Component {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
verifyCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Head>
|
<Head>
|
||||||
<title>FAQ: turnie.re</title>
|
<title>FAQ: turnie.re</title>
|
||||||
|
|
@ -226,4 +237,6 @@ export default () => (
|
||||||
<Main/>
|
<Main/>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@ import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import {BigImage, Footer, TurniereNavigation} from '../js/CommonComponents.js';
|
import {BigImage, Footer, TurniereNavigation} from '../js/CommonComponents.js';
|
||||||
import '../static/everypage.css';
|
import '../static/everypage.css';
|
||||||
|
|
||||||
|
import {
|
||||||
|
verifyCredentials
|
||||||
|
} from '../js/api';
|
||||||
|
|
||||||
function Main() {
|
function Main() {
|
||||||
return (
|
return (
|
||||||
<div className="main running-text">
|
<div className="main running-text">
|
||||||
|
|
@ -69,7 +73,14 @@ function ImprintText(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default () => (
|
export default class ImprintPage extends React.Component {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
verifyCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Head>
|
<Head>
|
||||||
<title>Impressum: turnie.re</title>
|
<title>Impressum: turnie.re</title>
|
||||||
|
|
@ -79,4 +90,6 @@ export default () => (
|
||||||
<Main/>
|
<Main/>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,10 @@ import '../static/css/index.css';
|
||||||
|
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import {
|
||||||
|
verifyCredentials
|
||||||
|
} from '../js/api';
|
||||||
|
|
||||||
function Main() {
|
function Main() {
|
||||||
return (
|
return (
|
||||||
<div className="main">
|
<div className="main">
|
||||||
|
|
@ -114,7 +118,7 @@ function PromotedLinkTournamentCode() {
|
||||||
<CardBody className="row">
|
<CardBody className="row">
|
||||||
<form id="turniercode-form" className="col-lg-4" action="/t" method="get">
|
<form id="turniercode-form" className="col-lg-4" action="/t" method="get">
|
||||||
<input className="form-control" type="search" name="code" placeholder="Turnier-Code"/>
|
<input className="form-control" type="search" name="code" placeholder="Turnier-Code"/>
|
||||||
<button className="btn btn-outline-success w-100 my-2" type="submit">Turnier-Code öffnen</button>
|
<Button className="btn btn-outline-success w-100 my-2" type="submit">Turnier-Code öffnen</Button>
|
||||||
</form>
|
</form>
|
||||||
<div className="col-lg-8">
|
<div className="col-lg-8">
|
||||||
<p>Gib hier einen Turnier Code ein, um direkt zum entsprechenden Turnier zu gelangen.</p>
|
<p>Gib hier einen Turnier Code ein, um direkt zum entsprechenden Turnier zu gelangen.</p>
|
||||||
|
|
@ -165,6 +169,11 @@ function PromotedLinkCreateTournament() {
|
||||||
|
|
||||||
|
|
||||||
class Index extends React.Component {
|
class Index extends React.Component {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
verifyCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,24 @@
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import '../static/everypage.css';
|
|
||||||
import { Footer, TurniereNavigation } from '../js/CommonComponents';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Card, CardBody, Container } from 'reactstrap';
|
import { Card, CardBody, Container } from 'reactstrap';
|
||||||
import { getRequest, getState } from '../js/api';
|
|
||||||
|
|
||||||
export default () => (
|
import { Footer, TurniereNavigation } from '../js/CommonComponents';
|
||||||
|
import {
|
||||||
|
getRequest,
|
||||||
|
getState,
|
||||||
|
verifyCredentials
|
||||||
|
} from '../js/api';
|
||||||
|
|
||||||
|
import '../static/everypage.css';
|
||||||
|
|
||||||
|
export default class ListPage extends React.Component {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
verifyCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
<div className="main generic-fullpage-bg">
|
<div className="main generic-fullpage-bg">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Öffentliche Turniere: turnie.re</title>
|
<title>Öffentliche Turniere: turnie.re</title>
|
||||||
|
|
@ -16,7 +29,9 @@ export default () => (
|
||||||
</div>
|
</div>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class TournamentList extends React.Component {
|
class TournamentList extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,18 @@ import { Button, Card, CardBody, Container, Form, FormGroup, Input, Label } from
|
||||||
import { login } from '../js/api';
|
import { login } from '../js/api';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
export default () => (
|
import {
|
||||||
|
verifyCredentials
|
||||||
|
} from '../js/api';
|
||||||
|
|
||||||
|
export default class LoginPage extends React.Component {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
verifyCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
<div className="main generic-fullpage-bg">
|
<div className="main generic-fullpage-bg">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Login: turnie.re</title>
|
<title>Login: turnie.re</title>
|
||||||
|
|
@ -17,7 +28,9 @@ export default () => (
|
||||||
</div>
|
</div>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Login() {
|
function Login() {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,10 @@ import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import { BigImage, Footer, TurniereNavigation } from '../js/CommonComponents.js';
|
import { BigImage, Footer, TurniereNavigation } from '../js/CommonComponents.js';
|
||||||
import '../static/everypage.css';
|
import '../static/everypage.css';
|
||||||
|
|
||||||
|
import {
|
||||||
|
verifyCredentials
|
||||||
|
} from '../js/api';
|
||||||
|
|
||||||
function Main() {
|
function Main() {
|
||||||
return (
|
return (
|
||||||
<div className="main running-text">
|
<div className="main running-text">
|
||||||
|
|
@ -488,7 +492,14 @@ function PrivacyText(){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default () => (
|
export default class PrivacyPage extends React.Component {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
verifyCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Head>
|
<Head>
|
||||||
<title>Datenschutzerklärung: turnie.re</title>
|
<title>Datenschutzerklärung: turnie.re</title>
|
||||||
|
|
@ -498,4 +509,6 @@ export default () => (
|
||||||
<Main/>
|
<Main/>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,18 @@ import { Button, Card, CardBody, Container, Form, FormGroup, FormText, Input, La
|
||||||
import { register } from '../js/api';
|
import { register } from '../js/api';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
export default () => (
|
import {
|
||||||
|
verifyCredentials
|
||||||
|
} from '../js/api';
|
||||||
|
|
||||||
|
export default class RegisterPage extends React.Component {
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
verifyCredentials();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
<div className="main generic-fullpage-bg">
|
<div className="main generic-fullpage-bg">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Registrieren: turnie.re</title>
|
<title>Registrieren: turnie.re</title>
|
||||||
|
|
@ -18,7 +29,9 @@ export default () => (
|
||||||
</div>
|
</div>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Register() {
|
function Register() {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,290 @@
|
||||||
|
import Head from 'next/head';
|
||||||
|
import React from 'react';
|
||||||
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { notify } from 'react-notify-toast';
|
||||||
|
|
||||||
|
import { requestTournament } from '../js/api';
|
||||||
|
import { BigImage, Footer, TurniereNavigation } from '../js/CommonComponents.js';
|
||||||
|
import { ErrorPageComponent } from '../js/components/ErrorComponents.js';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Container,
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
CardBody,
|
||||||
|
Table
|
||||||
|
} from 'reactstrap';
|
||||||
|
|
||||||
|
import {
|
||||||
|
verifyCredentials,
|
||||||
|
updateTeamName
|
||||||
|
} from '../js/api';
|
||||||
|
|
||||||
|
import '../static/everypage.css';
|
||||||
|
import '../static/css/index.css';
|
||||||
|
|
||||||
|
class EditTournamentPage extends React.Component {
|
||||||
|
|
||||||
|
static async getInitialProps({query}) {
|
||||||
|
return {query};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
validCode: true
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
verifyCredentials();
|
||||||
|
requestTournament(this.props.query.code, () => {
|
||||||
|
this.setState({ validCode: true });
|
||||||
|
this._edittournamentcontent.notifyOfContentUpdate();
|
||||||
|
}, () => {
|
||||||
|
this.setState({ validCode: false });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { validCode } = this.state;
|
||||||
|
const { name } = this.props;
|
||||||
|
|
||||||
|
if(validCode) {
|
||||||
|
return (
|
||||||
|
<div className='pb-5'>
|
||||||
|
<Head>
|
||||||
|
<title>Turnie.re - Turnier bearbeiten</title>
|
||||||
|
</Head>
|
||||||
|
<TurniereNavigation/>
|
||||||
|
<BigImage text={ name }/>
|
||||||
|
|
||||||
|
<EditTournamentContent ref={(edittournamentcontent) => { this._edittournamentcontent = edittournamentcontent; }}/>
|
||||||
|
|
||||||
|
<Footer/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<ErrorPageComponent statusCode={ 404 }/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapStateToTournamentInfo(state) {
|
||||||
|
const { name } = state.tournamentinfo;
|
||||||
|
return { name };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(
|
||||||
|
mapStateToTournamentInfo
|
||||||
|
)(EditTournamentPage);
|
||||||
|
|
||||||
|
class EditTournamentContent extends React.Component {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className='mb-5'>
|
||||||
|
<ReturnToTournamentButton/>
|
||||||
|
<EditTournamentPropertiesField ref={(field) => { this._edittournamentpropertiesfield = field; }}/>
|
||||||
|
<EditTeamField ref={(field) => { this._editteamfield = field; }}/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyOfContentUpdate() {
|
||||||
|
this._edittournamentpropertiesfield.notifyOfContentUpdate();
|
||||||
|
this._editteamfield.notifyOfContentUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function ReturnToTournamentButton() {
|
||||||
|
return (
|
||||||
|
<Container className="px-0">
|
||||||
|
<Button color="secondary" className="mb-5 w-100" href="./">Zurück zum Turnier</Button>
|
||||||
|
</Container>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditTournamentPropertiesField extends React.Component {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Card className="container">
|
||||||
|
<CardBody>
|
||||||
|
<h2>Turnier-Eigenschaften ändern</h2>
|
||||||
|
<VisibleEditTournamentForm ref={(form) => { this._visibleedittournamentform = form; }}/>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyOfContentUpdate() {
|
||||||
|
this._visibleedittournamentform.getWrappedInstance().notifyOfContentUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditTournamentForm extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
name : '',
|
||||||
|
description : '',
|
||||||
|
isPublic : false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { name, description, isPublic } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="name">Turnier-Name</label>
|
||||||
|
<input className="form-control" type="text" name="name" id="edittournament-textfield-name" value={ name } placeholder={ name } onChange={ this.handleNameInput.bind(this) } />
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label htmlFor="name">Turnier-Beschreibung</label>
|
||||||
|
<input className="form-control" type="text" name="name" id="edittournament-textfield-description" value={ description } placeholder={ description } onChange={ this.handleDescriptionInput.bind(this) } />
|
||||||
|
</div>
|
||||||
|
<div className="form-group custom-control custom-checkbox">
|
||||||
|
<input className="custom-control-input" type="checkbox" name="isPublic" id="edittournament-checkbox-isPublic" value={ isPublic } onChange={ this.handlePublicInput.bind(this) } />
|
||||||
|
<label htmlFor="isPublic" className="custom-control-label">Das Turnier öffentlich anzeigen</label>
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<div className="input-group">
|
||||||
|
<Button color="success" className="px-5" id="edittournament-button" onClick={ this.handleClick.bind(this) }>Ändern</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyOfContentUpdate() {
|
||||||
|
const { name, description, isPublic } = this.props;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
name : name? name : '',
|
||||||
|
description : description? description : '',
|
||||||
|
isPublic : isPublic
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick() {
|
||||||
|
// TODO: Apply changes to the tournament properties
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNameInput(input) {
|
||||||
|
this.setState({ name : input.target.value });
|
||||||
|
}
|
||||||
|
|
||||||
|
handleDescriptionInput(input) {
|
||||||
|
this.setState({ description : input.target.value });
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePublicInput(input) {
|
||||||
|
this.setState({ public : input.target.value });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapStateToTournamentFormProps(state) {
|
||||||
|
const { name, description, isPublic } = state.tournamentinfo;
|
||||||
|
return { name, description, isPublic };
|
||||||
|
}
|
||||||
|
|
||||||
|
const VisibleEditTournamentForm = connect(
|
||||||
|
mapStateToTournamentFormProps,
|
||||||
|
null, null, { withRef : true}
|
||||||
|
)(EditTournamentForm);
|
||||||
|
|
||||||
|
class EditTeamField extends React.Component {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<Card className="container my-4">
|
||||||
|
<CardBody>
|
||||||
|
<h2>Team-Namen ändern</h2>
|
||||||
|
<VisibleEditTeamNamesForm ref={(form) => { this._visibleeditteamnamesform = form; }}/>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyOfContentUpdate() {
|
||||||
|
this._visibleeditteamnamesform.getWrappedInstance().notifyOfContentUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class EditTeamNamesForm extends React.Component {
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
teams : []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { teams } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Table className="table-striped mt-3">
|
||||||
|
<tbody>
|
||||||
|
{
|
||||||
|
teams.map((team, index) =>
|
||||||
|
<tr key={index}>
|
||||||
|
<td><Button outline size="sm" className="changeTeamnameButton" id={ 'editteam-button-team_' + team.id } onClick={ this.handleClick.bind(this, index) }>Ändern</Button></td>
|
||||||
|
<td className="w-100"><input className="form-control" type="text" id={ 'editteam-textfield-team_' + team.id } value={ team.name } placeholder={ team.name } onChange={ this.handleNameInput.bind(this, index) } /></td>
|
||||||
|
</tr>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</tbody>
|
||||||
|
</Table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyOfContentUpdate() {
|
||||||
|
const { teams } = this.props;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
teams : teams
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNameInput(index, input) {
|
||||||
|
var team = this.state.teams.slice();
|
||||||
|
|
||||||
|
team[index].name = input.target.value;
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
teams : team
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleClick(index) {
|
||||||
|
updateTeamName(this.state.teams[index], () => {
|
||||||
|
notify.show('Team Name wurde erfolgreich geändert.', 'success', 5000);
|
||||||
|
}, () => {
|
||||||
|
notify.show('Team Name konnte nicht geändert werden.', 'warning', 5000);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mapStateToTeamFormProps(state) {
|
||||||
|
const { teams } = state.tournamentinfo;
|
||||||
|
return { teams };
|
||||||
|
}
|
||||||
|
|
||||||
|
const VisibleEditTeamNamesForm = connect(
|
||||||
|
mapStateToTeamFormProps,
|
||||||
|
null, null, { withRef : true }
|
||||||
|
)(EditTeamNamesForm);
|
||||||
|
|
||||||
|
|
@ -1,12 +1,20 @@
|
||||||
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 (
|
||||||
<div>
|
<div>
|
||||||
|
|
|
||||||
|
|
@ -22,29 +22,39 @@ import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import {BigImage, Footer, TurniereNavigation} from '../js/CommonComponents.js';
|
import {BigImage, Footer, TurniereNavigation} from '../js/CommonComponents.js';
|
||||||
import '../static/everypage.css';
|
import '../static/everypage.css';
|
||||||
import '../static/css/tournament.css';
|
import '../static/css/tournament.css';
|
||||||
import { getRequest, getState } from '../js/api';
|
|
||||||
|
|
||||||
function Tournament(props) {
|
import {
|
||||||
|
getRequest,
|
||||||
|
getState,
|
||||||
|
verifyCredentials
|
||||||
|
} from '../js/api';
|
||||||
|
|
||||||
|
class TournamentPage extends React.Component {
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { id, description, isPublic, code, ownerUsername, playoffStages } = this.props.tournament;
|
||||||
|
|
||||||
// TODO: Change href-prop of the anchor tag to contain the tournament code
|
// TODO: Change href-prop of the anchor tag to contain the tournament code
|
||||||
return (
|
return (
|
||||||
<div className='pb-5'>
|
<div className='pb-5'>
|
||||||
<Container>
|
<Container>
|
||||||
<a href={'/t/' + props.tournament.id + '/edit'} className='btn btn-outline-secondary'>Turnier bearbeiten</a>
|
<a href={'/t/' + id + '/edit'} className='btn btn-outline-secondary'>Turnier bearbeiten</a>
|
||||||
<p>{props.tournament.description}</p>
|
<p>{description}</p>
|
||||||
<ListGroup>
|
<ListGroup>
|
||||||
<ListGroupItem>
|
<ListGroupItem>
|
||||||
{props.tournament.isPublic ? 'Das Turnier ist öffentlich.' : 'Das Turnier ist privat.'}
|
{isPublic ? 'Das Turnier ist öffentlich.' : 'Das Turnier ist privat.'}
|
||||||
</ListGroupItem>
|
</ListGroupItem>
|
||||||
<ListGroupItem>Turnier-Code: <b>{props.tournament.code}</b></ListGroupItem>
|
<ListGroupItem>Turnier-Code: <b>{code}</b></ListGroupItem>
|
||||||
<ListGroupItem>von <b>{props.tournament.ownerUsername}</b></ListGroupItem>
|
<ListGroupItem>von <b>{ownerUsername}</b></ListGroupItem>
|
||||||
</ListGroup>
|
</ListGroup>
|
||||||
</Container>
|
</Container>
|
||||||
<div className='stages pt-5'>
|
<div className='stages pt-5'>
|
||||||
{props.tournament.playoffStages.map(stage =>
|
{playoffStages.map(stage =>
|
||||||
<Stage level={getLevelName(stage.level)} matches={stage.matches} key={stage.level}/>)}
|
<Stage level={getLevelName(stage.level)} matches={stage.matches} key={stage.level}/>)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLevelName(levelNumber) {
|
function getLevelName(levelNumber) {
|
||||||
|
|
@ -57,10 +67,12 @@ function getLevelName(levelNumber) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function TournamentContainer(props) {
|
function TournamentContainer(props) {
|
||||||
if (props.data === null) {
|
const { tournament } = props.data;
|
||||||
|
|
||||||
|
if (tournament === null) {
|
||||||
return <Container>null</Container>;
|
return <Container>null</Container>;
|
||||||
} else {
|
} else {
|
||||||
return <Tournament tournament={props.data.tournament}/>;
|
return <TournamentPage tournament={tournament}/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -339,9 +351,24 @@ function convertMatch(apiMatch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Main extends React.Component {
|
class Main extends React.Component {
|
||||||
|
|
||||||
|
static async getInitialProps({query}) {
|
||||||
|
return {query};
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
tournament : null
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
verifyCredentials();
|
||||||
|
|
||||||
const code = this.props.query.code;
|
const code = this.props.query.code;
|
||||||
|
|
||||||
getRequest(getState(), '/tournaments/' + code)
|
getRequest(getState(), '/tournaments/' + code)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.setState({tournament: convertTournament(response.data)});
|
this.setState({tournament: convertTournament(response.data)});
|
||||||
|
|
@ -349,12 +376,9 @@ class Main extends React.Component {
|
||||||
.catch(() => { /* TODO: Show some kind of error or smth */ });
|
.catch(() => { /* TODO: Show some kind of error or smth */ });
|
||||||
}
|
}
|
||||||
|
|
||||||
static async getInitialProps({query}) {
|
|
||||||
return {query};
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const tournamentName = this.state === null ? 'Turnier' : this.state.tournament.name;
|
const tournamentName = this.state.tournament === null ? 'Turnier' : this.state.tournament.name;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Head>
|
<Head>
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,12 @@ app.prepare()
|
||||||
app.render(req, res, actualPage, queryParam);
|
app.render(req, res, actualPage, queryParam);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.get('/t/:code/edit', (req, res) => {
|
||||||
|
const actualPage = '/tournament-edit';
|
||||||
|
const queryParam = { code: req.params.code };
|
||||||
|
app.render(req, res, actualPage, queryParam);
|
||||||
|
});
|
||||||
|
|
||||||
server.get('*', (req, res) => {
|
server.get('*', (req, res) => {
|
||||||
return handle(req, res);
|
return handle(req, res);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,3 +2,7 @@
|
||||||
background: url("/static/images/tennis-blurred.jpg") no-repeat center;
|
background: url("/static/images/tennis-blurred.jpg") no-repeat center;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h2, h3, h4 {
|
||||||
|
font-family: Halt, sans-serif;
|
||||||
|
}
|
||||||
10
yarn.lock
10
yarn.lock
|
|
@ -5635,7 +5635,7 @@ number-is-nan@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
|
||||||
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
|
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
|
||||||
|
|
||||||
object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
object-assign@^4.0.0, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
|
||||||
version "4.1.1"
|
version "4.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||||
|
|
@ -6388,6 +6388,14 @@ react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4:
|
||||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||||
|
|
||||||
|
react-notify-toast@^0.5.0:
|
||||||
|
version "0.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/react-notify-toast/-/react-notify-toast-0.5.0.tgz#b00cf50a3cc97a1d222ecd7d7a8e7f14bef5fa67"
|
||||||
|
integrity sha1-sAz1CjzJeh0iLs19eo5/FL71+mc=
|
||||||
|
dependencies:
|
||||||
|
object-assign "^4.0.0"
|
||||||
|
prop-types "^15.5.8"
|
||||||
|
|
||||||
react-popper@^0.10.4:
|
react-popper@^0.10.4:
|
||||||
version "0.10.4"
|
version "0.10.4"
|
||||||
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.10.4.tgz#af2a415ea22291edd504678d7afda8a6ee3295aa"
|
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-0.10.4.tgz#af2a415ea22291edd504678d7afda8a6ee3295aa"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue