Merge pull request #26 from turniere/ticket/TURNIERE-177
Choose and apply consistent code style rules: Ticket/turniere 177
This commit is contained in:
commit
cea1ceb081
|
|
@ -7,7 +7,7 @@
|
||||||
"plugins": [
|
"plugins": [
|
||||||
"react"
|
"react"
|
||||||
],
|
],
|
||||||
"extends": "eslint:recommended",
|
"extends": ["eslint:recommended", "google"],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 2018,
|
"ecmaVersion": 2018,
|
||||||
"sourceType": "module",
|
"sourceType": "module",
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
|
"arrow-parens": ["error", "as-needed"],
|
||||||
|
"comma-dangle": ["error", "never"],
|
||||||
"react/jsx-uses-react": "error",
|
"react/jsx-uses-react": "error",
|
||||||
"react/jsx-uses-vars": "error",
|
"react/jsx-uses-vars": "error",
|
||||||
"indent": [
|
"indent": [
|
||||||
|
|
@ -26,10 +28,16 @@
|
||||||
"error",
|
"error",
|
||||||
"unix"
|
"unix"
|
||||||
],
|
],
|
||||||
|
"max-len": [
|
||||||
|
"error",
|
||||||
|
{"code": 120}
|
||||||
|
],
|
||||||
"quotes": [
|
"quotes": [
|
||||||
"error",
|
"error",
|
||||||
"single"
|
"single"
|
||||||
],
|
],
|
||||||
|
"require-jsdoc": "off",
|
||||||
|
"valid-jsdoc": "off",
|
||||||
"semi": [
|
"semi": [
|
||||||
"error",
|
"error",
|
||||||
"always"
|
"always"
|
||||||
|
|
|
||||||
386
js/api.js
386
js/api.js
|
|
@ -3,116 +3,116 @@ import {
|
||||||
applyMiddleware,
|
applyMiddleware,
|
||||||
combineReducers
|
combineReducers
|
||||||
} from 'redux';
|
} from 'redux';
|
||||||
import { composeWithDevTools } from 'redux-devtools-extension';
|
import {composeWithDevTools} from 'redux-devtools-extension';
|
||||||
import thunkMiddleware from 'redux-thunk';
|
import thunkMiddleware from 'redux-thunk';
|
||||||
|
|
||||||
import { errorMessages } from './constants';
|
import {errorMessages} from './constants';
|
||||||
|
|
||||||
import getConfig from 'next/config';
|
import getConfig from 'next/config';
|
||||||
const { publicRuntimeConfig } = getConfig();
|
const {publicRuntimeConfig} = getConfig();
|
||||||
|
|
||||||
const api_url = publicRuntimeConfig.api_url;
|
const apiUrl = publicRuntimeConfig.api_url;
|
||||||
|
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
const actiontypes_userinfo = {
|
const actionTypesUserinfo = {
|
||||||
'REGISTER' : 'REGISTER',
|
'REGISTER': 'REGISTER',
|
||||||
'REGISTER_RESULT_SUCCESS' : 'REGISTER_RESULT_SUCCESS',
|
'REGISTER_RESULT_SUCCESS': 'REGISTER_RESULT_SUCCESS',
|
||||||
'REGISTER_RESULT_ERROR' : 'REGISTER_RESULT_ERROR',
|
'REGISTER_RESULT_ERROR': 'REGISTER_RESULT_ERROR',
|
||||||
|
|
||||||
'LOGIN' : 'LOGIN',
|
'LOGIN': 'LOGIN',
|
||||||
'LOGIN_RESULT_SUCCESS' : 'LOGIN_RESULT_SUCCESS',
|
'LOGIN_RESULT_SUCCESS': 'LOGIN_RESULT_SUCCESS',
|
||||||
'LOGIN_RESULT_ERROR' : 'LOGIN_RESULT_ERROR',
|
'LOGIN_RESULT_ERROR': 'LOGIN_RESULT_ERROR',
|
||||||
|
|
||||||
'LOGOUT' : 'LOGOUT',
|
'LOGOUT': 'LOGOUT',
|
||||||
|
|
||||||
'VERIFY_CREDENTIALS' : 'VERIFY_CREDENTIALS',
|
'VERIFY_CREDENTIALS': 'VERIFY_CREDENTIALS',
|
||||||
'VERIFY_CREDENTIALS_SUCCESS' : 'VERIFY_CREDENTIALS_SUCCESS',
|
'VERIFY_CREDENTIALS_SUCCESS': 'VERIFY_CREDENTIALS_SUCCESS',
|
||||||
'VERIFY_CREDENTIALS_ERROR' : 'VERIFY_CREDENTIALS_ERROR',
|
'VERIFY_CREDENTIALS_ERROR': 'VERIFY_CREDENTIALS_ERROR',
|
||||||
|
|
||||||
'STORE_AUTH_HEADERS' : 'STORE_AUTH_HEADERS',
|
'STORE_AUTH_HEADERS': 'STORE_AUTH_HEADERS',
|
||||||
|
|
||||||
'REHYDRATE' : 'USERINFO_REHYDRATE',
|
'REHYDRATE': 'USERINFO_REHYDRATE',
|
||||||
'CLEAR' : 'USERINFO_CLEAR'
|
'CLEAR': 'USERINFO_CLEAR'
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultstate_userinfo = {
|
const defaultStateUserinfo = {
|
||||||
isSignedIn : false,
|
isSignedIn: false,
|
||||||
username : null,
|
username: null,
|
||||||
error : false,
|
error: false,
|
||||||
errorMessages : [],
|
errorMessages: [],
|
||||||
|
|
||||||
accesstoken : null,
|
accesstoken: null,
|
||||||
client : null,
|
client: null,
|
||||||
expiry : null,
|
expiry: null,
|
||||||
uid : null
|
uid: null
|
||||||
};
|
};
|
||||||
|
|
||||||
const actiontypes_tournamentinfo = {
|
const actionTypesTournamentinfo = {
|
||||||
'REQUEST_TOURNAMENT' : 'REQUEST_TOURNAMENT',
|
'REQUEST_TOURNAMENT': 'REQUEST_TOURNAMENT',
|
||||||
'REQUEST_TOURNAMENT_SUCCESS' : 'REQUEST_TOURNAMENT_SUCCESS',
|
'REQUEST_TOURNAMENT_SUCCESS': 'REQUEST_TOURNAMENT_SUCCESS',
|
||||||
|
|
||||||
'CREATE_TOURNAMENT' : 'CREATE_TOURNAMENT',
|
'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',
|
||||||
|
|
||||||
'REHYDRATE' : 'TOURNAMENTINFO_REHYDRATE',
|
'REHYDRATE': 'TOURNAMENTINFO_REHYDRATE',
|
||||||
'CLEAR' : 'TOURNAMENTINFO_CLEAR',
|
'CLEAR': 'TOURNAMENTINFO_CLEAR'
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultstate_tournamentinfo = {
|
const defaultStateTournamentinfo = {
|
||||||
code : '',
|
code: '',
|
||||||
description : '',
|
description: '',
|
||||||
id : -1,
|
id: -1,
|
||||||
name : '',
|
name: '',
|
||||||
ownerUsername : '',
|
ownerUsername: '',
|
||||||
isPublic : '',
|
isPublic: '',
|
||||||
stages: [],
|
stages: [],
|
||||||
teams : []
|
teams: []
|
||||||
};
|
};
|
||||||
|
|
||||||
const actiontypes_tournamentlist = {
|
const actionTypesTournamentlist = {
|
||||||
'FETCH': 'FETCH',
|
'FETCH': 'FETCH',
|
||||||
'FETCH_SUCCESS': 'FETCH_SUCCESS',
|
'FETCH_SUCCESS': 'FETCH_SUCCESS',
|
||||||
'REHYDRATE': 'REHYDRATE'
|
'REHYDRATE': 'REHYDRATE'
|
||||||
};
|
};
|
||||||
|
|
||||||
const defaultstate_tournamentlist = {
|
const defaultStateTournamentlist = {
|
||||||
tournaments: []
|
tournaments: []
|
||||||
};
|
};
|
||||||
|
|
||||||
export function postRequest(state, url, data) {
|
export function postRequest(state, url, data) {
|
||||||
return axios.post(api_url + url, data, {
|
return axios.post(apiUrl + url, data, {
|
||||||
headers : generateHeaders(state)
|
headers: generateHeaders(state)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRequest(state, url) {
|
export function getRequest(state, url) {
|
||||||
return axios.get(api_url + url, {
|
return axios.get(apiUrl + url, {
|
||||||
headers : generateHeaders(state)
|
headers: generateHeaders(state)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteRequest(state, url) {
|
export function deleteRequest(state, url) {
|
||||||
return axios.delete(api_url + url, {
|
return axios.delete(apiUrl + url, {
|
||||||
headers : generateHeaders(state)
|
headers: generateHeaders(state)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function patchRequest(state, url, data) {
|
export function patchRequest(state, url, data) {
|
||||||
return axios.patch(api_url + url, data, {
|
return axios.patch(apiUrl + url, data, {
|
||||||
headers : generateHeaders(state)
|
headers: generateHeaders(state)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateHeaders(state) {
|
function generateHeaders(state) {
|
||||||
if(state.userinfo.isSignedIn) {
|
if (state.userinfo.isSignedIn) {
|
||||||
return {
|
return {
|
||||||
'access-token' : state.userinfo.accesstoken,
|
'access-token': state.userinfo.accesstoken,
|
||||||
'client' : state.userinfo.client,
|
'client': state.userinfo.client,
|
||||||
'uid' : state.userinfo.uid
|
'uid': state.userinfo.uid
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -120,26 +120,26 @@ function generateHeaders(state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function storeOptionalToken(response) {
|
function storeOptionalToken(response) {
|
||||||
if(checkForAuthenticationHeaders(response)) {
|
if (checkForAuthenticationHeaders(response)) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type : actiontypes_userinfo.STORE_AUTH_HEADERS,
|
type: actionTypesUserinfo.STORE_AUTH_HEADERS,
|
||||||
parameters : {
|
parameters: {
|
||||||
accesstoken : response.headers['access-token'],
|
accesstoken: response.headers['access-token'],
|
||||||
client : response.headers['client'],
|
client: response.headers['client'],
|
||||||
expiry : response.headers['expiry'],
|
expiry: response.headers['expiry'],
|
||||||
uid : response.headers['uid']
|
uid: response.headers['uid']
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkForAuthenticationHeaders(response) {
|
function checkForAuthenticationHeaders(response) {
|
||||||
if(response.headers) {
|
if (response.headers) {
|
||||||
const requiredHeaders = [
|
const requiredHeaders = [
|
||||||
'access-token', 'client', 'uid', 'expiry'
|
'access-token', 'client', 'uid', 'expiry'
|
||||||
];
|
];
|
||||||
for(var i = 0; i < requiredHeaders.length; i++) {
|
for (let i = 0; i < requiredHeaders.length; i++) {
|
||||||
if(!response.headers[requiredHeaders[i]]) {
|
if (!response.headers[requiredHeaders[i]]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -148,32 +148,32 @@ function checkForAuthenticationHeaders(response) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const reducer_userinfo = (state = defaultstate_userinfo, action) => {
|
const reducerUserinfo = (state = defaultStateUserinfo, action) => {
|
||||||
switch(action.type) {
|
switch (action.type) {
|
||||||
case actiontypes_userinfo.REGISTER:
|
case actionTypesUserinfo.REGISTER:
|
||||||
postRequest(action.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
|
||||||
}).then((resp) => {
|
}).then(resp => {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type : actiontypes_userinfo.REGISTER_RESULT_SUCCESS
|
type: actionTypesUserinfo.REGISTER_RESULT_SUCCESS
|
||||||
});
|
});
|
||||||
storeOptionalToken(resp);
|
storeOptionalToken(resp);
|
||||||
}).catch((error) => {
|
}).catch(error => {
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
'type' : actiontypes_userinfo.REGISTER_RESULT_ERROR,
|
'type': actionTypesUserinfo.REGISTER_RESULT_ERROR,
|
||||||
'parameters' : {
|
'parameters': {
|
||||||
'errorMessages' : error.response.data.errors.full_messages
|
'errorMessages': error.response.data.errors.full_messages
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
storeOptionalToken(error.response);
|
storeOptionalToken(error.response);
|
||||||
} else {
|
} else {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
'type' : actiontypes_userinfo.REGISTER_RESULT_ERROR,
|
'type': actionTypesUserinfo.REGISTER_RESULT_ERROR,
|
||||||
'parameters' : {
|
'parameters': {
|
||||||
'errorMessages' : [
|
'errorMessages': [
|
||||||
errorMessages['registration_errorunknown']['en']
|
errorMessages['registration_errorunknown']['en']
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -181,115 +181,115 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return Object.assign({}, state, {});
|
return Object.assign({}, state, {});
|
||||||
case actiontypes_userinfo.REGISTER_RESULT_SUCCESS:
|
case actionTypesUserinfo.REGISTER_RESULT_SUCCESS:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
error : false,
|
error: false,
|
||||||
errorMessages : []
|
errorMessages: []
|
||||||
});
|
});
|
||||||
case actiontypes_userinfo.REGISTER_RESULT_ERROR:
|
case actionTypesUserinfo.REGISTER_RESULT_ERROR:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
error : true,
|
error: true,
|
||||||
errorMessages : action.parameters.errorMessages
|
errorMessages: action.parameters.errorMessages
|
||||||
});
|
});
|
||||||
case actiontypes_userinfo.LOGIN:
|
case actionTypesUserinfo.LOGIN:
|
||||||
postRequest(action.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 => {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type : actiontypes_userinfo.LOGIN_RESULT_SUCCESS,
|
type: actionTypesUserinfo.LOGIN_RESULT_SUCCESS,
|
||||||
parameters : {
|
parameters: {
|
||||||
username : resp.data.username,
|
username: resp.data.username,
|
||||||
successCallback: action.parameters.successCallback
|
successCallback: action.parameters.successCallback
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
storeOptionalToken(resp);
|
storeOptionalToken(resp);
|
||||||
}).catch((error) => {
|
}).catch(error => {
|
||||||
if(error.response) {
|
if (error.response) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
'type' : actiontypes_userinfo.LOGIN_RESULT_ERROR,
|
'type': actionTypesUserinfo.LOGIN_RESULT_ERROR,
|
||||||
'parameters' : {
|
'parameters': {
|
||||||
'errorMessages' : error.response.data.errors
|
'errorMessages': error.response.data.errors
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
storeOptionalToken(error.response);
|
storeOptionalToken(error.response);
|
||||||
} else {
|
} else {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
'type' : actiontypes_userinfo.LOGIN_RESULT_ERROR,
|
'type': actionTypesUserinfo.LOGIN_RESULT_ERROR,
|
||||||
'parameters' : {
|
'parameters': {
|
||||||
'errorMessages' : [ errorMessages['login_errorunknown']['en'] ]
|
'errorMessages': [errorMessages['login_errorunknown']['en']]
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return Object.assign({}, state, {});
|
return Object.assign({}, state, {});
|
||||||
case actiontypes_userinfo.LOGIN_RESULT_SUCCESS:
|
case actionTypesUserinfo.LOGIN_RESULT_SUCCESS:
|
||||||
action.parameters.successCallback(action.parameters.username);
|
action.parameters.successCallback(action.parameters.username);
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
isSignedIn : true,
|
isSignedIn: true,
|
||||||
error : false,
|
error: false,
|
||||||
errorMessages : [],
|
errorMessages: [],
|
||||||
username : action.parameters.username,
|
username: action.parameters.username
|
||||||
});
|
});
|
||||||
case actiontypes_userinfo.LOGIN_RESULT_ERROR:
|
case actionTypesUserinfo.LOGIN_RESULT_ERROR:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
error : true,
|
error: true,
|
||||||
errorMessages : action.parameters.errorMessages
|
errorMessages: action.parameters.errorMessages
|
||||||
});
|
});
|
||||||
case actiontypes_userinfo.LOGOUT:
|
case actionTypesUserinfo.LOGOUT:
|
||||||
deleteRequest(action.state, '/users/sign_out').then(() => {
|
deleteRequest(action.state, '/users/sign_out').then(() => {
|
||||||
action.parameters.successCallback();
|
action.parameters.successCallback();
|
||||||
__store.dispatch({ type : actiontypes_userinfo.CLEAR });
|
__store.dispatch({type: actionTypesUserinfo.CLEAR});
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
__store.dispatch({ type : actiontypes_userinfo.CLEAR });
|
__store.dispatch({type: actionTypesUserinfo.CLEAR});
|
||||||
});
|
});
|
||||||
return Object.assign({}, state, {});
|
return Object.assign({}, state, {});
|
||||||
case actiontypes_userinfo.STORE_AUTH_HEADERS:
|
case actionTypesUserinfo.STORE_AUTH_HEADERS:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
accesstoken : action.parameters.accesstoken,
|
accesstoken: action.parameters.accesstoken,
|
||||||
client : action.parameters.client,
|
client: action.parameters.client,
|
||||||
expiry : action.parameters.expiry,
|
expiry: action.parameters.expiry,
|
||||||
uid : action.parameters.uid
|
uid: action.parameters.uid
|
||||||
});
|
});
|
||||||
case actiontypes_userinfo.VERIFY_CREDENTIALS:
|
case actionTypesUserinfo.VERIFY_CREDENTIALS:
|
||||||
getRequest(action.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: actionTypesUserinfo.CLEAR});
|
||||||
});
|
});
|
||||||
return Object.assign({}, state, {});
|
return Object.assign({}, state, {});
|
||||||
case actiontypes_userinfo.REHYDRATE:
|
case actionTypesUserinfo.REHYDRATE:
|
||||||
return Object.assign({}, state, action.parameters, { error: false, errorMessages: [] });
|
return Object.assign({}, state, action.parameters, {error: false, errorMessages: []});
|
||||||
case actiontypes_userinfo.CLEAR:
|
case actionTypesUserinfo.CLEAR:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
isSignedIn : false,
|
isSignedIn: false,
|
||||||
username : null,
|
username: null,
|
||||||
error : false,
|
error: false,
|
||||||
errorMessages : [],
|
errorMessages: [],
|
||||||
|
|
||||||
accesstoken : null,
|
accesstoken: null,
|
||||||
client : null,
|
client: null,
|
||||||
expiry : null,
|
expiry: null,
|
||||||
uid : null
|
uid: null
|
||||||
});
|
});
|
||||||
default: return state;
|
default: return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const reducer_tournamentinfo = (state = defaultstate_tournamentinfo, action) => {
|
const reducerTournamentinfo = (state = defaultStateTournamentinfo, action) => {
|
||||||
switch(action.type) {
|
switch (action.type) {
|
||||||
case actiontypes_tournamentinfo.CREATE_TOURNAMENT:
|
case actionTypesTournamentinfo.CREATE_TOURNAMENT:
|
||||||
postRequest(action.state, '/tournaments', action.parameters.tournament).then((resp) => {
|
postRequest(action.state, '/tournaments', action.parameters.tournament).then(resp => {
|
||||||
storeOptionalToken(resp);
|
storeOptionalToken(resp);
|
||||||
action.parameters.successCallback();
|
action.parameters.successCallback();
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
action.parameters.errorCallback();
|
action.parameters.errorCallback();
|
||||||
});
|
});
|
||||||
return Object.assign({}, state, {});
|
return Object.assign({}, state, {});
|
||||||
case actiontypes_tournamentinfo.REQUEST_TOURNAMENT:
|
case actionTypesTournamentinfo.REQUEST_TOURNAMENT:
|
||||||
getRequest(action.state, '/tournaments/' + action.parameters.code).then((resp) => {
|
getRequest(action.state, '/tournaments/' + action.parameters.code).then(resp => {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type: actiontypes_tournamentinfo.REQUEST_TOURNAMENT_SUCCESS,
|
type: actionTypesTournamentinfo.REQUEST_TOURNAMENT_SUCCESS,
|
||||||
parameters: resp.data
|
parameters: resp.data
|
||||||
});
|
});
|
||||||
storeOptionalToken(resp);
|
storeOptionalToken(resp);
|
||||||
|
|
@ -298,64 +298,64 @@ const reducer_tournamentinfo = (state = defaultstate_tournamentinfo, action) =>
|
||||||
action.parameters.errorCallback();
|
action.parameters.errorCallback();
|
||||||
});
|
});
|
||||||
return Object.assign({}, state, {});
|
return Object.assign({}, state, {});
|
||||||
case actiontypes_tournamentinfo.REQUEST_TOURNAMENT_SUCCESS:
|
case actionTypesTournamentinfo.REQUEST_TOURNAMENT_SUCCESS:
|
||||||
return Object.assign({}, state, {
|
return Object.assign({}, state, {
|
||||||
code : action.parameters.code,
|
code: action.parameters.code,
|
||||||
description : action.parameters.description,
|
description: action.parameters.description,
|
||||||
id : action.parameters.id,
|
id: action.parameters.id,
|
||||||
name : action.parameters.name,
|
name: action.parameters.name,
|
||||||
ownerUsername : action.parameters.owner_username,
|
ownerUsername: action.parameters.owner_username,
|
||||||
isPublic : action.parameters.public,
|
isPublic: action.parameters.public,
|
||||||
stages: action.parameters.stages,
|
stages: action.parameters.stages,
|
||||||
teams : action.parameters.teams
|
teams: action.parameters.teams
|
||||||
});
|
});
|
||||||
case actiontypes_tournamentinfo.MODIFY_TOURNAMENT:
|
case actionTypesTournamentinfo.MODIFY_TOURNAMENT:
|
||||||
patchRequest(action.state, '/teams/' + action.parameters.teamid, {
|
patchRequest(action.state, '/teams/' + action.parameters.teamid, {
|
||||||
name: action.parameters.name
|
name: action.parameters.name
|
||||||
}).then((resp) => {
|
}).then(resp => {
|
||||||
storeOptionalToken(resp);
|
storeOptionalToken(resp);
|
||||||
action.parameters.onSuccess();
|
action.parameters.onSuccess();
|
||||||
}).catch((error) => {
|
}).catch(error => {
|
||||||
if(error.response) {
|
if (error.response) {
|
||||||
storeOptionalToken(error.response);
|
storeOptionalToken(error.response);
|
||||||
}
|
}
|
||||||
action.parameters.onError();
|
action.parameters.onError();
|
||||||
});
|
});
|
||||||
return Object.assign({}, state, {});
|
return Object.assign({}, state, {});
|
||||||
case actiontypes_tournamentinfo.MODIFY_TOURNAMENT_SUCCESS:
|
case actionTypesTournamentinfo.MODIFY_TOURNAMENT_SUCCESS:
|
||||||
|
|
||||||
return Object.assign({}, state, {});
|
return Object.assign({}, state, {});
|
||||||
case actiontypes_tournamentinfo.MODIFY_TOURNAMENT_ERROR:
|
case actionTypesTournamentinfo.MODIFY_TOURNAMENT_ERROR:
|
||||||
|
|
||||||
return Object.assign({}, state, {});
|
return Object.assign({}, state, {});
|
||||||
case actiontypes_tournamentinfo.REHYDRATE:
|
case actionTypesTournamentinfo.REHYDRATE:
|
||||||
|
|
||||||
return Object.assign({}, state, {});
|
return Object.assign({}, state, {});
|
||||||
case actiontypes_tournamentinfo.CLEAR:
|
case actionTypesTournamentinfo.CLEAR:
|
||||||
|
|
||||||
return Object.assign({}, state, {});
|
return Object.assign({}, state, {});
|
||||||
default: return state;
|
default: return state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const reducer_tournamentlist = (state = defaultstate_tournamentlist, action) => {
|
const reducerTournamentlist = (state = defaultStateTournamentlist, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case actiontypes_tournamentlist.FETCH:
|
case actionTypesTournamentlist.FETCH:
|
||||||
getRequest(action.state, '/tournaments?type=' + action.parameters.type).then((resp) => {
|
getRequest(action.state, '/tournaments?type=' + action.parameters.type).then(resp => {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type: actiontypes_tournamentlist.FETCH_SUCCESS,
|
type: actionTypesTournamentlist.FETCH_SUCCESS,
|
||||||
parameters: resp.data
|
parameters: resp.data
|
||||||
});
|
});
|
||||||
storeOptionalToken(resp);
|
storeOptionalToken(resp);
|
||||||
action.parameters.successCallback(resp.data);
|
action.parameters.successCallback(resp.data);
|
||||||
}).catch((error) => {
|
}).catch(error => {
|
||||||
if(error.response) {
|
if (error.response) {
|
||||||
storeOptionalToken(error.response);
|
storeOptionalToken(error.response);
|
||||||
}
|
}
|
||||||
action.parameters.errorCallback();
|
action.parameters.errorCallback();
|
||||||
});
|
});
|
||||||
return state;
|
return state;
|
||||||
case actiontypes_tournamentlist.FETCH_SUCCESS:
|
case actionTypesTournamentlist.FETCH_SUCCESS:
|
||||||
return Object.assign({}, state, {tournaments: action.parameters});
|
return Object.assign({}, state, {tournaments: action.parameters});
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
|
@ -363,28 +363,28 @@ const reducer_tournamentlist = (state = defaultstate_tournamentlist, action) =>
|
||||||
};
|
};
|
||||||
|
|
||||||
const reducers = {
|
const reducers = {
|
||||||
userinfo: reducer_userinfo,
|
userinfo: reducerUserinfo,
|
||||||
tournamentinfo: reducer_tournamentinfo,
|
tournamentinfo: reducerTournamentinfo,
|
||||||
tournamentlist: reducer_tournamentlist
|
tournamentlist: reducerTournamentlist
|
||||||
};
|
};
|
||||||
|
|
||||||
const default_applicationstate = {
|
const defaultApplicationState = {
|
||||||
userinfo : defaultstate_userinfo,
|
userinfo: defaultStateUserinfo,
|
||||||
tournamentinfo: defaultstate_tournamentinfo,
|
tournamentinfo: defaultStateTournamentinfo,
|
||||||
tournamentlist: defaultstate_tournamentlist
|
tournamentlist: defaultStateTournamentlist
|
||||||
};
|
};
|
||||||
|
|
||||||
var __store;
|
let __store;
|
||||||
var applicationHydrated = false;
|
let applicationHydrated = false;
|
||||||
|
|
||||||
export function initializeStore(initialState = default_applicationstate) {
|
export function initializeStore(initialState = defaultApplicationState) {
|
||||||
__store = createStore(
|
__store = createStore(
|
||||||
combineReducers(reducers),
|
combineReducers(reducers),
|
||||||
initialState,
|
initialState,
|
||||||
composeWithDevTools(applyMiddleware(thunkMiddleware))
|
composeWithDevTools(applyMiddleware(thunkMiddleware))
|
||||||
);
|
);
|
||||||
__store.subscribe(() => {
|
__store.subscribe(() => {
|
||||||
if(applicationHydrated) {
|
if (applicationHydrated) {
|
||||||
localStorage.setItem('reduxState', JSON.stringify(__store.getState()));
|
localStorage.setItem('reduxState', JSON.stringify(__store.getState()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -394,9 +394,9 @@ export function initializeStore(initialState = default_applicationstate) {
|
||||||
export function verifyCredentials() {
|
export function verifyCredentials() {
|
||||||
rehydrateApplicationState();
|
rehydrateApplicationState();
|
||||||
|
|
||||||
if(__store.getState().userinfo.isSignedIn) {
|
if (__store.getState().userinfo.isSignedIn) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type: actiontypes_userinfo.VERIFY_CREDENTIALS,
|
type: actionTypesUserinfo.VERIFY_CREDENTIALS,
|
||||||
state: __store.getState()
|
state: __store.getState()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -404,7 +404,7 @@ export function verifyCredentials() {
|
||||||
|
|
||||||
export function register(username, email, password) {
|
export function register(username, email, password) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type: actiontypes_userinfo.REGISTER,
|
type: actionTypesUserinfo.REGISTER,
|
||||||
parameters: {
|
parameters: {
|
||||||
username: username,
|
username: username,
|
||||||
email: email,
|
email: email,
|
||||||
|
|
@ -416,7 +416,7 @@ export function register(username, email, password) {
|
||||||
|
|
||||||
export function login(email, password, successCallback) {
|
export function login(email, password, successCallback) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type: actiontypes_userinfo.LOGIN,
|
type: actionTypesUserinfo.LOGIN,
|
||||||
parameters: {
|
parameters: {
|
||||||
email: email,
|
email: email,
|
||||||
password: password,
|
password: password,
|
||||||
|
|
@ -428,7 +428,7 @@ export function login(email, password, successCallback) {
|
||||||
|
|
||||||
export function logout(successCallback) {
|
export function logout(successCallback) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type : actiontypes_userinfo.LOGOUT,
|
type: actionTypesUserinfo.LOGOUT,
|
||||||
parameters: {
|
parameters: {
|
||||||
successCallback: successCallback
|
successCallback: successCallback
|
||||||
},
|
},
|
||||||
|
|
@ -438,7 +438,7 @@ export function logout(successCallback) {
|
||||||
|
|
||||||
export function createTournament(data, successCallback, errorCallback) {
|
export function createTournament(data, successCallback, errorCallback) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type: actiontypes_tournamentinfo.CREATE_TOURNAMENT,
|
type: actionTypesTournamentinfo.CREATE_TOURNAMENT,
|
||||||
parameters: {
|
parameters: {
|
||||||
tournament: data,
|
tournament: data,
|
||||||
successCallback: successCallback,
|
successCallback: successCallback,
|
||||||
|
|
@ -450,7 +450,7 @@ export function createTournament(data, successCallback, errorCallback) {
|
||||||
|
|
||||||
export function requestTournament(code, successCallback, errorCallback) {
|
export function requestTournament(code, successCallback, errorCallback) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type: actiontypes_tournamentinfo.REQUEST_TOURNAMENT,
|
type: actionTypesTournamentinfo.REQUEST_TOURNAMENT,
|
||||||
parameters: {
|
parameters: {
|
||||||
code: code,
|
code: code,
|
||||||
successCallback: successCallback,
|
successCallback: successCallback,
|
||||||
|
|
@ -462,12 +462,12 @@ export function requestTournament(code, successCallback, errorCallback) {
|
||||||
|
|
||||||
export function updateTeamName(team, successCB, errorCB) {
|
export function updateTeamName(team, successCB, errorCB) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type: actiontypes_tournamentinfo.MODIFY_TOURNAMENT,
|
type: actionTypesTournamentinfo.MODIFY_TOURNAMENT,
|
||||||
parameters: {
|
parameters: {
|
||||||
teamid: team.id,
|
teamid: team.id,
|
||||||
name: team.name,
|
name: team.name,
|
||||||
onSuccess : successCB,
|
onSuccess: successCB,
|
||||||
onError : errorCB
|
onError: errorCB
|
||||||
},
|
},
|
||||||
state: __store.getState()
|
state: __store.getState()
|
||||||
});
|
});
|
||||||
|
|
@ -479,7 +479,7 @@ export function getState() {
|
||||||
|
|
||||||
export function requestTournamentList(type, successCallback, errorCallback) {
|
export function requestTournamentList(type, successCallback, errorCallback) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type: actiontypes_tournamentlist.FETCH,
|
type: actionTypesTournamentlist.FETCH,
|
||||||
parameters: {
|
parameters: {
|
||||||
type: type,
|
type: type,
|
||||||
successCallback: successCallback,
|
successCallback: successCallback,
|
||||||
|
|
@ -494,18 +494,18 @@ function rehydrateApplicationState() {
|
||||||
JSON.parse(localStorage.getItem('reduxState')) :
|
JSON.parse(localStorage.getItem('reduxState')) :
|
||||||
undefined;
|
undefined;
|
||||||
|
|
||||||
if(persistedState) {
|
if (persistedState) {
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type : actiontypes_userinfo.REHYDRATE,
|
type: actionTypesUserinfo.REHYDRATE,
|
||||||
parameters : Object.assign({}, persistedState.userinfo)
|
parameters: Object.assign({}, persistedState.userinfo)
|
||||||
});
|
});
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type : actiontypes_tournamentinfo.REHYDRATE,
|
type: actionTypesTournamentinfo.REHYDRATE,
|
||||||
parameters : Object.assign({}, persistedState.tournamentinfo)
|
parameters: Object.assign({}, persistedState.tournamentinfo)
|
||||||
});
|
});
|
||||||
__store.dispatch({
|
__store.dispatch({
|
||||||
type : actiontypes_tournamentlist.REHYDRATE,
|
type: actionTypesTournamentlist.REHYDRATE,
|
||||||
parameters : Object.assign({}, persistedState.tournamentlist)
|
parameters: Object.assign({}, persistedState.tournamentlist)
|
||||||
});
|
});
|
||||||
applicationHydrated = true;
|
applicationHydrated = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,15 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import {
|
||||||
Alert,
|
Alert, Button, Card, CardBody, CardTitle, Input, InputGroup, InputGroupAddon
|
||||||
Button,
|
|
||||||
Card,
|
|
||||||
CardBody,
|
|
||||||
CardTitle,
|
|
||||||
Input,
|
|
||||||
InputGroup,
|
|
||||||
InputGroupAddon
|
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
|
|
||||||
import '../../static/css/editablestringlist.css';
|
import '../../static/css/editablestringlist.css';
|
||||||
|
|
||||||
export default class EditableStringList extends React.Component {
|
export default class EditableStringList extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
groupSize: props.groupSize,
|
groupSize: props.groupSize, teams: props.teams, groups: props.groups
|
||||||
teams: props.teams,
|
|
||||||
groups: props.groups
|
|
||||||
};
|
};
|
||||||
this.add = this.add.bind(this);
|
this.add = this.add.bind(this);
|
||||||
this.remove = this.remove.bind(this);
|
this.remove = this.remove.bind(this);
|
||||||
|
|
@ -32,16 +22,15 @@ export default class EditableStringList extends React.Component {
|
||||||
}
|
}
|
||||||
this.state.teams.push(text);
|
this.state.teams.push(text);
|
||||||
|
|
||||||
var lastGroup = this.state.groups[this.state.groups.length - 1];
|
let lastGroup = this.state.groups[this.state.groups.length - 1];
|
||||||
if(lastGroup === undefined || lastGroup.length >= this.state.groupSize) {
|
if (lastGroup === undefined || lastGroup.length >= this.state.groupSize) {
|
||||||
this.state.groups[this.state.groups.length] = [];
|
this.state.groups[this.state.groups.length] = [];
|
||||||
}
|
}
|
||||||
lastGroup = this.state.groups[this.state.groups.length - 1];
|
lastGroup = this.state.groups[this.state.groups.length - 1];
|
||||||
lastGroup[lastGroup.length] = text;
|
lastGroup[lastGroup.length] = text;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
teams: this.state.teams,
|
teams: this.state.teams, groups: this.state.groups
|
||||||
groups: this.state.groups
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.props.onTeamsChange(this.state.teams);
|
this.props.onTeamsChange(this.state.teams);
|
||||||
|
|
@ -51,13 +40,12 @@ export default class EditableStringList extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
remove(text) {
|
remove(text) {
|
||||||
if(this.removeTeamFromGroup(text) === false) {
|
if (this.removeTeamFromGroup(text) === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
teams: this.state.teams,
|
teams: this.state.teams, groups: this.state.groups
|
||||||
groups: this.state.groups
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.props.onTeamsChange(this.state.teams);
|
this.props.onTeamsChange(this.state.teams);
|
||||||
|
|
@ -67,20 +55,20 @@ export default class EditableStringList extends React.Component {
|
||||||
removeTeamFromGroup(text) {
|
removeTeamFromGroup(text) {
|
||||||
this.state.teams = this.state.teams.filter(item => item !== text);
|
this.state.teams = this.state.teams.filter(item => item !== text);
|
||||||
|
|
||||||
let teamIndex = this.findTeam(text);
|
const teamIndex = this.findTeam(text);
|
||||||
if(teamIndex === null) {
|
if (teamIndex === null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move every first team to the next group
|
// Move every first team to the next group
|
||||||
this.state.groups[teamIndex.group].splice(teamIndex.team, 1);
|
this.state.groups[teamIndex.group].splice(teamIndex.team, 1);
|
||||||
for(var group = teamIndex.group; group < this.state.groups.length - 1; group++) {
|
for (let group = teamIndex.group; group < this.state.groups.length - 1; group++) {
|
||||||
let currentGroup = this.state.groups[group];
|
const currentGroup = this.state.groups[group];
|
||||||
currentGroup[currentGroup.length] = this.state.groups[group + 1].splice(0, 1)[0];
|
currentGroup[currentGroup.length] = this.state.groups[group + 1].splice(0, 1)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete the last group in case it is empty
|
// delete the last group in case it is empty
|
||||||
if(this.state.groups[this.state.groups.length - 1].length === 0) {
|
if (this.state.groups[this.state.groups.length - 1].length === 0) {
|
||||||
this.state.groups.splice(this.state.groups.length - 1, 1);
|
this.state.groups.splice(this.state.groups.length - 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,12 +76,11 @@ export default class EditableStringList extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
findTeam(text) {
|
findTeam(text) {
|
||||||
for(var group = 0; group < this.state.groups.length; group++) {
|
for (let group = 0; group < this.state.groups.length; group++) {
|
||||||
for(var team = 0; team < this.state.groups[group].length; team++) {
|
for (let team = 0; team < this.state.groups[group].length; team++) {
|
||||||
if(this.state.groups[group][team] === text) {
|
if (this.state.groups[group][team] === text) {
|
||||||
return {
|
return {
|
||||||
group: group,
|
group: group, team: team
|
||||||
team: team
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -102,17 +89,17 @@ export default class EditableStringList extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
resizeGroups(newSize) {
|
resizeGroups(newSize) {
|
||||||
let oldGroups = this.state.groups;
|
const oldGroups = this.state.groups;
|
||||||
var rearrangedGroups = [];
|
const rearrangedGroups = [];
|
||||||
|
|
||||||
for(var oldGroupIndex = 0; oldGroupIndex < oldGroups.length; oldGroupIndex++) {
|
for (let oldGroupIndex = 0; oldGroupIndex < oldGroups.length; oldGroupIndex++) {
|
||||||
for(var oldTeamIndex = 0; oldTeamIndex < oldGroups[oldGroupIndex].length; oldTeamIndex++) {
|
for (let oldTeamIndex = 0; oldTeamIndex < oldGroups[oldGroupIndex].length; oldTeamIndex++) {
|
||||||
let index = oldGroupIndex * this.state.groupSize + oldTeamIndex;
|
const index = oldGroupIndex * this.state.groupSize + oldTeamIndex;
|
||||||
|
|
||||||
let newGroupIndex = Math.floor(index / newSize);
|
const newGroupIndex = Math.floor(index / newSize);
|
||||||
let newTeamIndex = index % newSize;
|
const newTeamIndex = index % newSize;
|
||||||
|
|
||||||
if(newTeamIndex === 0) {
|
if (newTeamIndex === 0) {
|
||||||
rearrangedGroups[newGroupIndex] = [];
|
rearrangedGroups[newGroupIndex] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -121,8 +108,7 @@ export default class EditableStringList extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
groupSize: newSize,
|
groupSize: newSize, groups: rearrangedGroups
|
||||||
groups: rearrangedGroups
|
|
||||||
});
|
});
|
||||||
this.props.onGroupsChange(this.state.groups);
|
this.props.onGroupsChange(this.state.groups);
|
||||||
}
|
}
|
||||||
|
|
@ -143,85 +129,71 @@ export default class EditableStringList extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if(this.props.groupSize !== this.state.groupSize) {
|
if (this.props.groupSize !== this.state.groupSize) {
|
||||||
this.resizeGroups(this.props.groupSize);
|
this.resizeGroups(this.props.groupSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.props.groupPhaseEnabled) {
|
if (this.props.groupPhaseEnabled) {
|
||||||
if ((typeof this.state.teams !== 'undefined') && this.state.teams.length > 0) {
|
if ((typeof this.state.teams !== 'undefined') && this.state.teams.length > 0) {
|
||||||
return (
|
return (<div className="bg-light p-3 text-secondary font-italic">
|
||||||
<div className="bg-light p-3 text-secondary font-italic">
|
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder}
|
||||||
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder} addButtonText={this.props.addButtonText}/>
|
addButtonText={this.props.addButtonText}/>
|
||||||
<GroupView groups={this.state.groups} removeTeam={this.remove} onGroupSwitched={this.onGroupSwitch}/>
|
<GroupView groups={this.state.groups} removeTeam={this.remove}
|
||||||
</div>
|
onGroupSwitched={this.onGroupSwitch}/>
|
||||||
);
|
</div>);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (<div className="bg-light p-3 text-secondary text-center font-italic">
|
||||||
<div className="bg-light p-3 text-secondary text-center font-italic">
|
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder}
|
||||||
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder} addButtonText={this.props.addButtonText}/>
|
addButtonText={this.props.addButtonText}/>
|
||||||
{this.props.groupPlaceHolder}
|
{this.props.groupPlaceHolder}
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((typeof this.state.teams !== 'undefined') && this.state.teams.length > 0) {
|
if ((typeof this.state.teams !== 'undefined') && this.state.teams.length > 0) {
|
||||||
return (
|
return (<div className="bg-light p-3 text-secondary font-italic">
|
||||||
<div className="bg-light p-3 text-secondary font-italic">
|
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder}
|
||||||
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder} addButtonText={this.props.addButtonText}/>
|
addButtonText={this.props.addButtonText}/>
|
||||||
{this.state.teams.map((text) => <Item text={text} key={text} removeItem={this.remove}/>)}
|
{this.state.teams.map(text => <Item text={text} key={text} removeItem={this.remove}/>)}
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (<div className="bg-light p-3 text-secondary text-center font-italic">
|
||||||
<div className="bg-light p-3 text-secondary text-center font-italic">
|
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder}
|
||||||
<StringInput submit={this.add} placeholder={this.props.inputPlaceholder} addButtonText={this.props.addButtonText}/>
|
addButtonText={this.props.addButtonText}/>
|
||||||
{this.props.teamPlaceholder}
|
{this.props.teamPlaceholder}
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GroupView extends React.Component {
|
class GroupView extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<div>
|
||||||
<div>
|
{this.props.groups.map((group, groupindex) => (<Card className="group-card" key={groupindex}>
|
||||||
{this.props.groups.map((group, groupindex) => (
|
|
||||||
<Card className="group-card" key={groupindex}>
|
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<CardTitle>Group {groupindex + 1}</CardTitle>
|
<CardTitle>Group {groupindex + 1}</CardTitle>
|
||||||
{group.map((team, teamindex) => (
|
{group.map((team, teamindex) => (<div key={team} draggable droppable="droppable"
|
||||||
<div key={team} draggable droppable="droppable"
|
|
||||||
className="grouped-team-item"
|
className="grouped-team-item"
|
||||||
onDragStart={(e) => this.onDragStart(e, groupindex,teamindex)}
|
onDragStart={e => this.onDragStart(e, groupindex, teamindex)}
|
||||||
onDragOver={(e) => this.onDragOver(e)}
|
onDragOver={e => this.onDragOver(e)}
|
||||||
onDrop={(e) => this.onDrop(e, groupindex, teamindex)}>
|
onDrop={e => this.onDrop(e, groupindex, teamindex)}>
|
||||||
|
|
||||||
<Item text={team} removeItem={this.props.removeTeam}/>
|
<Item text={team} removeItem={this.props.removeTeam}/>
|
||||||
|
|
||||||
</div>
|
</div>))}
|
||||||
))}
|
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>))}
|
||||||
))}
|
</div>);
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDragStart(e, group, team) {
|
onDragStart(e, group, team) {
|
||||||
e.dataTransfer.setData(
|
e.dataTransfer.setData('text/plain', JSON.stringify({
|
||||||
'text/plain',
|
group: group, team: team
|
||||||
JSON.stringify({
|
}));
|
||||||
group: group,
|
|
||||||
team: team
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDragOver(e) {
|
onDragOver(e) {
|
||||||
|
|
@ -231,10 +203,9 @@ class GroupView extends React.Component {
|
||||||
onDrop(e, group, team) {
|
onDrop(e, group, team) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
let src = JSON.parse(e.dataTransfer.getData('text'));
|
const src = JSON.parse(e.dataTransfer.getData('text'));
|
||||||
let dest = {
|
const dest = {
|
||||||
group: group,
|
group: group, team: team
|
||||||
team: team
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.props.onGroupSwitched(src, dest);
|
this.props.onGroupSwitched(src, dest);
|
||||||
|
|
@ -254,9 +225,9 @@ class StringInput extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<InputGroup className="mb-3">
|
||||||
<InputGroup className="mb-3">
|
<Input placeholder={this.props.placeholder} type="text" size="255" value={this.state.value} required
|
||||||
<Input placeholder={this.props.placeholder} type="text" size="255" value={this.state.value} required onChange={this.handleChange} onKeyPress={(e) => {
|
onChange={this.handleChange} onKeyPress={e => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
this.submit();
|
this.submit();
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -266,8 +237,7 @@ class StringInput extends React.Component {
|
||||||
<Button color="success" outline={true}
|
<Button color="success" outline={true}
|
||||||
onClick={() => this.submit()}>{this.props.addButtonText}</Button>
|
onClick={() => this.submit()}>{this.props.addButtonText}</Button>
|
||||||
</InputGroupAddon>
|
</InputGroupAddon>
|
||||||
</InputGroup>
|
</InputGroup>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
submit() {
|
submit() {
|
||||||
|
|
@ -292,10 +262,8 @@ class Item extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<Alert className="team-item m-2" color="info" isOpen={this.state.visible} toggle={this.onDismiss}>
|
||||||
<Alert className="team-item m-2" color="info" isOpen={this.state.visible} toggle={this.onDismiss}>
|
|
||||||
{this.props.text}
|
{this.props.text}
|
||||||
</Alert>
|
</Alert>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Container } from 'reactstrap';
|
import {Container} from 'reactstrap';
|
||||||
|
|
||||||
import { TurniereNavigation } from './Navigation';
|
import {TurniereNavigation} from './Navigation';
|
||||||
import { Footer } from './Footer';
|
import {Footer} from './Footer';
|
||||||
|
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
||||||
|
|
@ -11,9 +11,8 @@ import '../../static/everypage.css';
|
||||||
import '../../static/css/error.css';
|
import '../../static/css/error.css';
|
||||||
|
|
||||||
export class ErrorPageComponent extends React.Component {
|
export class ErrorPageComponent extends React.Component {
|
||||||
|
static getInitialProps({statusCode}) {
|
||||||
static getInitialProps({ statusCode }) {
|
return {statusCode};
|
||||||
return { statusCode };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
@ -30,7 +29,7 @@ export class ErrorPageComponent extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ErrorPage(props){
|
export function ErrorPage(props) {
|
||||||
return (
|
return (
|
||||||
<Container className="mb-5">
|
<Container className="mb-5">
|
||||||
<div className="row mb-5">
|
<div className="row mb-5">
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,13 @@ import React from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import Router from 'next/router';
|
import Router from 'next/router';
|
||||||
|
|
||||||
import { login } from '../api';
|
import {login} from '../api';
|
||||||
|
|
||||||
import '../../static/css/errormessages.css';
|
import '../../static/css/errormessages.css';
|
||||||
import {notify} from 'react-notify-toast';
|
import {notify} from 'react-notify-toast';
|
||||||
|
|
||||||
export function Login(props) {
|
export function Login(props) {
|
||||||
return (
|
return (<Container className="py-5">
|
||||||
<Container className="py-5">
|
|
||||||
<Card className="shadow">
|
<Card className="shadow">
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<h1 className="custom-font">Login</h1>
|
<h1 className="custom-font">Login</h1>
|
||||||
|
|
@ -22,38 +21,30 @@ export function Login(props) {
|
||||||
</div>
|
</div>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
</Container>
|
</Container>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class LoginErrorList extends React.Component {
|
class LoginErrorList extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const { error, errorMessages } = this.props;
|
const {error, errorMessages} = this.props;
|
||||||
if(error) {
|
if (error) {
|
||||||
return (
|
return (<ul className='mt-3 error-box'>
|
||||||
<ul className='mt-3 error-box'>
|
{errorMessages.map((message, index) => <li key={index}>
|
||||||
{ errorMessages.map((message, index) =>
|
|
||||||
<li key={index}>
|
|
||||||
{message}
|
{message}
|
||||||
</li>
|
</li>)}
|
||||||
|
</ul>);
|
||||||
) }
|
|
||||||
</ul>
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToErrorMessages = (state) => {
|
const mapStateToErrorMessages = state => {
|
||||||
const { errorMessages, error } = state.userinfo;
|
const {errorMessages, error} = state.userinfo;
|
||||||
return { errorMessages, error };
|
return {errorMessages, error};
|
||||||
};
|
};
|
||||||
|
|
||||||
const VisibleLoginErrorList = connect(
|
const VisibleLoginErrorList = connect(mapStateToErrorMessages)(LoginErrorList);
|
||||||
mapStateToErrorMessages
|
|
||||||
)(LoginErrorList);
|
|
||||||
|
|
||||||
class LoginSuccessRedirectComponent extends React.Component {
|
class LoginSuccessRedirectComponent extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
|
|
@ -64,7 +55,7 @@ class LoginSuccessRedirectComponent extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapLoginState = (state) => {
|
const mapLoginState = state => {
|
||||||
const {isSignedIn} = state.userinfo;
|
const {isSignedIn} = state.userinfo;
|
||||||
return {isSignedIn};
|
return {isSignedIn};
|
||||||
};
|
};
|
||||||
|
|
@ -72,53 +63,50 @@ const mapLoginState = (state) => {
|
||||||
const LoginSuccessRedirect = connect(mapLoginState)(LoginSuccessRedirectComponent);
|
const LoginSuccessRedirect = connect(mapLoginState)(LoginSuccessRedirectComponent);
|
||||||
|
|
||||||
class LoginForm extends React.Component {
|
class LoginForm extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
email : '',
|
email: '', password: ''
|
||||||
password : ''
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
tryLogin(event) {
|
tryLogin(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
login(this.state.email, this.state.password, (username) => notify.show('Willkommen, ' + username + '!', 'success', 2500));
|
login(this.state.email, this.state.password,
|
||||||
|
username => notify.show('Willkommen, ' + username + '!', 'success', 2500));
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<Form onSubmit={this.tryLogin.bind(this)}>
|
||||||
<Form onSubmit={this.tryLogin.bind(this)}>
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="username">E-Mail-Adresse</Label>
|
<Label for="username">E-Mail-Adresse</Label>
|
||||||
<Input type="email" name="username" value={this.state.email} onChange={ this.handleEmailInput.bind(this) } />
|
<Input type="email" name="username" value={this.state.email}
|
||||||
|
onChange={this.handleEmailInput.bind(this)}/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="password">Passwort</Label>
|
<Label for="password">Passwort</Label>
|
||||||
<Input type="password" name="password" value={this.state.password} onChange={ this.handlePasswordInput.bind(this) } />
|
<Input type="password" name="password" value={this.state.password}
|
||||||
|
onChange={this.handlePasswordInput.bind(this)}/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<input type="submit" className="btn btn-lg btn-success w-100 shadow-sm" value="Anmelden"/>
|
<input type="submit" className="btn btn-lg btn-success w-100 shadow-sm" value="Anmelden"/>
|
||||||
<VisibleLoginErrorList/>
|
<VisibleLoginErrorList/>
|
||||||
<LoginSuccessRedirect/>
|
<LoginSuccessRedirect/>
|
||||||
</Form>
|
</Form>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePasswordInput(input) {
|
handlePasswordInput(input) {
|
||||||
this.setState({ password : input.target.value });
|
this.setState({password: input.target.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEmailInput(input) {
|
handleEmailInput(input) {
|
||||||
this.setState({ email : input.target.value });
|
this.setState({email: input.target.value});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Hint(props) {
|
function Hint(props) {
|
||||||
if(props.hint != null) {
|
if (props.hint != null) {
|
||||||
return (
|
return (<h3>{props.hint}</h3>);
|
||||||
<h3>{ props.hint }</h3>
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,13 @@
|
||||||
import {
|
import {
|
||||||
Badge,
|
Badge, Button, ButtonGroup, Collapse, Nav, Navbar, NavbarBrand, NavbarToggler, NavItem, NavLink
|
||||||
Button,
|
|
||||||
ButtonGroup,
|
|
||||||
Collapse,
|
|
||||||
Nav,
|
|
||||||
Navbar,
|
|
||||||
NavbarBrand,
|
|
||||||
NavbarToggler,
|
|
||||||
NavItem,
|
|
||||||
NavLink
|
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
import { connect } from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { logout } from '../api';
|
import {logout} from '../api';
|
||||||
import {notify} from 'react-notify-toast';
|
import {notify} from 'react-notify-toast';
|
||||||
|
|
||||||
export class TurniereNavigation extends React.Component {
|
export class TurniereNavigation extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
|
@ -35,30 +25,25 @@ export class TurniereNavigation extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<Navbar color="light" light expand="lg">
|
||||||
<Navbar color="light" light expand="lg">
|
|
||||||
<NavbarBrand href="/">turnie.re</NavbarBrand>
|
<NavbarBrand href="/">turnie.re</NavbarBrand>
|
||||||
<Betabadge/>
|
<Betabadge/>
|
||||||
<NavbarToggler onClick={this.toggle} />
|
<NavbarToggler onClick={this.toggle}/>
|
||||||
<Collapse isOpen={!this.state.collapsed} navbar>
|
<Collapse isOpen={!this.state.collapsed} navbar>
|
||||||
<NavLinks/>
|
<NavLinks/>
|
||||||
<LoginLogoutButtons/>
|
<LoginLogoutButtons/>
|
||||||
</Collapse>
|
</Collapse>
|
||||||
</Navbar>
|
</Navbar>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Navlink(props) {
|
function Navlink(props) {
|
||||||
return (
|
return (<NavItem active={true}>
|
||||||
<NavItem active={true}>
|
|
||||||
<NavLink href={props.target}>{props.text}</NavLink>
|
<NavLink href={props.target}>{props.text}</NavLink>
|
||||||
</NavItem>
|
</NavItem>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class SmartNavLinks extends React.Component {
|
class SmartNavLinks extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (<Nav navbar className="mr-auto">
|
return (<Nav navbar className="mr-auto">
|
||||||
<Navlink target="/create" text="Turnier erstellen"/>
|
<Navlink target="/create" text="Turnier erstellen"/>
|
||||||
|
|
@ -74,41 +59,36 @@ function Betabadge() {
|
||||||
}
|
}
|
||||||
|
|
||||||
class InvisibleLoginLogoutButtons extends React.Component {
|
class InvisibleLoginLogoutButtons extends React.Component {
|
||||||
|
logout() {
|
||||||
logout(){
|
|
||||||
logout(() => notify.show('Du bist jetzt abgemeldet.', 'success', 2500));
|
logout(() => notify.show('Du bist jetzt abgemeldet.', 'success', 2500));
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isSignedIn, username } = this.props;
|
const {isSignedIn, username} = this.props;
|
||||||
|
|
||||||
if(isSignedIn) {
|
if (isSignedIn) {
|
||||||
return (
|
return (<ButtonGroup className="nav-item">
|
||||||
<ButtonGroup className="nav-item">
|
<Button outline color="success" href="/profile"
|
||||||
<Button outline color="success" href="/profile" className="navbar-btn my-2 my-sm-0 px-5">{ username }</Button>
|
className="navbar-btn my-2 my-sm-0 px-5">{username}</Button>
|
||||||
<Button outline color="success" onClick={this.logout.bind(this)} className="navbar-btn my-2 my-sm-0 px-5">Logout</Button>
|
<Button outline color="success" onClick={this.logout.bind(this)}
|
||||||
</ButtonGroup>
|
className="navbar-btn my-2 my-sm-0 px-5">Logout</Button>
|
||||||
);
|
</ButtonGroup>);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (<ButtonGroup className="nav-item">
|
||||||
<ButtonGroup className="nav-item">
|
<Button outline color="success" href="/login"
|
||||||
<Button outline color="success" href="/login" className="navbar-btn my-2 my-sm-0 px-5">Login</Button>
|
className="navbar-btn my-2 my-sm-0 px-5">Login</Button>
|
||||||
<Button outline color="success" href="/register" className="navbar-btn my-2 my-sm-0 px-5">Registrieren</Button>
|
<Button outline color="success" href="/register"
|
||||||
</ButtonGroup>
|
className="navbar-btn my-2 my-sm-0 px-5">Registrieren</Button>
|
||||||
);
|
</ButtonGroup>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToUserinfo = (state) => {
|
const mapStateToUserinfo = state => {
|
||||||
const { isSignedIn, username } = state.userinfo;
|
const {isSignedIn, username} = state.userinfo;
|
||||||
return { isSignedIn, username };
|
return {isSignedIn, username};
|
||||||
};
|
};
|
||||||
|
|
||||||
const LoginLogoutButtons = connect(
|
const LoginLogoutButtons = connect(mapStateToUserinfo)(InvisibleLoginLogoutButtons);
|
||||||
mapStateToUserinfo
|
|
||||||
)(InvisibleLoginLogoutButtons);
|
|
||||||
|
|
||||||
const NavLinks = connect(
|
const NavLinks = connect(mapStateToUserinfo)(SmartNavLinks);
|
||||||
mapStateToUserinfo
|
|
||||||
)(SmartNavLinks);
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ export default class TournamentList extends React.Component {
|
||||||
Turniere vorhanden</p>;
|
Turniere vorhanden</p>;
|
||||||
} else {
|
} else {
|
||||||
return this.state.tournaments.map(item => (
|
return this.state.tournaments.map(item => (
|
||||||
//The code should be item.code but the api just supports it this way by now
|
// The code should be item.code but the api just supports it this way by now
|
||||||
<TournamentListEntry name={item.name} code={item.id} key={item.id}/>
|
<TournamentListEntry name={item.name} code={item.id} key={item.id}/>
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,15 +30,12 @@ import React from 'react';
|
||||||
* since it would always be taken otherwise (the options' conditions are checked from top to bottom)
|
* since it would always be taken otherwise (the options' conditions are checked from top to bottom)
|
||||||
*/
|
*/
|
||||||
export class UserRestrictor extends React.Component {
|
export class UserRestrictor extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { children } = this.props;
|
const {children} = this.props;
|
||||||
|
|
||||||
for(var i in children) {
|
for (const child of children) {
|
||||||
var c = children[i];
|
if (child.props.condition) {
|
||||||
|
return child;
|
||||||
if(c.props.condition) {
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
|
|
||||||
|
|
||||||
export const errorMessages = {
|
export const errorMessages = {
|
||||||
registration_errorunknown : {
|
registration_errorunknown: {
|
||||||
en : 'An unknown error prevented a successful registration.'
|
en: 'An unknown error prevented a successful registration.'
|
||||||
},
|
},
|
||||||
login_errorunknown : {
|
login_errorunknown: {
|
||||||
en : 'An unknown error prevented a successful login.'
|
en: 'An unknown error prevented a successful login.'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { initializeStore } from '../api';
|
import {initializeStore} from '../api';
|
||||||
|
|
||||||
const isServer = typeof window === 'undefined';
|
const isServer = typeof window === 'undefined';
|
||||||
const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__';
|
const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__';
|
||||||
|
|
||||||
function getOrCreateStore (initialState) {
|
function getOrCreateStore(initialState) {
|
||||||
// Always make a new store if server, otherwise state is shared between requests
|
// Always make a new store if server, otherwise state is shared between requests
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
return initializeStore(initialState);
|
return initializeStore(initialState);
|
||||||
|
|
@ -17,9 +17,9 @@ function getOrCreateStore (initialState) {
|
||||||
return window[__NEXT_REDUX_STORE__];
|
return window[__NEXT_REDUX_STORE__];
|
||||||
}
|
}
|
||||||
|
|
||||||
export default (App) => {
|
export default App => {
|
||||||
return class AppWithRedux extends React.Component {
|
return class AppWithRedux extends React.Component {
|
||||||
static async getInitialProps (appContext) {
|
static async getInitialProps(appContext) {
|
||||||
// Get or Create the store with `undefined` as initialState
|
// Get or Create the store with `undefined` as initialState
|
||||||
// This allows you to set a custom default initialState
|
// This allows you to set a custom default initialState
|
||||||
const reduxStore = getOrCreateStore();
|
const reduxStore = getOrCreateStore();
|
||||||
|
|
@ -38,12 +38,12 @@ export default (App) => {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor (props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.reduxStore = getOrCreateStore(props.initialReduxState);
|
this.reduxStore = getOrCreateStore(props.initialReduxState);
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
return <App {...this.props} reduxStore={this.reduxStore} />;
|
return <App {...this.props} reduxStore={this.reduxStore} />;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@
|
||||||
"@zeit/next-css": "^1.0.1",
|
"@zeit/next-css": "^1.0.1",
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"bootstrap": "^4.1.3",
|
"bootstrap": "^4.1.3",
|
||||||
|
"eslint-config-google": "^0.12.0",
|
||||||
"express": "^4.16.4",
|
"express": "^4.16.4",
|
||||||
"next": "^7.0.2",
|
"next": "^7.0.2",
|
||||||
"react": "^16.6.1",
|
"react": "^16.6.1",
|
||||||
|
|
@ -30,7 +31,8 @@
|
||||||
"redux-thunk": "^2.3.0"
|
"redux-thunk": "^2.3.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^5.9.0",
|
"eslint": "^5.16.0",
|
||||||
|
"eslint-config-google": "^0.12.0",
|
||||||
"eslint-plugin-react": "^7.11.1",
|
"eslint-plugin-react": "^7.11.1",
|
||||||
"react-editable-list": "0.0.3"
|
"react-editable-list": "0.0.3"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,26 @@
|
||||||
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';
|
import {verifyCredentials} from '../js/api.js';
|
||||||
|
|
||||||
class TurniereApp extends App {
|
class TurniereApp extends App {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
verifyCredentials();
|
verifyCredentials();
|
||||||
}
|
}
|
||||||
|
|
||||||
render () {
|
render() {
|
||||||
const {Component, pageProps, reduxStore} = this.props;
|
const {Component, pageProps, reduxStore} = this.props;
|
||||||
return (
|
return (<Container>
|
||||||
<Container>
|
<Notifications/>
|
||||||
<Notifications />
|
|
||||||
<Favicon url="../static/icons/favicon.ico"/>
|
<Favicon url="../static/icons/favicon.ico"/>
|
||||||
<Provider store={reduxStore}>
|
<Provider store={reduxStore}>
|
||||||
<Component {...pageProps} />
|
<Component {...pageProps} />
|
||||||
</Provider>
|
</Provider>
|
||||||
</Container>
|
</Container>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { ErrorPageComponent } from '../js/components/ErrorComponents';
|
import {ErrorPageComponent} from '../js/components/ErrorComponents';
|
||||||
import { verifyCredentials } from '../js/api';
|
import {verifyCredentials} from '../js/api';
|
||||||
|
|
||||||
export default class Error extends React.Component {
|
export default class Error extends React.Component {
|
||||||
static getInitialProps({ res, err }) {
|
static getInitialProps({res, err}) {
|
||||||
const statusCode = res ? res.statusCode : err ? err.statusCode : 400;
|
const statusCode = res ? res.statusCode : err ? err.statusCode : 400;
|
||||||
return { statusCode };
|
return {statusCode};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
|
|
@ -14,8 +14,6 @@ export default class Error extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<ErrorPageComponent statusCode={this.props.statusCode}/>);
|
||||||
<ErrorPageComponent statusCode={this.props.statusCode}/>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
124
pages/create.js
124
pages/create.js
|
|
@ -1,37 +1,27 @@
|
||||||
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 {notify} from 'react-notify-toast';
|
||||||
import { connect } from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import posed from 'react-pose';
|
import posed from 'react-pose';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Button,
|
Button, Card, CardBody, Container, CustomInput, Form, FormGroup, Input, Label
|
||||||
Card,
|
|
||||||
CardBody,
|
|
||||||
Container,
|
|
||||||
CustomInput,
|
|
||||||
Form,
|
|
||||||
FormGroup,
|
|
||||||
Input,
|
|
||||||
Label
|
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
|
|
||||||
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 { 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 EditableStringList from '../js/components/EditableStringList';
|
import EditableStringList from '../js/components/EditableStringList';
|
||||||
import { createTournament } from '../js/api';
|
import {createTournament} from '../js/api';
|
||||||
|
|
||||||
import '../static/everypage.css';
|
import '../static/everypage.css';
|
||||||
|
|
||||||
class CreatePage extends React.Component {
|
class CreatePage extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isSignedIn } = this.props;
|
const {isSignedIn} = this.props;
|
||||||
|
|
||||||
return (
|
return (<UserRestrictor>
|
||||||
<UserRestrictor>
|
|
||||||
<Option condition={isSignedIn}>
|
<Option condition={isSignedIn}>
|
||||||
<div className="main generic-fullpage-bg">
|
<div className="main generic-fullpage-bg">
|
||||||
<Head>
|
<Head>
|
||||||
|
|
@ -56,41 +46,33 @@ class CreatePage extends React.Component {
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
</Option>
|
</Option>
|
||||||
</UserRestrictor>
|
</UserRestrictor>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToCreatePageProperties(state) {
|
function mapStateToCreatePageProperties(state) {
|
||||||
const { isSignedIn } = state.userinfo;
|
const {isSignedIn} = state.userinfo;
|
||||||
return { isSignedIn };
|
return {isSignedIn};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToCreatePageProperties)(CreatePage);
|
||||||
mapStateToCreatePageProperties
|
|
||||||
)(CreatePage);
|
|
||||||
|
|
||||||
function CreateTournamentCard() {
|
function CreateTournamentCard() {
|
||||||
return (
|
return (<Container className="py-5">
|
||||||
<Container className="py-5">
|
|
||||||
<Card className="shadow">
|
<Card className="shadow">
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<h1 className="custom-font">Turnier erstellen</h1>
|
<h1 className="custom-font">Turnier erstellen</h1>
|
||||||
<CreateTournamentForm/>
|
<CreateTournamentForm/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
</Container>
|
</Container>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const GroupphaseFader = posed.div({
|
const GroupphaseFader = posed.div({
|
||||||
visible: {
|
visible: {
|
||||||
opacity: 1,
|
opacity: 1, height: 150
|
||||||
height: 150
|
}, hidden: {
|
||||||
},
|
opacity: 0, height: 0
|
||||||
hidden: {
|
|
||||||
opacity: 0,
|
|
||||||
height: 0
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -100,14 +82,9 @@ class CreateTournamentForm extends React.Component {
|
||||||
this.state = {
|
this.state = {
|
||||||
groupPhaseEnabled: false,
|
groupPhaseEnabled: false,
|
||||||
|
|
||||||
name: '',
|
name: '', description: '', public: false,
|
||||||
description: '',
|
|
||||||
public: false,
|
|
||||||
|
|
||||||
groupSize: 4,
|
groupSize: 4, groupAdvance: 1, teams: [], groups: []
|
||||||
groupAdvance: 1,
|
|
||||||
teams: [],
|
|
||||||
groups: []
|
|
||||||
};
|
};
|
||||||
this.handleGroupPhaseEnabledInput = this.handleGroupPhaseEnabledInput.bind(this);
|
this.handleGroupPhaseEnabledInput = this.handleGroupPhaseEnabledInput.bind(this);
|
||||||
this.teamListUpdate = this.teamListUpdate.bind(this);
|
this.teamListUpdate = this.teamListUpdate.bind(this);
|
||||||
|
|
@ -123,25 +100,29 @@ class CreateTournamentForm extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<div>
|
||||||
<div>
|
|
||||||
<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 value={this.state.name} onChange={this.handleNameInput}/>
|
<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" value={this.state.description} onChange={this.handleDescriptionInput}/>
|
<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)" checked={this.state.public} onChange={this.handlePublicInput}/>
|
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"
|
<CustomInput type="checkbox" id="group-phase" label="Gruppenphase"
|
||||||
checked={this.state.groupPhaseEnabled} onChange={this.handleGroupPhaseEnabledInput}/>
|
checked={this.state.groupPhaseEnabled}
|
||||||
|
onChange={this.handleGroupPhaseEnabledInput}/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<GroupphaseFader pose={this.state.groupPhaseEnabled? 'visible' : 'hidden'} className="groupphasefader">
|
<GroupphaseFader pose={this.state.groupPhaseEnabled ? 'visible' : 'hidden'}
|
||||||
|
className="groupphasefader">
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="teams-per-group">Anzahl Teams pro Gruppe</Label>
|
<Label for="teams-per-group">Anzahl Teams pro Gruppe</Label>
|
||||||
<Input type="number" name="teams-per-group" min="3"
|
<Input type="number" name="teams-per-group" min="3"
|
||||||
|
|
@ -167,9 +148,9 @@ class CreateTournamentForm extends React.Component {
|
||||||
onTeamsChange={this.teamListUpdate}
|
onTeamsChange={this.teamListUpdate}
|
||||||
onGroupsChange={this.groupListUpdate}
|
onGroupsChange={this.groupListUpdate}
|
||||||
inputPlaceholder="Teamname"/>
|
inputPlaceholder="Teamname"/>
|
||||||
<Button color="success" size="lg" className="w-100 shadow-sm mt-4" onClick={this.create}>Turnier erstellen</Button>
|
<Button color="success" size="lg" className="w-100 shadow-sm mt-4" onClick={this.create}>Turnier
|
||||||
</div>
|
erstellen</Button>
|
||||||
);
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
||||||
teamListUpdate(list) {
|
teamListUpdate(list) {
|
||||||
|
|
@ -181,35 +162,34 @@ class CreateTournamentForm extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleGroupSizeInput(input) {
|
handleGroupSizeInput(input) {
|
||||||
let newSize = input.target.value;
|
const newSize = input.target.value;
|
||||||
if(newSize <= this.state.groupAdvance) {
|
if (newSize <= this.state.groupAdvance) {
|
||||||
this.setState({
|
this.setState({
|
||||||
groupSize: newSize,
|
groupSize: newSize, groupAdvance: newSize - 1
|
||||||
groupAdvance: newSize - 1
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.setState({ groupSize: newSize });
|
this.setState({groupSize: newSize});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleGroupAdvanceInput(input) {
|
handleGroupAdvanceInput(input) {
|
||||||
this.setState({ groupAdvance: input.target.value });
|
this.setState({groupAdvance: input.target.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleGroupPhaseEnabledInput(input) {
|
handleGroupPhaseEnabledInput(input) {
|
||||||
this.setState({ groupPhaseEnabled: input.target.checked });
|
this.setState({groupPhaseEnabled: input.target.checked});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleNameInput(input) {
|
handleNameInput(input) {
|
||||||
this.setState({ name: input.target.value });
|
this.setState({name: input.target.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDescriptionInput(input) {
|
handleDescriptionInput(input) {
|
||||||
this.setState({ description: input.target.value });
|
this.setState({description: input.target.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePublicInput(input) {
|
handlePublicInput(input) {
|
||||||
this.setState({ public: input.target.checked });
|
this.setState({public: input.target.checked});
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
|
|
@ -225,7 +205,6 @@ class CreateTournamentForm extends React.Component {
|
||||||
notify.show('Das Turnier konnte nicht erstellt werden.', 'warning', 5000);
|
notify.show('Das Turnier konnte nicht erstellt werden.', 'warning', 5000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -245,20 +224,19 @@ class CreateTournamentForm extends React.Component {
|
||||||
* backend
|
* backend
|
||||||
*/
|
*/
|
||||||
function createTeamArray(groupphase, groups, teams) {
|
function createTeamArray(groupphase, groups, teams) {
|
||||||
let result = [];
|
const result = [];
|
||||||
|
|
||||||
if(groupphase) {
|
if (groupphase) {
|
||||||
for(let groupNumber = 0; groupNumber < groups.length; groupNumber++) {
|
for (let groupNumber = 0; groupNumber < groups.length; groupNumber++) {
|
||||||
for(let groupMember = 0; groupMember < groups[groupNumber].length; groupMember++) {
|
for (let groupMember = 0; groupMember < groups[groupNumber].length; groupMember++) {
|
||||||
result[result.length] = {
|
result[result.length] = {
|
||||||
'name': groups[groupNumber][groupMember],
|
'name': groups[groupNumber][groupMember], 'group': groupNumber
|
||||||
'group': groupNumber
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for(let i = 0; i < teams.length; i++) {
|
for (let i = 0; i < teams.length; i++) {
|
||||||
result[i] = { 'name': teams[i] };
|
result[i] = {'name': teams[i]};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
183
pages/faq.js
183
pages/faq.js
|
|
@ -1,18 +1,17 @@
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Col, Container, Row } from 'reactstrap';
|
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 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
||||||
import '../static/everypage.css';
|
import '../static/everypage.css';
|
||||||
|
|
||||||
function Main() {
|
function Main() {
|
||||||
return (
|
return (<div className="main">
|
||||||
<div className="main">
|
|
||||||
<Container className="pb-5">
|
<Container className="pb-5">
|
||||||
<GeneralFaq/>
|
<GeneralFaq/>
|
||||||
<hr className="mb-5"/>
|
<hr className="mb-5"/>
|
||||||
|
|
@ -20,13 +19,11 @@ function Main() {
|
||||||
<hr className="mb-5"/>
|
<hr className="mb-5"/>
|
||||||
<TournamentFaq/>
|
<TournamentFaq/>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function GeneralFaq() {
|
function GeneralFaq() {
|
||||||
return (
|
return (<div className="running-text">
|
||||||
<div className="running-text">
|
|
||||||
<h1>Allgemein</h1>
|
<h1>Allgemein</h1>
|
||||||
<Row>
|
<Row>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
|
|
@ -34,97 +31,83 @@ function GeneralFaq() {
|
||||||
<p>
|
<p>
|
||||||
turnie.re ist ein Online-Turnier­planer.</p>
|
turnie.re ist ein Online-Turnier­planer.</p>
|
||||||
<p>
|
<p>
|
||||||
Allein aus den Team-Namen berechnen wir dir einen kompletten Spielplan, den du auch gleich
|
Allein aus den Team-Namen berechnen wir dir einen kompletten Spielplan, den du auch gleich mit allen
|
||||||
mit allen Leuten teilen kannst, ohne dir Gedanken machen zu müssen, wer gegen wen spielen
|
Leuten teilen kannst, ohne dir Gedanken machen zu müssen, wer gegen wen spielen muss. Du trägst ein,
|
||||||
muss. Du trägst ein, wer gewonnen hat, und turnie.re sagt, wer als nächstes spielt.
|
wer gewonnen hat, und turnie.re sagt, wer als nächstes spielt. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4>Für welche Sportarten ist turnie.re geeignet?</h4>
|
<h4>Für welche Sportarten ist turnie.re geeignet?</h4>
|
||||||
<p>
|
<p>
|
||||||
turnie.re ist prinzipiell für jede Sportart geeignet. Die einzige Vor­aus­setzung ist, dass
|
turnie.re ist prinzipiell für jede Sportart geeignet. Die einzige Vor­aus­setzung ist,
|
||||||
in jedem Spiel zwei Mannschaften oder Spieler gegeinander antreten und dass derjenige mit
|
dass in jedem Spiel zwei Mannschaften oder Spieler gegeinander antreten und dass derjenige mit den
|
||||||
den meisten Punkten gewinnt.
|
meisten Punkten gewinnt. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4>Für welche Anzahl an Teams ist turnie.re geeignet?</h4>
|
<h4>Für welche Anzahl an Teams ist turnie.re geeignet?</h4>
|
||||||
<p>
|
<p>
|
||||||
turnie.re ist unabhängig von der Anzahl der Teams nutzbar.
|
turnie.re ist unabhängig von der Anzahl der Teams nutzbar. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4>Fallen für die Nutzung von turnie.re Kosten an?</h4>
|
<h4>Fallen für die Nutzung von turnie.re Kosten an?</h4>
|
||||||
<p>
|
<p>
|
||||||
turnie.re ist ein kostenloser Service! Wir erheben keine Kosten und sind nur darauf aus,
|
turnie.re ist ein kostenloser Service! Wir erheben keine Kosten und sind nur darauf aus,
|
||||||
dein Turnier-Management so einfach wie möglich zu gestalten.
|
dein Turnier-Management so einfach wie möglich zu gestalten. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function AccountFaq() {
|
function AccountFaq() {
|
||||||
return (
|
return (<div className="running-text">
|
||||||
<div className="running-text">
|
|
||||||
<h1>Account</h1>
|
<h1>Account</h1>
|
||||||
<Row>
|
<Row>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4>Warum brauche ich einen Account für turnie.re?</h4>
|
<h4>Warum brauche ich einen Account für turnie.re?</h4>
|
||||||
<p>
|
<p>
|
||||||
Wir wollen sicherstellen, dass nur berechtigte Nutzer Turnierdaten ändern können. Damit wir
|
Wir wollen sicherstellen, dass nur berechtigte Nutzer Turnierdaten ändern können. Damit wir dich als
|
||||||
dich als berechtigt verifizieren können, benötigst du einen Acoount, sodass wir dir die
|
berechtigt verifizieren können, benötigst du einen Acoount, sodass wir dir die entsprechenden
|
||||||
entsprechenden Bearbeitungsrechte zuteilen können.
|
Bearbeitungsrechte zuteilen können. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4>Welche Daten muss ich bei der Accounterstellung angeben?</h4>
|
<h4>Welche Daten muss ich bei der Accounterstellung angeben?</h4>
|
||||||
<p>
|
<p>
|
||||||
Um einen Account anzulegen musst du einen Nutzernamen, eine gültige E-Mailadresse sowie ein
|
Um einen Account anzulegen musst du einen Nutzernamen, eine gültige E-Mailadresse sowie ein Passwort
|
||||||
Passwort angeben.
|
angeben. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4>Wie werden meine Daten verarbeitet?</h4>
|
<h4>Wie werden meine Daten verarbeitet?</h4>
|
||||||
<p>
|
<p>
|
||||||
Deine Daten werden in unserer Datenbank gespeichert. Eine Weitergabe dieser Daten an Dritte
|
Deine Daten werden in unserer Datenbank gespeichert. Eine Weitergabe dieser Daten an Dritte erfolgt
|
||||||
erfolgt nicht!
|
nicht!
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Zusätlich wird dein Passwort verschlüsselt gespeichert, das bedeutet auch wir kennen dein
|
Zusätlich wird dein Passwort verschlüsselt gespeichert, das bedeutet auch wir kennen dein Passwort
|
||||||
Passwort nicht und dein Account wird zuverlässig geschützt.
|
nicht und dein Account wird zuverlässig geschützt. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4>Wie kann ich meinen Nutzernamen ändern?</h4>
|
<h4>Wie kann ich meinen Nutzernamen ändern?</h4>
|
||||||
<p>
|
<p>
|
||||||
Über deinen Nutzernamen, der in der Kopfzeile angezeigt wird, gelangst du auf deine
|
Über deinen Nutzernamen, der in der Kopfzeile angezeigt wird, gelangst du auf deine Profilseite.
|
||||||
Profilseite. Hier kannst du deinen Nutzernamen ändern.
|
Hier kannst du deinen Nutzernamen ändern. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4>Wie kann ich meine E-Mailadresse ändern?</h4>
|
<h4>Wie kann ich meine E-Mailadresse ändern?</h4>
|
||||||
<p>
|
<p>
|
||||||
Über deinen Nutzernamen, der in der Kopfzeile angezeigt wird, gelangst du auf deine
|
Über deinen Nutzernamen, der in der Kopfzeile angezeigt wird, gelangst du auf deine Profilseite.
|
||||||
Profilseite. Hier kannst du deine E-Mailadresse ändern ändern.
|
Hier kannst du deine E-Mailadresse ändern ändern. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4>Wie kann ich mein Passwort ändern?</h4>
|
<h4>Wie kann ich mein Passwort ändern?</h4>
|
||||||
<p>
|
<p>
|
||||||
Auf deiner Profilseite findest du einen "Passwort ändern" Button. Auf der sich dann
|
Auf deiner Profilseite findest du einen "Passwort ändern" Button. Auf der sich dann öffnenden Seite
|
||||||
öffnenden Seite kannst du dein Passwort ändern.
|
kannst du dein Passwort ändern. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function TournamentFaq() {
|
function TournamentFaq() {
|
||||||
return (
|
return (<div className="running-text">
|
||||||
<div className="running-text">
|
|
||||||
<h1>Turnier</h1>
|
<h1>Turnier</h1>
|
||||||
<Row>
|
<Row>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
|
|
@ -132,100 +115,85 @@ function TournamentFaq() {
|
||||||
<p>
|
<p>
|
||||||
Um ein Turnier zu erstellen musst du dich zuerst anmelden.</p>
|
Um ein Turnier zu erstellen musst du dich zuerst anmelden.</p>
|
||||||
<p>
|
<p>
|
||||||
Über "Turnier erstellen" gelangst du auf die "Turnier erstellen" Seite. Auf dieser kannst du
|
Über "Turnier erstellen" gelangst du auf die "Turnier erstellen" Seite. Auf dieser kannst du deinem
|
||||||
deinem Turnier einen Namen geben und eine (optionale) Beschreibung hinzufügen. Dann kannst
|
Turnier einen Namen geben und eine (optionale) Beschreibung hinzufügen. Dann kannst du dein
|
||||||
du dein Turnier <a href="#public-tournament">öffentlich oder privat</a> erstellen, die Teams
|
Turnier <a href="#public-tournament">öffentlich oder privat</a> erstellen, die Teams für die
|
||||||
für die Spielpaarungen <a href="#randomize-teams">mischen</a> lassen und eine <a href="#groupstage">Gruppenphase</a>
|
Spielpaarungen <a href="#randomize-teams">mischen</a> lassen und eine <a
|
||||||
hinzufügen. Im Feld "Teams" kannst du die
|
href="#groupstage">Gruppenphase</a>
|
||||||
teilnehmenden <a href="#add-teams">Teams
|
hinzufügen. Im Feld "Teams" kannst du die teilnehmenden <a href="#add-teams">Teams eintragen</a> und
|
||||||
eintragen</a> und hinzufügen. </p>
|
hinzufügen. </p>
|
||||||
<p>
|
<p>
|
||||||
Wenn du die Option Gruppenphase aktiviert hast, kannst du zusätzlich noch die Größe der
|
Wenn du die Option Gruppenphase aktiviert hast, kannst du zusätzlich noch die Größe der Gruppen
|
||||||
Gruppen angeben.
|
angeben. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4 id="public-tournament">Was ist der Unterschied zwischen einem öffentlichen und einem
|
<h4 id="public-tournament">Was ist der Unterschied zwischen einem öffentlichen und einem privaten
|
||||||
privaten Turnier?</h4>
|
Turnier?</h4>
|
||||||
<p>
|
<p>
|
||||||
Standardmäßig ist ein Turnier privat, das bedeutet, dass nur der Turnierersteller und
|
Standardmäßig ist ein Turnier privat, das bedeutet, dass nur der Turnierersteller und Zuschauer, die
|
||||||
Zuschauer, die den entsprechenden Turniercode erhalten haben, das Turnier, seine
|
den entsprechenden Turniercode erhalten haben, das Turnier, seine teilnehmenden Mannschaften, sowie
|
||||||
teilnehmenden Mannschaften, sowie die Spielpaarungen und die jeweiligen Spielstände sehen
|
die Spielpaarungen und die jeweiligen Spielstände sehen können. </p>
|
||||||
können.
|
|
||||||
</p>
|
|
||||||
<p>
|
<p>
|
||||||
Wenn du dich entscheidest dein Turnier öffentlich zu erstellen, wird der Turniercode nicht
|
Wenn du dich entscheidest dein Turnier öffentlich zu erstellen, wird der Turniercode nicht mehr
|
||||||
mehr benötigt, um das Turnier und all seine Informationen einzusehen. Das Turnier wird dann
|
benötigt, um das Turnier und all seine Informationen einzusehen. Das Turnier wird dann in der Liste
|
||||||
in der Liste der öffentlichen Turniere angezeigt und kann auch über seinen Namen von jedem
|
der öffentlichen Turniere angezeigt und kann auch über seinen Namen von jedem gefunden werden. </p>
|
||||||
gefunden werden. </p>
|
|
||||||
<p>
|
<p>
|
||||||
Trotzdem bleibt der Turnierersteller der Einzige, der die Turnierinformationen bearbeiten
|
Trotzdem bleibt der Turnierersteller der Einzige, der die Turnierinformationen bearbeiten und
|
||||||
und Spielstände eintragen kann.
|
Spielstände eintragen kann. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4 id="randomize-teams">Was bedeutet "Teams mischen"?</h4>
|
<h4 id="randomize-teams">Was bedeutet "Teams mischen"?</h4>
|
||||||
<p>
|
<p>
|
||||||
Die Spielpaarungen werden anhand der Eingabereihenfolge der Teams erstellt. So spielt z.B.
|
Die Spielpaarungen werden anhand der Eingabereihenfolge der Teams erstellt. So spielt z.B. das
|
||||||
das zuerst eingegebene Team gegen das als zweites eingegebene Team, das als drittes
|
zuerst eingegebene Team gegen das als zweites eingegebene Team, das als drittes eingegebene gegen
|
||||||
eingegebene gegen das als viertes eingegebene, und so weiter. </p>
|
das als viertes eingegebene, und so weiter. </p>
|
||||||
<p>
|
<p>
|
||||||
Wenn du das nicht möchtest kannst du die Option "Teams mischen" aktivieren und die
|
Wenn du das nicht möchtest kannst du die Option "Teams mischen" aktivieren und die Spielpaarungen
|
||||||
Spielpaarungen werden in einer zufälligen Reihenfolge erstellt.
|
werden in einer zufälligen Reihenfolge erstellt. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4 id="groupstage">Was passiert wenn ich die Gruppenphase aktiviere?</h4>
|
<h4 id="groupstage">Was passiert wenn ich die Gruppenphase aktiviere?</h4>
|
||||||
<p>
|
<p>
|
||||||
Grundsätzlich erstellt turnie.re dir einen Spielplan für ein Turnier <strong>ohne</strong>
|
Grundsätzlich erstellt turnie.re dir einen Spielplan für ein Turnier <strong>ohne</strong>
|
||||||
Gruppenphase und <strong>nur</strong> einer K.O.-Phase. Wenn du eine Gruppenphase spielen
|
Gruppenphase und <strong>nur</strong> einer K.O.-Phase. Wenn du eine Gruppenphase spielen lassen
|
||||||
lassen willst, kannst du das aber auch tun. Wenn die Gruppenphase aktiviert ist, werden
|
willst, kannst du das aber auch tun. Wenn die Gruppenphase aktiviert ist, werden deine eingegeben
|
||||||
deine eingegeben Teams automatisch in Gruppen eingeteilt und auch die Spielpläne für die
|
Teams automatisch in Gruppen eingeteilt und auch die Spielpläne für die einzelnen Gruppen berechnet.
|
||||||
einzelnen Gruppen berechnet. </p>
|
|
||||||
<p>
|
|
||||||
Bitte beachte, dass die Anzahl der Teams durch die Gruppengröße teilbar sein muss.
|
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
Bitte beachte, dass die Anzahl der Teams durch die Gruppengröße teilbar sein muss. </p>
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4 id="add-teams">Wie kann ich Teams hinzufügen?</h4>
|
<h4 id="add-teams">Wie kann ich Teams hinzufügen?</h4>
|
||||||
<p>
|
<p>
|
||||||
Auf der "Turnier erstellen" Seite kannst du im Feld "Teams" deine Teams eintragen. </p>
|
Auf der "Turnier erstellen" Seite kannst du im Feld "Teams" deine Teams eintragen. </p>
|
||||||
<p>
|
<p>
|
||||||
Du kannst die Teamnamen einzeln eingeben und dann über drücken der Entertaste oder über den
|
Du kannst die Teamnamen einzeln eingeben und dann über drücken der Entertaste oder über den Button
|
||||||
Button "Team hinzufügen" das Team deinem Turnier hinzufügen. Du kannst aber auch deine Teams
|
"Team hinzufügen" das Team deinem Turnier hinzufügen. Du kannst aber auch deine Teams als eine mit
|
||||||
als eine mit Kommas getrennte Liste eingeben und dann hinzufügen.
|
Kommas getrennte Liste eingeben und dann hinzufügen. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4>Wie starte ich ein Spiel?</h4>
|
<h4>Wie starte ich ein Spiel?</h4>
|
||||||
<p>
|
<p>
|
||||||
Auf der Turnierübersicht Seite gibt es für jede Partie einen "Spiel starten" Button. Über
|
Auf der Turnierübersicht Seite gibt es für jede Partie einen "Spiel starten" Button. Über diesen
|
||||||
diesen kannst du einfach das jeweilige Spiel starten.
|
kannst du einfach das jeweilige Spiel starten. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
<Col sm="4">
|
<Col sm="4">
|
||||||
<h4>Wie trage ich einen Spielstand für eine Partie ein?</h4>
|
<h4>Wie trage ich einen Spielstand für eine Partie ein?</h4>
|
||||||
<p>
|
<p>
|
||||||
Auf der Turnierübersicht Seite gibt es für jede Partie einen "Spielstand ändern" Button.
|
Auf der Turnierübersicht Seite gibt es für jede Partie einen "Spielstand ändern" Button. Über diesen
|
||||||
Über diesen kannst du einfach den Spielstand eintragen. In dem Popup, das sich öffnet kannst
|
kannst du einfach den Spielstand eintragen. In dem Popup, das sich öffnet kannst du den aktuellen
|
||||||
du den aktuellen Spielstand eintragen und angeben, ob das Spiel noch läuft oder schon
|
Spielstand eintragen und angeben, ob das Spiel noch läuft oder schon beendet ist. </p>
|
||||||
beendet ist.
|
|
||||||
</p>
|
|
||||||
<h4>Gibt es in der Gruppenphase eine Blitztabelle?</h4>
|
<h4>Gibt es in der Gruppenphase eine Blitztabelle?</h4>
|
||||||
<p>
|
<p>
|
||||||
Ja, die in der Gruppenphase dargestellte Tabelle stellt eine Blitztabelle dar.
|
Ja, die in der Gruppenphase dargestellte Tabelle stellt eine Blitztabelle dar. </p>
|
||||||
</p>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class FaqPage extends React.Component {
|
export default class FaqPage extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<div>
|
||||||
<div>
|
|
||||||
<Head>
|
<Head>
|
||||||
<title>FAQ: turnie.re</title>
|
<title>FAQ: turnie.re</title>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
@ -233,7 +201,6 @@ export default class FaqPage extends React.Component {
|
||||||
<BigImage text="FAQ"/>
|
<BigImage text="FAQ"/>
|
||||||
<Main/>
|
<Main/>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,22 @@
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Container } from 'reactstrap';
|
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 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
import '../static/everypage.css';
|
import '../static/everypage.css';
|
||||||
|
|
||||||
function Main() {
|
function Main() {
|
||||||
return (
|
return (<div className="main running-text">
|
||||||
<div className="main running-text">
|
|
||||||
<ImprintText/>
|
<ImprintText/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function ImprintText(){
|
function ImprintText() {
|
||||||
return (
|
return (<Container>
|
||||||
<Container>
|
|
||||||
<h3>
|
<h3>
|
||||||
Angaben gemäß §5 TMG:
|
Angaben gemäß §5 TMG:
|
||||||
</h3>
|
</h3>
|
||||||
|
|
@ -40,44 +37,60 @@ function ImprintText(){
|
||||||
<h3>Haftungsausschluss</h3>
|
<h3>Haftungsausschluss</h3>
|
||||||
<h4>Haftung für Inhalte</h4>
|
<h4>Haftung für Inhalte</h4>
|
||||||
<p>
|
<p>
|
||||||
Die Inhalte unserer Seiten wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit und Aktualität
|
Die Inhalte unserer Seiten wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit
|
||||||
der Inhalte können wir jedoch keine Gewähr übernehmen. Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene
|
und Aktualität
|
||||||
Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als
|
der Inhalte können wir jedoch keine Gewähr übernehmen. Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG
|
||||||
Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu überwachen oder nach
|
für eigene
|
||||||
Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung oder Sperrung
|
Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir
|
||||||
der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine diesbezügliche Haftung ist
|
als
|
||||||
jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden von
|
Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde Informationen zu
|
||||||
|
überwachen oder nach
|
||||||
|
Umständen zu forschen, die auf eine rechtswidrige Tätigkeit hinweisen. Verpflichtungen zur Entfernung
|
||||||
|
oder Sperrung
|
||||||
|
der Nutzung von Informationen nach den allgemeinen Gesetzen bleiben hiervon unberührt. Eine
|
||||||
|
diesbezügliche Haftung ist
|
||||||
|
jedoch erst ab dem Zeitpunkt der Kenntnis einer konkreten Rechtsverletzung möglich. Bei Bekanntwerden
|
||||||
|
von
|
||||||
entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.
|
entsprechenden Rechtsverletzungen werden wir diese Inhalte umgehend entfernen.
|
||||||
</p>
|
</p>
|
||||||
<h4>Haftung für Links</h4>
|
<h4>Haftung für Links</h4>
|
||||||
<p>
|
<p>
|
||||||
Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können
|
Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben.
|
||||||
wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der
|
Deshalb können
|
||||||
jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt der Verlinkung
|
wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist
|
||||||
auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht erkennbar. Eine
|
stets der
|
||||||
permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer Rechtsverletzung
|
jeweilige Anbieter oder Betreiber der Seiten verantwortlich. Die verlinkten Seiten wurden zum Zeitpunkt
|
||||||
|
der Verlinkung
|
||||||
|
auf mögliche Rechtsverstöße überprüft. Rechtswidrige Inhalte waren zum Zeitpunkt der Verlinkung nicht
|
||||||
|
erkennbar. Eine
|
||||||
|
permanente inhaltliche Kontrolle der verlinkten Seiten ist jedoch ohne konkrete Anhaltspunkte einer
|
||||||
|
Rechtsverletzung
|
||||||
nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.
|
nicht zumutbar. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Links umgehend entfernen.
|
||||||
</p>
|
</p>
|
||||||
<h4>Urheberrecht</h4>
|
<h4>Urheberrecht</h4>
|
||||||
<p>
|
<p>
|
||||||
Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht.
|
Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen
|
||||||
Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes
|
Urheberrecht.
|
||||||
bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser Seite sind
|
Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des
|
||||||
nur für den privaten, nicht kommerziellen Gebrauch gestattet. Soweit die Inhalte auf dieser Seite nicht vom Betreiber
|
Urheberrechtes
|
||||||
erstellt wurden, werden die Urheberrechte Dritter beachtet. Insbesondere werden Inhalte Dritter als solche
|
bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser
|
||||||
gekennzeichnet. Sollten Sie trotzdem auf eine Urheberrechtsverletzung aufmerksam werden, bitten wir um einen
|
Seite sind
|
||||||
entsprechenden Hinweis. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Inhalte umgehend entfernen.
|
nur für den privaten, nicht kommerziellen Gebrauch gestattet. Soweit die Inhalte auf dieser Seite nicht
|
||||||
|
vom Betreiber
|
||||||
|
erstellt wurden, werden die Urheberrechte Dritter beachtet. Insbesondere werden Inhalte Dritter als
|
||||||
|
solche
|
||||||
|
gekennzeichnet. Sollten Sie trotzdem auf eine Urheberrechtsverletzung aufmerksam werden, bitten wir um
|
||||||
|
einen
|
||||||
|
entsprechenden Hinweis. Bei Bekanntwerden von Rechtsverletzungen werden wir derartige Inhalte umgehend
|
||||||
|
entfernen.
|
||||||
</p>
|
</p>
|
||||||
</Container>
|
</Container>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default class ImprintPage extends React.Component {
|
export default class ImprintPage extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<div>
|
||||||
<div>
|
|
||||||
<Head>
|
<Head>
|
||||||
<title>Impressum: turnie.re</title>
|
<title>Impressum: turnie.re</title>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
@ -85,7 +98,6 @@ export default class ImprintPage extends React.Component {
|
||||||
<BigImage text="Impressum / Haftungs­ausschluss"/>
|
<BigImage text="Impressum / Haftungs­ausschluss"/>
|
||||||
<Main/>
|
<Main/>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,13 @@
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {
|
import {
|
||||||
Alert,
|
Alert, Button, Card, CardBody
|
||||||
Button,
|
|
||||||
Card,
|
|
||||||
CardBody
|
|
||||||
} from 'reactstrap';
|
} 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 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
||||||
|
|
@ -18,60 +15,49 @@ import '../static/everypage.css';
|
||||||
import '../static/css/index.css';
|
import '../static/css/index.css';
|
||||||
|
|
||||||
function Main() {
|
function Main() {
|
||||||
return (
|
return (<div className="main">
|
||||||
<div className="main">
|
|
||||||
<Marketing/>
|
<Marketing/>
|
||||||
<MainPromotedLinks/>
|
<MainPromotedLinks/>
|
||||||
<MainBottomSummary/>
|
<MainBottomSummary/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function Marketing() {
|
function Marketing() {
|
||||||
return (
|
return (<div className="container marketing my-5">
|
||||||
<div className="container marketing my-5">
|
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-lg-4">
|
<div className="col-lg-4">
|
||||||
<h2>Für jede Sportart</h2>
|
<h2>Für jede Sportart</h2>
|
||||||
<p>
|
<p>
|
||||||
Egal, um welche Sportart es geht: Solange du mit mehreren Mannschaften ein Turnier veranstalten
|
Egal, um welche Sportart es geht: Solange du mit mehreren Mannschaften ein Turnier veranstalten
|
||||||
willst, kann
|
willst, kann turnie.re dir ein Turnier berechnen!
|
||||||
turnie.re dir ein Turnier berechnen!
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-lg-4">
|
<div className="col-lg-4">
|
||||||
<h2>Beliebige Anzahl Teams</h2>
|
<h2>Beliebige Anzahl Teams</h2>
|
||||||
<p>
|
<p>
|
||||||
Egal, wie viele Teams du gerne in deinem Turnier hast, wir regeln das. Füge einfach deine Teams
|
Egal, wie viele Teams du gerne in deinem Turnier hast, wir regeln das. Füge einfach deine Teams
|
||||||
hinzu
|
hinzu und schon sagen wir dir, wer gegen wen spielt. </p>
|
||||||
und schon sagen wir dir, wer gegen wen spielt.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="col-lg-4">
|
<div className="col-lg-4">
|
||||||
<h2>Kostenlos</h2>
|
<h2>Kostenlos</h2>
|
||||||
<p>
|
<p>
|
||||||
turnie.re ist ein kostenloser Service! Wir erheben keine Kosten und sind nur darauf aus, dein
|
turnie.re ist ein kostenloser Service! Wir erheben keine Kosten und sind nur darauf aus, dein
|
||||||
Turnier-Management so einfach wie möglich zu gestalten.
|
Turnier-Management so einfach wie möglich zu gestalten. </p>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<Betawarning/>
|
<Betawarning/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function Betawarning() {
|
function Betawarning() {
|
||||||
return (
|
return (<Alert color="danger" className="shadow-sm mt-4" fade={false}>
|
||||||
<Alert color="danger" className="shadow-sm mt-4" fade={false}>
|
|
||||||
<h4 className="alert-heading custom-font">Public Beta</h4>
|
<h4 className="alert-heading custom-font">Public Beta</h4>
|
||||||
<p>
|
<p>
|
||||||
Diese Website ist noch in der Entwicklung.<br/>
|
Diese Website ist noch in der Entwicklung.<br/>
|
||||||
Bei Problemen fülle bitte <a href="#" id="bugLink" className="alert-link">dieses </a>
|
Bei Problemen fülle bitte <a href="#" id="bugLink" className="alert-link">dieses </a>
|
||||||
und für Feedback <a href="#" id="feedbackLink" className="alert-link">dieses</a> Formular aus.
|
und für Feedback <a href="#" id="feedbackLink" className="alert-link">dieses</a> Formular aus. </p>
|
||||||
</p>
|
</Alert>);
|
||||||
</Alert>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function MainBottomSummary() {
|
function MainBottomSummary() {
|
||||||
|
|
@ -84,17 +70,15 @@ function MainBottomSummary() {
|
||||||
turnie.re berechnet dir ein Turnier. Allein aus den Team-Namen berechnen wir dir einen kompletten
|
turnie.re berechnet dir ein Turnier. Allein aus den Team-Namen berechnen wir dir einen kompletten
|
||||||
Spielplan,
|
Spielplan,
|
||||||
den du auch gleich mit allen Leuten teilen kannst, ohne dir Gedanken machen zu müssen, wer gegen wen
|
den du auch gleich mit allen Leuten teilen kannst, ohne dir Gedanken machen zu müssen, wer gegen wen
|
||||||
spielen
|
spielen muss.<br/>
|
||||||
muss.<br/>
|
Du trägst ein, wer gewonnen hat, und turnie.re sagt, wer als nächstes spielt. </p>
|
||||||
Du trägst ein, wer gewonnen hat, und turnie.re sagt, wer als nächstes spielt.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="col-lg-6">
|
<div className="col-lg-6">
|
||||||
<h2>Ich habe einen Turniercode bekommen. Was nun?</h2>
|
<h2>Ich habe einen Turniercode bekommen. Was nun?</h2>
|
||||||
<p>
|
<p>
|
||||||
Der Turniercode führt dich direkt zu einem Turnier. Gebe dafür den Code
|
Der Turniercode führt dich direkt zu einem Turnier. Gebe dafür den Code <a className="text-success"
|
||||||
<a className="text-success" href="#turniercode-form">oben</a> ein, dann wirst du sofort weitergeleitet.
|
href="#turniercode-form">oben</a> ein,
|
||||||
</p>
|
dann wirst du sofort weitergeleitet. </p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="my-5 text-center">
|
<div className="my-5 text-center">
|
||||||
|
|
@ -114,8 +98,7 @@ function MainPromotedLinks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function PromotedLinkTournamentCode() {
|
function PromotedLinkTournamentCode() {
|
||||||
return (
|
return (<Card className="container shadow-lg mt-3">
|
||||||
<Card className="container shadow-lg mt-3">
|
|
||||||
<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"/>
|
||||||
|
|
@ -125,30 +108,24 @@ function PromotedLinkTournamentCode() {
|
||||||
<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>
|
||||||
</div>
|
</div>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function PromotedLinkListTournaments() {
|
function PromotedLinkListTournaments() {
|
||||||
return (
|
return (<Card className="container shadow-lg my-4">
|
||||||
<Card className="container shadow-lg my-4">
|
|
||||||
<CardBody className="row">
|
<CardBody className="row">
|
||||||
<div className="col-lg-4 pb-3">
|
<div className="col-lg-4 pb-3">
|
||||||
<Button outline color="success" className="w-100" href="/list">Alle Turniere anzeigen</Button>
|
<Button outline color="success" className="w-100" href="/list">Alle Turniere anzeigen</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-lg-8">
|
<div className="col-lg-8">
|
||||||
<p>
|
<p>
|
||||||
Hier findest du alle öffentlichen Turniere. Wenn du ein Turnier suchst, den Turniercode aber
|
Hier findest du alle öffentlichen Turniere. Wenn du ein Turnier suchst, den Turniercode aber nicht
|
||||||
nicht hast, wirst
|
hast, wirst du wahrscheinlich hier fündig. </p>
|
||||||
du wahrscheinlich hier fündig.
|
|
||||||
</p>
|
|
||||||
<p>
|
<p>
|
||||||
Wenn du eingeloggt bist, findest du hier auch deine eigenen Turniere.
|
Wenn du eingeloggt bist, findest du hier auch deine eigenen Turniere. </p>
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function PromotedLinkCreateTournament() {
|
function PromotedLinkCreateTournament() {
|
||||||
|
|
@ -156,9 +133,8 @@ function PromotedLinkCreateTournament() {
|
||||||
<CardBody className="row">
|
<CardBody className="row">
|
||||||
<div className="col-lg-8">
|
<div className="col-lg-8">
|
||||||
<p>
|
<p>
|
||||||
<strong>Einfach ausprobieren:</strong> Einen Turnier-Namen, ein paar Team-Namen, und schon
|
<strong>Einfach ausprobieren:</strong> Einen Turnier-Namen, ein paar Team-Namen, und schon kriegst
|
||||||
kriegst du ein
|
du ein komplettes Turnier!
|
||||||
komplettes Turnier!
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-lg-4">
|
<div className="col-lg-4">
|
||||||
|
|
@ -170,10 +146,8 @@ function PromotedLinkCreateTournament() {
|
||||||
|
|
||||||
|
|
||||||
class Index extends React.Component {
|
class Index extends React.Component {
|
||||||
|
render() {
|
||||||
render () {
|
return (<div>
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<Head>
|
<Head>
|
||||||
<title>turnie.re</title>
|
<title>turnie.re</title>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
@ -181,8 +155,7 @@ class Index extends React.Component {
|
||||||
<BigImage text="Einfach Turniere organisieren"/>
|
<BigImage text="Einfach Turniere organisieren"/>
|
||||||
<Main/>
|
<Main/>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,8 @@ import TournamentList from '../js/components/TournamentList';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
|
|
||||||
export default class PublicTournamentsPage extends React.Component {
|
export default class PublicTournamentsPage extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
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>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
@ -22,8 +20,7 @@ export default class PublicTournamentsPage extends React.Component {
|
||||||
<PublicTournamentPageContent/>
|
<PublicTournamentPageContent/>
|
||||||
</div>
|
</div>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,9 +29,7 @@ function mapStateToProperties(state) {
|
||||||
return {isSignedIn};
|
return {isSignedIn};
|
||||||
}
|
}
|
||||||
|
|
||||||
const PublicTournamentPageContent = connect(
|
const PublicTournamentPageContent = connect(mapStateToProperties)(PublicTournaments);
|
||||||
mapStateToProperties,
|
|
||||||
)(PublicTournaments);
|
|
||||||
|
|
||||||
function PublicTournaments(props) {
|
function PublicTournaments(props) {
|
||||||
if (props.isSignedIn) {
|
if (props.isSignedIn) {
|
||||||
|
|
@ -46,7 +41,6 @@ function PublicTournaments(props) {
|
||||||
<a href='/private' className="btn btn-success shadow">zu den privaten Turnieren</a>
|
<a href='/private' className="btn btn-success shadow">zu den privaten Turnieren</a>
|
||||||
</Container>
|
</Container>
|
||||||
</div>);
|
</div>);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return (<Container className='py-5'>
|
return (<Container className='py-5'>
|
||||||
<PublicTournamentsCard/>
|
<PublicTournamentsCard/>
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import React from 'react';
|
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 '../static/everypage.css';
|
import '../static/everypage.css';
|
||||||
|
|
||||||
export default class LoginPage extends React.Component {
|
export default class LoginPage extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
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>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
@ -20,7 +18,6 @@ export default class LoginPage extends React.Component {
|
||||||
<Login/>
|
<Login/>
|
||||||
</div>
|
</div>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
422
pages/privacy.js
422
pages/privacy.js
|
|
@ -1,41 +1,33 @@
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Container } from 'reactstrap';
|
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 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
||||||
import '../static/everypage.css';
|
import '../static/everypage.css';
|
||||||
|
|
||||||
function Main() {
|
function Main() {
|
||||||
return (
|
return (<div className="main running-text">
|
||||||
<div className="main running-text">
|
|
||||||
<PrivacyText/>
|
<PrivacyText/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function PrivacyText(){
|
function PrivacyText() {
|
||||||
return (
|
return (<Container>
|
||||||
<Container>
|
|
||||||
<p>
|
<p>
|
||||||
Die nachfolgende Datenschutzerklärung gilt für die Nutzung unseres Online-Angebots turnie.re (nachfolgend
|
Die nachfolgende Datenschutzerklärung gilt für die Nutzung unseres Online-Angebots turnie.re (nachfolgend
|
||||||
„Website“).<br/>
|
„Website“).<br/>
|
||||||
Wir messen dem Datenschutz große Bedeutung bei. Die Erhebung und Verarbeitung Ihrer personenbezogenen Daten
|
Wir messen dem Datenschutz große Bedeutung bei. Die Erhebung und Verarbeitung Ihrer personenbezogenen Daten
|
||||||
geschieht
|
geschieht unter Beachtung der geltenden datenschutzrechtlichen Vorschriften, insbesondere der
|
||||||
unter Beachtung der geltenden datenschutzrechtlichen Vorschriften, insbesondere der
|
Datenschutzgrundverordnung (DSGVO). </p>
|
||||||
Datenschutzgrundverordnung
|
|
||||||
(DSGVO).
|
|
||||||
</p>
|
|
||||||
<h3>1 Verantwortlicher</h3>
|
<h3>1 Verantwortlicher</h3>
|
||||||
<p>
|
<p>
|
||||||
Verantwortlicher für die Erhebung, Verarbeitung und Nutzung Ihrer personenbezogenen Daten im Sinne von Art.
|
Verantwortlicher für die Erhebung, Verarbeitung und Nutzung Ihrer personenbezogenen Daten im Sinne von Art.
|
||||||
4 Nr. 7
|
4 Nr. 7 DSGVO ist </p>
|
||||||
DSGVO ist
|
|
||||||
</p>
|
|
||||||
<p>
|
<p>
|
||||||
Jonas Seydel<br/>
|
Jonas Seydel<br/>
|
||||||
August-Euler-Weg 3<br/>
|
August-Euler-Weg 3<br/>
|
||||||
|
|
@ -45,16 +37,12 @@ function PrivacyText(){
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Sofern Sie der Erhebung, Verarbeitung oder Nutzung Ihrer Daten durch uns nach Maßgabe dieser
|
Sofern Sie der Erhebung, Verarbeitung oder Nutzung Ihrer Daten durch uns nach Maßgabe dieser
|
||||||
Datenschutzbestimmungen
|
Datenschutzbestimmungen insgesamt oder für einzelne Maßnahmen widersprechen wollen, können Sie Ihren
|
||||||
insgesamt oder für einzelne Maßnahmen widersprechen wollen, können Sie Ihren Widerspruch an den
|
Widerspruch an den Verantwortlichen richten.<br/>
|
||||||
Verantwortlichen
|
Sie können diese Datenschutzerklärung jederzeit speichern und ausdrucken. </p>
|
||||||
richten.<br/>
|
|
||||||
Sie können diese Datenschutzerklärung jederzeit speichern und ausdrucken.
|
|
||||||
</p>
|
|
||||||
<h3>2 Allgemeine Zwecke der Verarbeitung</h3>
|
<h3>2 Allgemeine Zwecke der Verarbeitung</h3>
|
||||||
<p>
|
<p>
|
||||||
Wir verwenden personenbezogene Daten zum Zweck des Betriebs der Website.
|
Wir verwenden personenbezogene Daten zum Zweck des Betriebs der Website. </p>
|
||||||
</p>
|
|
||||||
<h3>3 Welche Daten wir verwenden und warum</h3>
|
<h3>3 Welche Daten wir verwenden und warum</h3>
|
||||||
<h4>3.1 Hosting</h4>
|
<h4>3.1 Hosting</h4>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -66,20 +54,15 @@ function PrivacyText(){
|
||||||
Hierbei verarbeiten wir, bzw. unser Hostinganbieter Bestandsdaten, Kontaktdaten, Inhaltsdaten,
|
Hierbei verarbeiten wir, bzw. unser Hostinganbieter Bestandsdaten, Kontaktdaten, Inhaltsdaten,
|
||||||
Vertragsdaten,
|
Vertragsdaten,
|
||||||
Nutzungsdaten, Meta- und Kommunikationsdaten von Kunden, Interessenten und Besuchern dieser Website auf
|
Nutzungsdaten, Meta- und Kommunikationsdaten von Kunden, Interessenten und Besuchern dieser Website auf
|
||||||
Grundlage
|
Grundlage unserer berechtigten Interessen an einer effizienten und sicheren Zurverfügungstellung unserer
|
||||||
unserer berechtigten Interessen an einer effizienten und sicheren Zurverfügungstellung unserer Website gem.
|
Website gem. Art. 6 Abs. 1 S. 1 f) DSGVO i.V.m. Art. 28 DSGVO. </p>
|
||||||
Art. 6
|
|
||||||
Abs. 1 S. 1 f) DSGVO i.V.m. Art. 28 DSGVO.
|
|
||||||
</p>
|
|
||||||
<h4>3.2 Zugriffsdaten</h4>
|
<h4>3.2 Zugriffsdaten</h4>
|
||||||
<p>
|
<p>
|
||||||
Wir sammeln Informationen über Sie, wenn Sie diese Website nutzen. Wir erfassen automatisch Informationen
|
Wir sammeln Informationen über Sie, wenn Sie diese Website nutzen. Wir erfassen automatisch Informationen
|
||||||
über Ihr
|
über Ihr Nutzungsverhalten und Ihre Interaktion mit uns und registrieren Daten zu Ihrem Computer oder
|
||||||
Nutzungsverhalten und Ihre Interaktion mit uns und registrieren Daten zu Ihrem Computer oder Mobilgerät. Wir
|
Mobilgerät. Wir erheben,
|
||||||
erheben,
|
|
||||||
speichern und nutzen Daten über jeden Zugriff auf unsere Website (sogenannte Serverlogfiles). Zu den
|
speichern und nutzen Daten über jeden Zugriff auf unsere Website (sogenannte Serverlogfiles). Zu den
|
||||||
Zugriffsdaten
|
Zugriffsdaten gehören:
|
||||||
gehören:
|
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Name und URL der abgerufenen Datei</li>
|
<li>Name und URL der abgerufenen Datei</li>
|
||||||
|
|
@ -95,60 +78,40 @@ function PrivacyText(){
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
Wir nutzen diese Protokolldaten ohne Zuordnung zu Ihrer Person oder sonstiger Profilerstellung für
|
Wir nutzen diese Protokolldaten ohne Zuordnung zu Ihrer Person oder sonstiger Profilerstellung für
|
||||||
statistische
|
statistische Auswertungen zum Zweck des Betriebs, der Sicherheit und der Optimierung unserer Website, aber
|
||||||
Auswertungen zum Zweck des Betriebs, der Sicherheit und der Optimierung unserer Website, aber auch zur
|
auch zur anonymen Erfassung der Anzahl der Besucher auf unserer Website (traffic) sowie zum Umfang und zur
|
||||||
anonymen
|
Art der Nutzung unserer Website und Dienste, ebenso zu Abrechnungszwecken, um die Anzahl der von
|
||||||
Erfassung der Anzahl der Besucher auf unserer Website (traffic) sowie zum Umfang und zur Art der Nutzung
|
Kooperationspartnern erhaltenen Clicks zu messen. Aufgrund dieser Informationen können wir personalisierte
|
||||||
unserer
|
und standortbezogene Inhalte zur Verfügung stellen und den Datenverkehr analysieren, Fehler suchen und
|
||||||
Website und Dienste, ebenso zu Abrechnungszwecken, um die Anzahl der von Kooperationspartnern erhaltenen
|
beheben und unsere Dienste verbessern.<br/>
|
||||||
Clicks zu
|
|
||||||
messen. Aufgrund dieser Informationen können wir personalisierte und standortbezogene Inhalte zur Verfügung
|
|
||||||
stellen
|
|
||||||
und den Datenverkehr analysieren, Fehler suchen und beheben und unsere Dienste verbessern.<br/>
|
|
||||||
Hierin liegt auch unser berechtigtes Interesse gemäß Art 6 Abs. 1 S. 1 f) DSGVO.<br/>
|
Hierin liegt auch unser berechtigtes Interesse gemäß Art 6 Abs. 1 S. 1 f) DSGVO.<br/>
|
||||||
Wir behalten uns vor, die Protokolldaten nachträglich zu überprüfen, wenn aufgrund konkreter Anhaltspunkte
|
Wir behalten uns vor, die Protokolldaten nachträglich zu überprüfen, wenn aufgrund konkreter Anhaltspunkte
|
||||||
der
|
der berechtigte Verdacht einer rechtswidrigen Nutzung besteht. IP-Adressen speichern wir für einen
|
||||||
berechtigte Verdacht einer rechtswidrigen Nutzung besteht. IP-Adressen speichern wir für einen begrenzten
|
begrenzten Zeitraum in den Logfiles, wenn dies für Sicherheitszwecke erforderlich oder für die
|
||||||
Zeitraum in
|
Leistungserbringung oder die Abrechnung einer Leistung nötig ist, z. B. wenn Sie eines unserer Angebote
|
||||||
den Logfiles, wenn dies für Sicherheitszwecke erforderlich oder für die Leistungserbringung oder die
|
nutzen. Nach Abbruch des Vorgangs der Bestellung oder nach Zahlungseingang löschen wir die IP-Adresse, wenn
|
||||||
Abrechnung einer
|
diese für Sicherheitszwecke nicht mehr erforderlich ist. IP-Adressen speichern wir auch dann, wenn wir den
|
||||||
Leistung nötig ist, z. B. wenn Sie eines unserer Angebote nutzen. Nach Abbruch des Vorgangs der Bestellung
|
konkreten Verdacht einer Straftat im Zusammenhang mit der Nutzung unserer Website haben. Außerdem speichern
|
||||||
oder nach
|
wir als Teil Ihres Accounts das Datum Ihres letzten Besuchs (z.B. bei Registrierung,
|
||||||
Zahlungseingang löschen wir die IP-Adresse, wenn diese für Sicherheitszwecke nicht mehr erforderlich ist.
|
Login, Klicken von Links etc.). </p>
|
||||||
IP-Adressen
|
|
||||||
speichern wir auch dann, wenn wir den konkreten Verdacht einer Straftat im Zusammenhang mit der Nutzung
|
|
||||||
unserer
|
|
||||||
Website haben. Außerdem speichern wir als Teil Ihres Accounts das Datum Ihres letzten Besuchs (z.B. bei
|
|
||||||
Registrierung,
|
|
||||||
Login, Klicken von Links etc.).
|
|
||||||
</p>
|
|
||||||
<h4>3.3 Cookies</h4>
|
<h4>3.3 Cookies</h4>
|
||||||
<p>
|
<p>
|
||||||
Wir verwenden sogenannte Session-Cookies, um unsere Website zu optimieren. Ein Session-Cookie ist eine
|
Wir verwenden sogenannte Session-Cookies, um unsere Website zu optimieren. Ein Session-Cookie ist eine
|
||||||
kleine
|
kleine Textdatei, die von den jeweiligen Servern beim Besuch einer Internetseite verschickt und auf Ihrer
|
||||||
Textdatei, die von den jeweiligen Servern beim Besuch einer Internetseite verschickt und auf Ihrer
|
Festplatte zwischengespeichert wird. Diese Datei als solche enthält eine sogenannte Session-ID, mit welcher
|
||||||
Festplatte
|
sich verschiedene Anfragen Ihres Browsers der gemeinsamen Sitzung zuordnen lassen. Dadurch kann Ihr Rechner
|
||||||
zwischengespeichert wird. Diese Datei als solche enthält eine sogenannte Session-ID, mit welcher sich
|
wiedererkannt werden, wenn Sie auf unsere Website zurückkehren. Diese Cookies werden gelöscht, nachdem Sie
|
||||||
verschiedene
|
Ihren Browser schließen. Sie dienen z. B. dazu, dass Sie die Warenkorbfunktion über mehrere Seiten hinweg
|
||||||
Anfragen Ihres Browsers der gemeinsamen Sitzung zuordnen lassen. Dadurch kann Ihr Rechner wiedererkannt
|
nutzen können.<br/>
|
||||||
werden, wenn
|
|
||||||
Sie auf unsere Website zurückkehren. Diese Cookies werden gelöscht, nachdem Sie Ihren Browser schließen. Sie
|
|
||||||
dienen z.
|
|
||||||
B. dazu, dass Sie die Warenkorbfunktion über mehrere Seiten hinweg nutzen können.<br/>
|
|
||||||
Wir verwenden in geringem Umfang auch persistente Cookies (ebenfalls kleine Textdateien, die auf Ihrem
|
Wir verwenden in geringem Umfang auch persistente Cookies (ebenfalls kleine Textdateien, die auf Ihrem
|
||||||
Endgerät
|
Endgerät abgelegt werden), die auf Ihrem Endgerät verbleiben und es uns ermöglichen, Ihren Browser beim
|
||||||
abgelegt werden), die auf Ihrem Endgerät verbleiben und es uns ermöglichen, Ihren Browser beim nächsten
|
nächsten Besuch wiederzuerkennen. Diese Cookies werden auf Ihrer Festplatte gespeichert und löschen sich
|
||||||
Besuch
|
nach der vorgegebenen Zeit von allein. Ihre Lebensdauer beträgt 1 Monat bis 10 Jahre. So können wir Ihnen
|
||||||
wiederzuerkennen. Diese Cookies werden auf Ihrer Festplatte gespeichert und löschen sich nach der
|
unser Angebot nutzerfreundlicher,
|
||||||
vorgegebenen Zeit
|
|
||||||
von allein. Ihre Lebensdauer beträgt 1 Monat bis 10 Jahre. So können wir Ihnen unser Angebot
|
|
||||||
nutzerfreundlicher,
|
|
||||||
effektiver und sicherer präsentieren und Ihnen beispielsweise speziell auf Ihre Interessen abgestimmte
|
effektiver und sicherer präsentieren und Ihnen beispielsweise speziell auf Ihre Interessen abgestimmte
|
||||||
Informationen
|
Informationen auf der Seite anzeigen.<br/>
|
||||||
auf der Seite anzeigen.<br/>
|
Unser berechtigtes Interesse an der Nutzung der Cookies gemäß Art 6 Abs. 1 S. 1 f) DSGVO liegt darin,
|
||||||
Unser berechtigtes Interesse an der Nutzung der Cookies gemäß Art 6 Abs. 1 S. 1 f) DSGVO liegt darin, unsere
|
unsere Website nutzerfreundlicher, effektiver und sicherer zu machen.<br/>
|
||||||
Website
|
|
||||||
nutzerfreundlicher, effektiver und sicherer zu machen.<br/>
|
|
||||||
In den Cookies werden etwa folgende Daten und Informationen gespeichert:
|
In den Cookies werden etwa folgende Daten und Informationen gespeichert:
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
|
|
@ -162,74 +125,53 @@ function PrivacyText(){
|
||||||
<p>
|
<p>
|
||||||
Bei Aktivierung des Cookies wird diesem eine Identifikationsnummer zugewiesen und eine Zuordnung Ihrer
|
Bei Aktivierung des Cookies wird diesem eine Identifikationsnummer zugewiesen und eine Zuordnung Ihrer
|
||||||
personenbezogenen Daten zu dieser Identifikationsnummer wird nicht vorgenommen. Ihr Name, Ihre IP-Adresse
|
personenbezogenen Daten zu dieser Identifikationsnummer wird nicht vorgenommen. Ihr Name, Ihre IP-Adresse
|
||||||
oder
|
oder ähnliche Daten, die eine Zuordnung des Cookies zu Ihnen ermöglichen würden, werden nicht in den Cookie
|
||||||
ähnliche Daten, die eine Zuordnung des Cookies zu Ihnen ermöglichen würden, werden nicht in den Cookie
|
eingelegt. Auf Basis der Cookie-Technologie erhalten wir lediglich pseudonymisierte Informationen,
|
||||||
eingelegt. Auf
|
beispielsweise darüber,
|
||||||
Basis der Cookie-Technologie erhalten wir lediglich pseudonymisierte Informationen, beispielsweise darüber,
|
welche Seiten unseres Shops besucht wurden, welche Produkte angesehen wurden, etc.<br/>
|
||||||
welche
|
|
||||||
Seiten unseres Shops besucht wurden, welche Produkte angesehen wurden, etc.<br/>
|
|
||||||
Sie können Ihren Browser so einstellen, dass Sie über das Setzen von Cookies vorab informiert werden und im
|
Sie können Ihren Browser so einstellen, dass Sie über das Setzen von Cookies vorab informiert werden und im
|
||||||
Einzelfall
|
Einzelfall entscheiden können, ob Sie die Annahme von Cookies für bestimmte Fälle oder generell
|
||||||
entscheiden können, ob Sie die Annahme von Cookies für bestimmte Fälle oder generell ausschließen, oder dass
|
ausschließen, oder dass Cookies komplett verhindert werden. Dadurch kann die Funktionalität der Website
|
||||||
Cookies
|
eingeschränkt werden. </p>
|
||||||
komplett verhindert werden. Dadurch kann die Funktionalität der Website eingeschränkt werden.
|
|
||||||
</p>
|
|
||||||
<h4>3.4 Nutzerkonto</h4>
|
<h4>3.4 Nutzerkonto</h4>
|
||||||
<p>Sie können auf unserer Website ein Nutzerkonto anlegen. Wünschen Sie dies, so benötigen wir die beim Login
|
<p>Sie können auf unserer Website ein Nutzerkonto anlegen. Wünschen Sie dies, so benötigen wir die beim Login
|
||||||
abgefragten
|
abgefragten personenbezogenen Daten. Beim späteren Einloggen werden nur Ihre Email bzw. Benutzername und das
|
||||||
personenbezogenen Daten. Beim späteren Einloggen werden nur Ihre Email bzw. Benutzername und das von Ihnen
|
von Ihnen gewählte Passwort benötigt.<br/>
|
||||||
gewählte
|
|
||||||
Passwort benötigt.<br/>
|
|
||||||
Für die Neuregistrierung erheben wir Stammdaten (z. B. Name, Adresse), Kommunikationsdaten (z. B.
|
Für die Neuregistrierung erheben wir Stammdaten (z. B. Name, Adresse), Kommunikationsdaten (z. B.
|
||||||
E-Mail-Adresse)
|
E-Mail-Adresse)
|
||||||
sowie Zugangsdaten (Benutzername u. Passwort).<br/>
|
sowie Zugangsdaten (Benutzername u. Passwort).<br/>
|
||||||
Sie können ein einmal angelegtes Nutzerkonto jederzeit von uns löschen lassen, ohne dass hierfür andere
|
Sie können ein einmal angelegtes Nutzerkonto jederzeit von uns löschen lassen, ohne dass hierfür andere als
|
||||||
als die
|
die Übermittlungskosten nach den Basistarifen entstehen. Eine Mitteilung in Textform an die unter Ziffer 1
|
||||||
Übermittlungskosten nach den Basistarifen entstehen. Eine Mitteilung in Textform an die unter Ziffer 1
|
genannten Kontaktdaten (z.B. E-Mail, Fax, Brief) reicht hierfür aus. Wir werden dann Ihre gespeicherten
|
||||||
genannten
|
personenbezogenen Daten löschen, soweit wir diese nicht noch zur Abwicklung von Bestellungen oder aufgrund
|
||||||
Kontaktdaten (z.B. E-Mail, Fax, Brief) reicht hierfür aus. Wir werden dann Ihre gespeicherten
|
gesetzlicher Aufbewahrungspflichten speichern müssen.<br/>
|
||||||
personenbezogenen Daten
|
|
||||||
löschen, soweit wir diese nicht noch zur Abwicklung von Bestellungen oder aufgrund gesetzlicher
|
|
||||||
Aufbewahrungspflichten
|
|
||||||
speichern müssen.<br/>
|
|
||||||
Rechtgrundlage für die Verarbeitung dieser Daten ist Ihre Einwilligung gemäß Art. 6 Abs. 1 S. 1 a)
|
Rechtgrundlage für die Verarbeitung dieser Daten ist Ihre Einwilligung gemäß Art. 6 Abs. 1 S. 1 a)
|
||||||
DSGVO.
|
DSGVO. </p>
|
||||||
</p>
|
|
||||||
<h4>3.5 E-Mail Kontakt</h4>
|
<h4>3.5 E-Mail Kontakt</h4>
|
||||||
<p>
|
<p>
|
||||||
Wenn Sie mit uns in Kontakt treten (z. B. per Kontaktformular oder E-Mail), verarbeiten wir Ihre Angaben zur
|
Wenn Sie mit uns in Kontakt treten (z. B. per Kontaktformular oder E-Mail), verarbeiten wir Ihre Angaben zur
|
||||||
Bearbeitung der Anfrage sowie für den Fall, dass Anschlussfragen entstehen.
|
Bearbeitung der Anfrage sowie für den Fall, dass Anschlussfragen entstehen. Erfolgt die Datenverarbeitung
|
||||||
Erfolgt die Datenverarbeitung zur Durchführung vorvertraglicher Maßnahmen, die auf Ihre Anfrage hin
|
zur Durchführung vorvertraglicher Maßnahmen, die auf Ihre Anfrage hin erfolgen, bzw.,
|
||||||
erfolgen, bzw.,
|
|
||||||
wenn Sie bereits unser Kunde sind, zur Durchführung des Vertrages, ist Rechtsgrundlage für diese
|
wenn Sie bereits unser Kunde sind, zur Durchführung des Vertrages, ist Rechtsgrundlage für diese
|
||||||
Datenverarbeitung
|
Datenverarbeitung Art. 6 Abs. 1 S. 1 b) DSGVO. Weitere personenbezogene Daten verarbeiten wir nur, wenn Sie
|
||||||
Art. 6 Abs. 1 S. 1 b) DSGVO.
|
dazu einwilligen (Art. 6 Abs. 1 S. 1 a)
|
||||||
Weitere personenbezogene Daten verarbeiten wir nur, wenn Sie dazu einwilligen (Art. 6 Abs. 1 S. 1 a) DSGVO)
|
DSGVO)
|
||||||
oder wir
|
oder wir ein berechtigtes Interesse an der Verarbeitung Ihrer Daten haben (Art. 6 Abs. 1 S. 1 f) DSGVO). Ein
|
||||||
ein berechtigtes Interesse an der Verarbeitung Ihrer Daten haben (Art. 6 Abs. 1 S. 1 f) DSGVO). Ein
|
berechtigtes Interesse liegt z. B. darin, auf Ihre E-Mail zu antworten. </p>
|
||||||
berechtigtes
|
|
||||||
Interesse liegt z. B. darin, auf Ihre E-Mail zu antworten.
|
|
||||||
</p>
|
|
||||||
<h3>4 Speicherdauer</h3>
|
<h3>4 Speicherdauer</h3>
|
||||||
<p>
|
<p>
|
||||||
Sofern nicht spezifisch angegeben speichern wir personenbezogene Daten nur so lange, wie dies zur Erfüllung
|
Sofern nicht spezifisch angegeben speichern wir personenbezogene Daten nur so lange, wie dies zur Erfüllung
|
||||||
der
|
der verfolgten Zwecke notwendig ist.<br/>
|
||||||
verfolgten Zwecke notwendig ist.<br/>
|
|
||||||
In einigen Fällen sieht der Gesetzgeber die Aufbewahrung von personenbezogenen Daten vor, etwa im Steuer-
|
In einigen Fällen sieht der Gesetzgeber die Aufbewahrung von personenbezogenen Daten vor, etwa im Steuer-
|
||||||
oder
|
oder Handelsrecht. In diesen Fällen werden die Daten von uns lediglich für diese gesetzlichen Zwecke weiter
|
||||||
Handelsrecht. In diesen Fällen werden die Daten von uns lediglich für diese gesetzlichen Zwecke weiter
|
|
||||||
gespeichert,
|
gespeichert,
|
||||||
aber nicht anderweitig verarbeitet und nach Ablauf der gesetzlichen Aufbewahrungsfrist gelöscht.
|
aber nicht anderweitig verarbeitet und nach Ablauf der gesetzlichen Aufbewahrungsfrist gelöscht. </p>
|
||||||
</p>
|
|
||||||
<h3>5 Ihre Rechte als von der Datenverarbeitung Betroffener</h3>
|
<h3>5 Ihre Rechte als von der Datenverarbeitung Betroffener</h3>
|
||||||
<p>
|
<p>
|
||||||
Nach den anwendbaren Gesetzen haben Sie verschiedene Rechte bezüglich Ihrer personenbezogenen Daten. Möchten
|
Nach den anwendbaren Gesetzen haben Sie verschiedene Rechte bezüglich Ihrer personenbezogenen Daten. Möchten
|
||||||
Sie diese
|
Sie diese Rechte geltend machen, so richten Sie Ihre Anfrage bitte per E-Mail oder per Post unter
|
||||||
Rechte geltend machen, so richten Sie Ihre Anfrage bitte per E-Mail oder per Post unter eindeutiger
|
eindeutiger Identifizierung Ihrer Person an die in Ziffer 1 genannte Adresse.<br/>
|
||||||
Identifizierung
|
Nachfolgend finden Sie eine Übersicht über Ihre Rechte. </p>
|
||||||
Ihrer Person an die in Ziffer 1 genannte Adresse.<br/>
|
|
||||||
Nachfolgend finden Sie eine Übersicht über Ihre Rechte.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h4>5.1 Recht auf Bestätigung und Auskunft</h4>
|
<h4>5.1 Recht auf Bestätigung und Auskunft</h4>
|
||||||
<p>
|
<p>
|
||||||
|
|
@ -238,58 +180,46 @@ function PrivacyText(){
|
||||||
Im Einzelnen:<br/>
|
Im Einzelnen:<br/>
|
||||||
|
|
||||||
Sie haben jederzeit das Recht, von uns eine Bestätigung darüber zu erhalten, ob Sie betreffende
|
Sie haben jederzeit das Recht, von uns eine Bestätigung darüber zu erhalten, ob Sie betreffende
|
||||||
personenbezogene Daten
|
personenbezogene Daten verarbeitet werden. Ist dies der Fall, so haben Sie das Recht, von uns eine
|
||||||
verarbeitet werden. Ist dies der Fall, so haben Sie das Recht, von uns eine unentgeltliche Auskunft über die
|
unentgeltliche Auskunft über die zu Ihnen gespeicherten personenbezogenen Daten nebst einer Kopie dieser
|
||||||
zu Ihnen
|
Daten zu verlangen. Des Weiteren besteht ein Recht auf folgende Informationen:
|
||||||
gespeicherten personenbezogenen Daten nebst einer Kopie dieser Daten zu verlangen. Des Weiteren besteht ein
|
|
||||||
Recht auf
|
|
||||||
folgende Informationen:
|
|
||||||
</p>
|
</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li>die Verarbeitungszwecke;</li>
|
<li>die Verarbeitungszwecke;</li>
|
||||||
<li>die Kategorien personenbezogener Daten, die verarbeitet werden;</li>
|
<li>die Kategorien personenbezogener Daten, die verarbeitet werden;</li>
|
||||||
<li>die Empfänger oder Kategorien von Empfängern, gegenüber denen die personenbezogenen Daten offengelegt
|
<li>die Empfänger oder Kategorien von Empfängern, gegenüber denen die personenbezogenen Daten offengelegt
|
||||||
worden sind
|
worden sind oder noch offengelegt werden, insbesondere bei Empfängern in Drittländern oder bei
|
||||||
oder noch offengelegt werden, insbesondere bei Empfängern in Drittländern oder bei internationalen
|
internationalen Organisationen;
|
||||||
Organisationen;
|
|
||||||
</li>
|
</li>
|
||||||
<li>falls möglich, die geplante Dauer, für die die personenbezogenen Daten gespeichert werden, oder, falls
|
<li>falls möglich, die geplante Dauer, für die die personenbezogenen Daten gespeichert werden, oder,
|
||||||
dies nicht
|
falls dies nicht möglich ist, die Kriterien für die Festlegung dieser Dauer;
|
||||||
möglich ist, die Kriterien für die Festlegung dieser Dauer;
|
|
||||||
</li>
|
</li>
|
||||||
<li>das Bestehen eines Rechts auf Berichtigung oder Löschung der Sie betreffenden personenbezogenen Daten
|
<li>das Bestehen eines Rechts auf Berichtigung oder Löschung der Sie betreffenden personenbezogenen Daten
|
||||||
oder auf
|
oder auf Einschränkung der Verarbeitung durch den Verantwortlichen oder eines Widerspruchsrechts gegen
|
||||||
Einschränkung der Verarbeitung durch den Verantwortlichen oder eines Widerspruchsrechts gegen diese
|
diese Verarbeitung;
|
||||||
Verarbeitung;
|
|
||||||
</li>
|
</li>
|
||||||
<li>das Bestehen eines Beschwerderechts bei einer Aufsichtsbehörde;</li>
|
<li>das Bestehen eines Beschwerderechts bei einer Aufsichtsbehörde;</li>
|
||||||
<li>wenn die personenbezogenen Daten nicht bei Ihnen erhoben werden, alle verfügbaren Informationen über die
|
<li>wenn die personenbezogenen Daten nicht bei Ihnen erhoben werden, alle verfügbaren Informationen über die
|
||||||
Herkunft
|
Herkunft der Daten;
|
||||||
der Daten;
|
|
||||||
</li>
|
</li>
|
||||||
<li>das Bestehen einer automatisierten Entscheidungsfindung einschließlich Profiling gemäß Art. 22 Abs. 1
|
<li>das Bestehen einer automatisierten Entscheidungsfindung einschließlich Profiling gemäß Art. 22 Abs. 1
|
||||||
und 4 DSGVO
|
und 4 DSGVO und – zumindest in diesen Fällen – aussagekräftige Informationen über die involvierte Logik
|
||||||
und – zumindest in diesen Fällen – aussagekräftige Informationen über die involvierte Logik sowie die
|
sowie die Tragweite und die angestrebten Auswirkungen einer derartigen Verarbeitung für Sie.
|
||||||
Tragweite
|
|
||||||
und die angestrebten Auswirkungen einer derartigen Verarbeitung für Sie.
|
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<p>
|
<p>
|
||||||
Werden personenbezogene Daten an ein Drittland oder an eine internationale Organisation übermittelt, so
|
Werden personenbezogene Daten an ein Drittland oder an eine internationale Organisation übermittelt, so
|
||||||
haben Sie das
|
haben Sie das Recht, über die geeigneten Garantien gemäß Art. 46 DSGVO im Zusammenhang mit der Übermittlung
|
||||||
Recht, über die geeigneten Garantien gemäß Art. 46 DSGVO im Zusammenhang mit der Übermittlung unterrichtet
|
unterrichtet zu werden. </p>
|
||||||
zu werden.
|
|
||||||
</p>
|
|
||||||
<h4>5.2 Recht auf Berichtigung</h4>
|
<h4>5.2 Recht auf Berichtigung</h4>
|
||||||
<p>
|
<p>
|
||||||
Sie haben das Recht, von uns die Berichtigung und ggf. auch Vervollständigung Sie betreffender
|
Sie haben das Recht, von uns die Berichtigung und ggf. auch Vervollständigung Sie betreffender
|
||||||
personenbezogener Daten
|
personenbezogener Daten zu verlangen.<br/>
|
||||||
zu verlangen.<br/>
|
|
||||||
Im Einzelnen:<br/>
|
Im Einzelnen:<br/>
|
||||||
Sie haben das Recht, von uns unverzüglich die Berichtigung Sie betreffender unrichtiger personenbezogener
|
Sie haben das Recht, von uns unverzüglich die Berichtigung Sie betreffender unrichtiger personenbezogener
|
||||||
Daten zu
|
Daten zu verlangen. Unter Berücksichtigung der Zwecke der Verarbeitung haben Sie das Recht, die
|
||||||
verlangen. Unter Berücksichtigung der Zwecke der Verarbeitung haben Sie das Recht, die Vervollständigung
|
Vervollständigung unvollständiger personenbezogener Daten – auch mittels einer ergänzenden Erklärung – zu
|
||||||
unvollständiger personenbezogener Daten – auch mittels einer ergänzenden Erklärung – zu verlangen.<br/>
|
verlangen.<br/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h4>5.3 Recht auf Löschung ("Recht auf Vergessenwerden")</h4>
|
<h4>5.3 Recht auf Löschung ("Recht auf Vergessenwerden")</h4>
|
||||||
|
|
@ -297,10 +227,9 @@ function PrivacyText(){
|
||||||
In einer Reihe von Fällen sind wir verpflichtet, Sie betreffende personenbezogene Daten zu löschen.<br/>
|
In einer Reihe von Fällen sind wir verpflichtet, Sie betreffende personenbezogene Daten zu löschen.<br/>
|
||||||
Im Einzelnen:<br/>
|
Im Einzelnen:<br/>
|
||||||
Sie haben gemäß Art. 17 Abs. 1 DSGVO das Recht, von uns zu verlangen, dass Sie betreffende personenbezogene
|
Sie haben gemäß Art. 17 Abs. 1 DSGVO das Recht, von uns zu verlangen, dass Sie betreffende personenbezogene
|
||||||
Daten
|
Daten unverzüglich gelöscht werden, und wir sind verpflichtet, personenbezogene Daten unverzüglich zu
|
||||||
unverzüglich gelöscht werden, und wir sind verpflichtet, personenbezogene Daten unverzüglich zu löschen,
|
löschen,
|
||||||
sofern einer
|
sofern einer der folgenden Gründe zutrifft:
|
||||||
der folgenden Gründe zutrifft:
|
|
||||||
</p>
|
</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li>Die personenbezogenen Daten sind für die Zwecke, für die sie erhoben oder auf sonstige Weise verarbeitet
|
<li>Die personenbezogenen Daten sind für die Zwecke, für die sie erhoben oder auf sonstige Weise verarbeitet
|
||||||
|
|
@ -308,58 +237,45 @@ function PrivacyText(){
|
||||||
nicht mehr notwendig.
|
nicht mehr notwendig.
|
||||||
</li>
|
</li>
|
||||||
<li>Sie widerrufen Ihre Einwilligung, auf die sich die Verarbeitung gemäß Art. 6 Abs. 1 S. 1 a) DSGVO oder
|
<li>Sie widerrufen Ihre Einwilligung, auf die sich die Verarbeitung gemäß Art. 6 Abs. 1 S. 1 a) DSGVO oder
|
||||||
Art. 9 Abs.
|
Art. 9 Abs. 2 a) DSGVO stützte, und es fehlt an einer anderweitigen Rechtsgrundlage für die
|
||||||
2 a) DSGVO stützte, und es fehlt an einer anderweitigen Rechtsgrundlage für die Verarbeitung.
|
Verarbeitung.
|
||||||
</li>
|
</li>
|
||||||
<li>Sie legen gemäß Art. 21 Abs. 1 DSGVO Widerspruch gegen die Verarbeitung ein und es liegen keine
|
<li>Sie legen gemäß Art. 21 Abs. 1 DSGVO Widerspruch gegen die Verarbeitung ein und es liegen keine
|
||||||
vorrangigen
|
vorrangigen berechtigten Gründe für die Verarbeitung vor, oder Sie legen gemäß Art. 21 Abs. 2 DSGVO
|
||||||
berechtigten Gründe für die Verarbeitung vor, oder Sie legen gemäß Art. 21 Abs. 2 DSGVO Widerspruch
|
Widerspruch gegen die Verarbeitung ein.
|
||||||
gegen die
|
|
||||||
Verarbeitung ein.
|
|
||||||
</li>
|
</li>
|
||||||
<li>Die personenbezogenen Daten wurden unrechtmäßig verarbeitet.</li>
|
<li>Die personenbezogenen Daten wurden unrechtmäßig verarbeitet.</li>
|
||||||
<li>Die Löschung der personenbezogenen Daten ist zur Erfüllung einer rechtlichen Verpflichtung nach dem
|
<li>Die Löschung der personenbezogenen Daten ist zur Erfüllung einer rechtlichen Verpflichtung nach dem
|
||||||
Unionsrecht
|
Unionsrecht oder dem Recht der Mitgliedstaaten erforderlich, dem wir unterliegen.
|
||||||
oder dem Recht der Mitgliedstaaten erforderlich, dem wir unterliegen.
|
|
||||||
</li>
|
</li>
|
||||||
<li>Die personenbezogenen Daten wurden in Bezug auf angebotene Dienste der Informationsgesellschaft gemäß
|
<li>Die personenbezogenen Daten wurden in Bezug auf angebotene Dienste der Informationsgesellschaft gemäß
|
||||||
Art. 8 Abs.
|
Art. 8 Abs. 1 DSGVO erhoben.
|
||||||
1 DSGVO erhoben.
|
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<p>
|
<p>
|
||||||
Haben wir die personenbezogenen Daten öffentlich gemacht und sind wir gemäß Art. 17 Abs. 1 DSGVO zu deren
|
Haben wir die personenbezogenen Daten öffentlich gemacht und sind wir gemäß Art. 17 Abs. 1 DSGVO zu deren
|
||||||
Löschung
|
Löschung verpflichtet, so treffen wir unter Berücksichtigung der verfügbaren Technologie und der
|
||||||
verpflichtet, so treffen wir unter Berücksichtigung der verfügbaren Technologie und der
|
Implementierungskosten angemessene Maßnahmen, auch technischer Art, um für die Datenverarbeitung
|
||||||
Implementierungskosten
|
Verantwortliche, die die personenbezogenen Daten verarbeiten, darüber zu informieren, dass Sie von ihnen die
|
||||||
angemessene Maßnahmen, auch technischer Art, um für die Datenverarbeitung Verantwortliche, die die
|
Löschung aller Links zu diesen personenbezogenen Daten oder von Kopien oder Replikationen dieser
|
||||||
personenbezogenen
|
personenbezogenen Daten verlangt haben. </p>
|
||||||
Daten verarbeiten, darüber zu informieren, dass Sie von ihnen die Löschung aller Links zu diesen
|
|
||||||
personenbezogenen
|
|
||||||
Daten oder von Kopien oder Replikationen dieser personenbezogenen Daten verlangt haben.
|
|
||||||
</p>
|
|
||||||
<h4>5.4 Recht auf Einschränkung der Verarbeitung</h4>
|
<h4>5.4 Recht auf Einschränkung der Verarbeitung</h4>
|
||||||
<p>
|
<p>
|
||||||
In einer Reihe von Fällen sind Sie berechtigt, von uns eine Einschränkung der Verarbeitung Ihrer
|
In einer Reihe von Fällen sind Sie berechtigt, von uns eine Einschränkung der Verarbeitung Ihrer
|
||||||
personenbezogenen
|
personenbezogenen Daten zu verlangen.<br/>
|
||||||
Daten zu verlangen.<br/>
|
|
||||||
Im Einzelnen:<br/>
|
Im Einzelnen:<br/>
|
||||||
Sie haben das Recht, von uns die Einschränkung der Verarbeitung zu verlangen, wenn eine der folgenden
|
Sie haben das Recht, von uns die Einschränkung der Verarbeitung zu verlangen, wenn eine der folgenden
|
||||||
Voraussetzungen
|
Voraussetzungen gegeben ist:
|
||||||
gegeben ist:
|
|
||||||
</p>
|
</p>
|
||||||
<ol>
|
<ol>
|
||||||
<li>die Richtigkeit der personenbezogenen Daten wird von Ihnen bestritten, und zwar für eine Dauer, die es
|
<li>die Richtigkeit der personenbezogenen Daten wird von Ihnen bestritten, und zwar für eine Dauer, die es
|
||||||
uns
|
uns ermöglicht, die Richtigkeit der personenbezogenen Daten zu überprüfen,
|
||||||
ermöglicht, die Richtigkeit der personenbezogenen Daten zu überprüfen,
|
|
||||||
</li>
|
</li>
|
||||||
<li>die Verarbeitung unrechtmäßig ist und Sie die Löschung der personenbezogenen Daten ablehnten und
|
<li>die Verarbeitung unrechtmäßig ist und Sie die Löschung der personenbezogenen Daten ablehnten und
|
||||||
stattdessen die
|
stattdessen die Einschränkung der Nutzung der personenbezogenen Daten verlangt haben;
|
||||||
Einschränkung der Nutzung der personenbezogenen Daten verlangt haben;
|
|
||||||
</li>
|
</li>
|
||||||
<li>wir die personenbezogenen Daten für die Zwecke der Verarbeitung nicht länger benötigen, Sie die Daten
|
<li>wir die personenbezogenen Daten für die Zwecke der Verarbeitung nicht länger benötigen, Sie die Daten
|
||||||
jedoch zur
|
jedoch zur Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen benötigen, oder
|
||||||
Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen benötigen, oder
|
|
||||||
</li>
|
</li>
|
||||||
<li>Sie Widerspruch gegen die Verarbeitung gemäß Art. 21 Abs. 1 DSGVO eingelegt haben, solange noch nicht
|
<li>Sie Widerspruch gegen die Verarbeitung gemäß Art. 21 Abs. 1 DSGVO eingelegt haben, solange noch nicht
|
||||||
feststeht,
|
feststeht,
|
||||||
|
|
@ -369,29 +285,21 @@ function PrivacyText(){
|
||||||
<h4>5.5 Recht auf Datenübertragbarkeit</h4>
|
<h4>5.5 Recht auf Datenübertragbarkeit</h4>
|
||||||
<p>
|
<p>
|
||||||
Sie haben das Recht, Sie betreffende personenbezogene Daten maschinenlesbar zu erhalten, zu übermitteln,
|
Sie haben das Recht, Sie betreffende personenbezogene Daten maschinenlesbar zu erhalten, zu übermitteln,
|
||||||
oder von uns
|
oder von uns übermitteln zu lasen.<br/>
|
||||||
übermitteln zu lasen.<br/>
|
|
||||||
Im Einzelnen:<br/>
|
Im Einzelnen:<br/>
|
||||||
Sie haben das Recht, die Sie betreffenden personenbezogenen Daten, die Sie uns bereitgestellt haben, in
|
Sie haben das Recht, die Sie betreffenden personenbezogenen Daten, die Sie uns bereitgestellt haben, in
|
||||||
einem
|
einem strukturierten, gängigen und maschinenlesbaren Format zu erhalten, und Sie haben das Recht, diese
|
||||||
strukturierten, gängigen und maschinenlesbaren Format zu erhalten, und Sie haben das Recht, diese Daten
|
Daten einem anderen Verantwortlichen ohne Behinderung durch uns zu übermitteln, sofern </p>
|
||||||
einem anderen
|
|
||||||
Verantwortlichen ohne Behinderung durch uns zu übermitteln, sofern
|
|
||||||
</p>
|
|
||||||
<ol>
|
<ol>
|
||||||
<li>die Verarbeitung auf einer Einwilligung gemäß Art. 6 Abs. 1 S. 1 a) DSGVO oder Art. 9 Abs. 2 a) DSGVO
|
<li>die Verarbeitung auf einer Einwilligung gemäß Art. 6 Abs. 1 S. 1 a) DSGVO oder Art. 9 Abs. 2 a)
|
||||||
oder auf
|
DSGVO oder auf einem Vertrag gemäß Art. 6 Abs. 1 S. 1 b) DSGVO beruht und
|
||||||
einem Vertrag gemäß Art. 6 Abs. 1 S. 1 b) DSGVO beruht und
|
|
||||||
</li>
|
</li>
|
||||||
<li>die Verarbeitung mithilfe automatisierter Verfahren erfolgt.</li>
|
<li>die Verarbeitung mithilfe automatisierter Verfahren erfolgt.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<p>
|
<p>
|
||||||
Bei der Ausübung Ihres Rechts auf Datenübertragbarkeit gemäß Absatz 1 haben Sie das Recht, zu erwirken, dass
|
Bei der Ausübung Ihres Rechts auf Datenübertragbarkeit gemäß Absatz 1 haben Sie das Recht, zu erwirken,
|
||||||
die
|
dass die personenbezogenen Daten direkt von uns einem anderen Verantwortlichen übermittelt werden, soweit
|
||||||
personenbezogenen Daten direkt von uns einem anderen Verantwortlichen übermittelt werden, soweit dies
|
dies technisch machbar ist. </p>
|
||||||
technisch
|
|
||||||
machbar ist.
|
|
||||||
</p>
|
|
||||||
<h4>5.6 Widerspruchsrecht</h4>
|
<h4>5.6 Widerspruchsrecht</h4>
|
||||||
<p>
|
<p>
|
||||||
Sie haben das Recht, auch einer rechtmäßigen Verarbeitung Ihrer personenbezogenen Daten durch uns zu
|
Sie haben das Recht, auch einer rechtmäßigen Verarbeitung Ihrer personenbezogenen Daten durch uns zu
|
||||||
|
|
@ -400,82 +308,67 @@ function PrivacyText(){
|
||||||
überwiegen.<br/>
|
überwiegen.<br/>
|
||||||
Im Einzelnen:<br/>
|
Im Einzelnen:<br/>
|
||||||
Sie haben das Recht, aus Gründen, die sich aus Ihrer besonderen Situation ergeben, jederzeit gegen die
|
Sie haben das Recht, aus Gründen, die sich aus Ihrer besonderen Situation ergeben, jederzeit gegen die
|
||||||
Verarbeitung
|
Verarbeitung Sie betreffender personenbezogener Daten, die aufgrund von Art. 6 Abs. 1 S. 1 e) oder f) DSGVO
|
||||||
Sie betreffender personenbezogener Daten, die aufgrund von Art. 6 Abs. 1 S. 1 e) oder f) DSGVO erfolgt,
|
erfolgt,
|
||||||
Widerspruch
|
Widerspruch einzulegen; dies gilt auch für ein auf diese Bestimmungen gestütztes Profiling. Wir verarbeiten
|
||||||
einzulegen; dies gilt auch für ein auf diese Bestimmungen gestütztes Profiling. Wir verarbeiten die
|
die personenbezogenen Daten nicht mehr, es sei denn, wir können zwingende schutzwürdige Gründe für die
|
||||||
personenbezogenen
|
Verarbeitung nachweisen,
|
||||||
Daten nicht mehr, es sei denn, wir können zwingende schutzwürdige Gründe für die Verarbeitung nachweisen,
|
die Ihre Interessen, Rechte und Freiheiten überwiegen, oder die Verarbeitung dient der Geltendmachung,
|
||||||
die Ihre
|
Ausübung oder Verteidigung von Rechtsansprüchen.<br/>
|
||||||
Interessen, Rechte und Freiheiten überwiegen, oder die Verarbeitung dient der Geltendmachung, Ausübung oder
|
|
||||||
Verteidigung von Rechtsansprüchen.<br/>
|
|
||||||
Werden personenbezogene Daten von uns verarbeitet, um Direktwerbung zu betreiben, so haben Sie das Recht,
|
Werden personenbezogene Daten von uns verarbeitet, um Direktwerbung zu betreiben, so haben Sie das Recht,
|
||||||
jederzeit
|
jederzeit Widerspruch gegen die Verarbeitung Sie betreffender personenbezogener Daten zum Zwecke derartiger
|
||||||
Widerspruch gegen die Verarbeitung Sie betreffender personenbezogener Daten zum Zwecke derartiger Werbung
|
Werbung einzulegen;
|
||||||
einzulegen;
|
|
||||||
dies gilt auch für das Profiling, soweit es mit solcher Direktwerbung in Verbindung steht.<br/>
|
dies gilt auch für das Profiling, soweit es mit solcher Direktwerbung in Verbindung steht.<br/>
|
||||||
Sie haben das Recht, aus Gründen, die sich aus Ihrer besonderen Situation ergeben, gegen die Sie betreffende
|
Sie haben das Recht, aus Gründen, die sich aus Ihrer besonderen Situation ergeben, gegen die Sie betreffende
|
||||||
Verarbeitung Sie betreffender personenbezogener Daten, die zu wissenschaftlichen oder historischen
|
Verarbeitung Sie betreffender personenbezogener Daten, die zu wissenschaftlichen oder historischen
|
||||||
Forschungszwecken
|
Forschungszwecken oder zu statistischen Zwecken gemäß Art. 89 Abs. 1 DSGVO erfolgt, Widerspruch einzulegen,
|
||||||
oder zu statistischen Zwecken gemäß Art. 89 Abs. 1 DSGVO erfolgt, Widerspruch einzulegen, es sei denn, die
|
es sei denn,
|
||||||
Verarbeitung ist zur Erfüllung einer im öffentlichen Interesse liegenden Aufgabe erforderlich.<br/>
|
die Verarbeitung ist zur Erfüllung einer im öffentlichen Interesse liegenden Aufgabe erforderlich.<br/>
|
||||||
</p>
|
</p>
|
||||||
<h4>5.7 Automatisierte Entscheidungen einschließlich Profiling</h4>
|
<h4>5.7 Automatisierte Entscheidungen einschließlich Profiling</h4>
|
||||||
<p>
|
<p>
|
||||||
Sie haben das Recht, nicht einer ausschließlich auf einer automatisierten Verarbeitung – einschließlich
|
Sie haben das Recht, nicht einer ausschließlich auf einer automatisierten Verarbeitung – einschließlich
|
||||||
Profiling –
|
Profiling –
|
||||||
beruhenden Entscheidung unterworfen zu werden, die Ihnen gegenüber rechtliche Wirkung entfaltet oder Sie in
|
beruhenden Entscheidung unterworfen zu werden, die Ihnen gegenüber rechtliche Wirkung entfaltet oder Sie in
|
||||||
ähnlicher
|
ähnlicher Weise erheblich beeinträchtigt.<br/>
|
||||||
Weise erheblich beeinträchtigt.<br/>
|
|
||||||
Eine automatisierte Entscheidungsfindung auf der Grundlage der erhobenen personenbezogenen Daten findet
|
Eine automatisierte Entscheidungsfindung auf der Grundlage der erhobenen personenbezogenen Daten findet
|
||||||
nicht statt.
|
nicht statt. </p>
|
||||||
</p>
|
|
||||||
<h4>5.8 Recht auf Widerruf einer datenschutzrechtlichen Einwilligung</h4>
|
<h4>5.8 Recht auf Widerruf einer datenschutzrechtlichen Einwilligung</h4>
|
||||||
<p>
|
<p>
|
||||||
Sie haben das Recht, eine Einwilligung zur Verarbeitung personenbezogener Daten jederzeit zu widerrufen.
|
Sie haben das Recht, eine Einwilligung zur Verarbeitung personenbezogener Daten jederzeit zu
|
||||||
</p>
|
widerrufen. </p>
|
||||||
|
|
||||||
<h4>5.9 Recht auf Beschwerde bei einer Aufsichtsbehörde</h4>
|
<h4>5.9 Recht auf Beschwerde bei einer Aufsichtsbehörde</h4>
|
||||||
<p>
|
<p>
|
||||||
Sie haben das Recht auf Beschwerde bei einer Aufsichtsbehörde, insbesondere in dem Mitgliedstaat Ihres
|
Sie haben das Recht auf Beschwerde bei einer Aufsichtsbehörde, insbesondere in dem Mitgliedstaat Ihres
|
||||||
Aufenthaltsorts, Ihres Arbeitsplatzes oder des Orts des mutmaßlichen Verstoßes, wenn Sie der Ansicht sind,
|
Aufenthaltsorts, Ihres Arbeitsplatzes oder des Orts des mutmaßlichen Verstoßes, wenn Sie der Ansicht sind,
|
||||||
dass die
|
dass die Verarbeitung der Sie betreffenden personenbezogenen Daten rechtswidrig ist. </p>
|
||||||
Verarbeitung der Sie betreffenden personenbezogenen Daten rechtswidrig ist.
|
|
||||||
</p>
|
|
||||||
<h3>6 Datensicherheit</h3>
|
<h3>6 Datensicherheit</h3>
|
||||||
<p>
|
<p>
|
||||||
Wir sind um die Sicherheit Ihrer Daten im Rahmen der geltenden Datenschutzgesetze und technischen
|
Wir sind um die Sicherheit Ihrer Daten im Rahmen der geltenden Datenschutzgesetze und technischen
|
||||||
Möglichkeiten
|
Möglichkeiten maximal bemüht.<br/>
|
||||||
maximal bemüht.<br/>
|
|
||||||
Ihre persönlichen Daten werden bei uns verschlüsselt übertragen. Dies gilt für Ihre Bestellungen und auch
|
Ihre persönlichen Daten werden bei uns verschlüsselt übertragen. Dies gilt für Ihre Bestellungen und auch
|
||||||
für das
|
für das Kundenlogin. Wir nutzen das Codierungssystem SSL (Secure Socket Layer), weisen jedoch darauf hin,
|
||||||
Kundenlogin. Wir nutzen das Codierungssystem SSL (Secure Socket Layer), weisen jedoch darauf hin, dass die
|
dass die Datenübertragung im Internet (z.B. bei der Kommunikation per E-Mail) Sicherheitslücken aufweisen
|
||||||
Datenübertragung im Internet (z.B. bei der Kommunikation per E-Mail) Sicherheitslücken aufweisen kann. Ein
|
kann. Ein lückenloser Schutz der Daten vor dem Zugriff durch Dritte ist nicht möglich.<br/>
|
||||||
lückenloser
|
|
||||||
Schutz der Daten vor dem Zugriff durch Dritte ist nicht möglich.<br/>
|
|
||||||
Zur Sicherung Ihrer Daten unterhalten wir technische und organisatorische Sicherungsmaßnahmen entsprechend
|
Zur Sicherung Ihrer Daten unterhalten wir technische und organisatorische Sicherungsmaßnahmen entsprechend
|
||||||
Art. 32
|
Art. 32 DSGVO, die wir immer wieder dem Stand der Technik anpassen.<br/>
|
||||||
DSGVO, die wir immer wieder dem Stand der Technik anpassen.<br/>
|
Wir gewährleisten außerdem nicht, dass unser Angebot zu bestimmten Zeiten zur Verfügung steht;
|
||||||
Wir gewährleisten außerdem nicht, dass unser Angebot zu bestimmten Zeiten zur Verfügung steht; Störungen,
|
Störungen,
|
||||||
Unterbrechungen oder Ausfälle können nicht ausgeschlossen werden. Die von uns verwendeten Server werden
|
Unterbrechungen oder Ausfälle können nicht ausgeschlossen werden. Die von uns verwendeten Server werden
|
||||||
regelmäßig
|
regelmäßig sorgfältig gesichert. </p>
|
||||||
sorgfältig gesichert.
|
|
||||||
</p>
|
|
||||||
<h3>7 Weitergabe von Daten an Dritte, keine Datenübertragung ins Nicht-EU-Ausland</h3>
|
<h3>7 Weitergabe von Daten an Dritte, keine Datenübertragung ins Nicht-EU-Ausland</h3>
|
||||||
<p>
|
<p>
|
||||||
Grundsätzlich verwenden wir Ihre personenbezogenen Daten nur innerhalb unseres Unternehmens.<br/>
|
Grundsätzlich verwenden wir Ihre personenbezogenen Daten nur innerhalb unseres Unternehmens.<br/>
|
||||||
Wenn und soweit wir Dritte im Rahmen der Erfüllung von Verträgen einschalten (etwa Logistik-Dienstleister),
|
Wenn und soweit wir Dritte im Rahmen der Erfüllung von Verträgen einschalten (etwa Logistik-Dienstleister),
|
||||||
erhalten
|
erhalten diese personenbezogene Daten nur in dem Umfang, in welchem die Übermittlung für die entsprechende
|
||||||
diese personenbezogene Daten nur in dem Umfang, in welchem die Übermittlung für die entsprechende Leistung
|
Leistung erforderlich ist.<br/>
|
||||||
erforderlich ist.<br/>
|
|
||||||
Für den Fall, dass wir bestimmte Teile der Datenverarbeitung auslagern („Auftragsverarbeitung“),
|
Für den Fall, dass wir bestimmte Teile der Datenverarbeitung auslagern („Auftragsverarbeitung“),
|
||||||
verpflichten wir
|
verpflichten wir Auftragsverarbeiter vertraglich dazu, personenbezogene Daten nur im Einklang mit den
|
||||||
Auftragsverarbeiter vertraglich dazu, personenbezogene Daten nur im Einklang mit den Anforderungen der
|
Anforderungen der Datenschutzgesetze zu verwenden und den Schutz der Rechte der betroffenen Person zu
|
||||||
Datenschutzgesetze zu verwenden und den Schutz der Rechte der betroffenen Person zu gewährleisten.<br/>
|
gewährleisten.<br/>
|
||||||
Eine Datenübertragung an Stellen oder Personen außerhalb der EU außerhalb des in dieser Erklärung in Ziffer
|
Eine Datenübertragung an Stellen oder Personen außerhalb der EU außerhalb des in dieser Erklärung in Ziffer
|
||||||
4
|
4 genannten Falls findet nicht statt und ist nicht geplant. </p>
|
||||||
genannten Falls findet nicht statt und ist nicht geplant.
|
|
||||||
</p>
|
|
||||||
<h3>8 Datenschutzbeauftragter</h3>
|
<h3>8 Datenschutzbeauftragter</h3>
|
||||||
<p>
|
<p>
|
||||||
Sollten Sie noch Fragen oder Bedenken zum Datenschutz haben, so wenden Sie sich bitte an unseren
|
Sollten Sie noch Fragen oder Bedenken zum Datenschutz haben, so wenden Sie sich bitte an unseren
|
||||||
|
|
@ -486,18 +379,14 @@ function PrivacyText(){
|
||||||
August-Euler-Weg 3<br/>
|
August-Euler-Weg 3<br/>
|
||||||
76133 Karlsruhe<br/>
|
76133 Karlsruhe<br/>
|
||||||
Germany<br/>
|
Germany<br/>
|
||||||
jon@s-seydel.de
|
jon@s-seydel.de </p>
|
||||||
</p>
|
</Container>);
|
||||||
</Container>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default class PrivacyPage extends React.Component {
|
export default class PrivacyPage extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<div>
|
||||||
<div>
|
|
||||||
<Head>
|
<Head>
|
||||||
<title>Datenschutzerklärung: turnie.re</title>
|
<title>Datenschutzerklärung: turnie.re</title>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
@ -505,7 +394,6 @@ export default class PrivacyPage extends React.Component {
|
||||||
<BigImage text="Datenschutzerklärung"/>
|
<BigImage text="Datenschutzerklärung"/>
|
||||||
<Main/>
|
<Main/>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {connect} from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
|
|
||||||
import {Card, CardBody, Container,} from 'reactstrap';
|
import {Card, CardBody, Container} from 'reactstrap';
|
||||||
|
|
||||||
import {TurniereNavigation} from '../js/components/Navigation';
|
import {TurniereNavigation} from '../js/components/Navigation';
|
||||||
import {Footer} from '../js/components/Footer';
|
import {Footer} from '../js/components/Footer';
|
||||||
|
|
@ -13,12 +13,10 @@ import '../static/everypage.css';
|
||||||
import TournamentList from '../js/components/TournamentList';
|
import TournamentList from '../js/components/TournamentList';
|
||||||
|
|
||||||
class PrivateTournamentsPage extends React.Component {
|
class PrivateTournamentsPage extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {isSignedIn} = this.props;
|
const {isSignedIn} = this.props;
|
||||||
|
|
||||||
return (
|
return (<UserRestrictor>
|
||||||
<UserRestrictor>
|
|
||||||
<Option condition={isSignedIn}>
|
<Option condition={isSignedIn}>
|
||||||
<div className="main generic-fullpage-bg">
|
<div className="main generic-fullpage-bg">
|
||||||
<Head>
|
<Head>
|
||||||
|
|
@ -42,8 +40,7 @@ class PrivateTournamentsPage extends React.Component {
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
</Option>
|
</Option>
|
||||||
</UserRestrictor>
|
</UserRestrictor>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,9 +49,7 @@ function mapStateToProperties(state) {
|
||||||
return {isSignedIn};
|
return {isSignedIn};
|
||||||
}
|
}
|
||||||
|
|
||||||
const PrivateTournamentListPage = connect(
|
const PrivateTournamentListPage = connect(mapStateToProperties)(PrivateTournamentsPage);
|
||||||
mapStateToProperties,
|
|
||||||
)(PrivateTournamentsPage);
|
|
||||||
|
|
||||||
export default PrivateTournamentListPage;
|
export default PrivateTournamentListPage;
|
||||||
|
|
||||||
|
|
@ -71,13 +66,11 @@ function PrivateTournamentsPageContent() {
|
||||||
|
|
||||||
class PrivateTournamentsCard extends React.Component {
|
class PrivateTournamentsCard extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<Card className="shadow">
|
||||||
<Card className="shadow">
|
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<h1 className="custom-font">Private Turniere</h1>
|
<h1 className="custom-font">Private Turniere</h1>
|
||||||
<TournamentList type='private'/>
|
<TournamentList type='private'/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,29 +1,20 @@
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button, Card, CardBody, Container, Form, FormGroup, FormText, Input, Label
|
||||||
Card,
|
|
||||||
CardBody,
|
|
||||||
Container,
|
|
||||||
Form,
|
|
||||||
FormGroup,
|
|
||||||
FormText,
|
|
||||||
Input,
|
|
||||||
Label
|
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
|
|
||||||
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 {register} from '../js/api';
|
||||||
|
|
||||||
import '../static/css/errormessages.css';
|
import '../static/css/errormessages.css';
|
||||||
import '../static/everypage.css';
|
import '../static/everypage.css';
|
||||||
|
|
||||||
export default class RegisterPage extends React.Component {
|
export default class RegisterPage extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
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>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
@ -33,16 +24,13 @@ export default class RegisterPage extends React.Component {
|
||||||
<AccountRequirementMarketing/>
|
<AccountRequirementMarketing/>
|
||||||
</div>
|
</div>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Register extends React.Component {
|
class Register extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<Container className="py-5">
|
||||||
<Container className="py-5">
|
|
||||||
<Card className="shadow">
|
<Card className="shadow">
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<h1 className="custom-font">Account anlegen</h1>
|
<h1 className="custom-font">Account anlegen</h1>
|
||||||
|
|
@ -52,97 +40,87 @@ class Register extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
</Container>
|
</Container>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RegisterErrorList extends React.Component {
|
class RegisterErrorList extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const { error, errorMessages } = this.props;
|
const {error, errorMessages} = this.props;
|
||||||
if(error) {
|
if (error) {
|
||||||
return (
|
return (<ul className="mt-3 error-box">
|
||||||
<ul className="mt-3 error-box">
|
{errorMessages.map((message, index) => <li key={index}>{message}</li>)}
|
||||||
{ errorMessages.map((message, index) =>
|
</ul>);
|
||||||
<li key={index}>{message}</li>
|
|
||||||
) }
|
|
||||||
</ul>
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToErrorMessages = (state) => {
|
const mapStateToErrorMessages = state => {
|
||||||
const { errorMessages, error } = state.userinfo;
|
const {errorMessages, error} = state.userinfo;
|
||||||
return { errorMessages, error };
|
return {errorMessages, error};
|
||||||
};
|
};
|
||||||
|
|
||||||
const VisibleRegisterErrorList = connect(
|
const VisibleRegisterErrorList = connect(mapStateToErrorMessages)(RegisterErrorList);
|
||||||
mapStateToErrorMessages
|
|
||||||
)(RegisterErrorList);
|
|
||||||
|
|
||||||
class RegisterForm extends React.Component {
|
class RegisterForm extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
username : '',
|
username: '', email: '', password: ''
|
||||||
email : '',
|
|
||||||
password : ''
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<Form>
|
||||||
<Form>
|
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="username">Benutzername</Label>
|
<Label for="username">Benutzername</Label>
|
||||||
<Input name="username" value={this.state.username} onChange={ this.handleUsernameInput.bind(this) } />
|
<Input name="username" value={this.state.username} onChange={this.handleUsernameInput.bind(this)}/>
|
||||||
<FormText>Wenn du anderen dein Turnier zeigst, können sie deinen Benutzernamen sehen.</FormText>
|
<FormText>Wenn du anderen dein Turnier zeigst, können sie deinen Benutzernamen sehen.</FormText>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="email">E-Mail-Adresse</Label>
|
<Label for="email">E-Mail-Adresse</Label>
|
||||||
<Input type="email" name="email" value={this.state.email} onChange={ this.handleEmailInput.bind(this) } />
|
<Input type="email" name="email" value={this.state.email}
|
||||||
|
onChange={this.handleEmailInput.bind(this)}/>
|
||||||
<FormText>Deine E-Mail-Adresse kann nur von dir gesehen werden.</FormText>
|
<FormText>Deine E-Mail-Adresse kann nur von dir gesehen werden.</FormText>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Label for="password">Passwort</Label>
|
<Label for="password">Passwort</Label>
|
||||||
<Input type="password" name="password" value={this.state.password} onChange={ this.handlePasswordInput.bind(this) } />
|
<Input type="password" name="password" value={this.state.password}
|
||||||
|
onChange={this.handlePasswordInput.bind(this)}/>
|
||||||
<FormText>Dein Passwort muss mindestens 12 Zeichen lang sein. Alle Zeichen sind erlaubt.</FormText>
|
<FormText>Dein Passwort muss mindestens 12 Zeichen lang sein. Alle Zeichen sind erlaubt.</FormText>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormText className="mb-2 mt-4">
|
<FormText className="mb-2 mt-4">
|
||||||
Du akzeptierst die <a href="/privacy">Datenschutzbestimmungen</a>, wenn du auf Registrieren klickst.
|
Du akzeptierst die <a href="/privacy">Datenschutzbestimmungen</a>, wenn du auf Registrieren klickst.
|
||||||
</FormText>
|
</FormText>
|
||||||
<Button onClick={ register.bind(this, this.state.username, this.state.email, this.state.password) } color="success" size="lg" className="w-100 shadow-sm">Registrieren</Button>
|
<Button onClick={register.bind(this, this.state.username, this.state.email, this.state.password)}
|
||||||
|
color="success" size="lg" className="w-100 shadow-sm">Registrieren</Button>
|
||||||
<VisibleRegisterErrorList/>
|
<VisibleRegisterErrorList/>
|
||||||
</Form>
|
</Form>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePasswordInput(input) {
|
handlePasswordInput(input) {
|
||||||
this.setState({ password : input.target.value });
|
this.setState({password: input.target.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleEmailInput(input) {
|
handleEmailInput(input) {
|
||||||
this.setState({ email : input.target.value });
|
this.setState({email: input.target.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUsernameInput(input) {
|
handleUsernameInput(input) {
|
||||||
this.setState({ username : input.target.value });
|
this.setState({username: input.target.value});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function AccountRequirementMarketing() {
|
function AccountRequirementMarketing() {
|
||||||
return (
|
return (<Container>
|
||||||
<Container>
|
|
||||||
<Card id="account-requirement">
|
<Card id="account-requirement">
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<h3 className="custom-font">Warum ein Account nötig ist</h3>
|
<h3 className="custom-font">Warum ein Account nötig ist</h3>
|
||||||
<p>Du benötigst deinen Account, damit nur du dein Turnier bearbeiten kannst.</p>
|
<p>Du benötigst deinen Account, damit nur du dein Turnier bearbeiten kannst.</p>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
</Container>
|
</Container>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,19 @@
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import { notify } from 'react-notify-toast';
|
import {notify} from 'react-notify-toast';
|
||||||
import {
|
import {
|
||||||
Container,
|
Container, Button, Card, CardBody, Table
|
||||||
Button,
|
|
||||||
Card,
|
|
||||||
CardBody,
|
|
||||||
Table
|
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
|
|
||||||
import { requestTournament } from '../js/api';
|
import {requestTournament} from '../js/api';
|
||||||
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 { UserRestrictor, Option } from '../js/components/UserRestrictor';
|
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 { updateTeamName } from '../js/api';
|
import {updateTeamName} from '../js/api';
|
||||||
|
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
||||||
|
|
@ -25,7 +21,6 @@ import '../static/everypage.css';
|
||||||
import '../static/css/index.css';
|
import '../static/css/index.css';
|
||||||
|
|
||||||
class EditTournamentPage extends React.Component {
|
class EditTournamentPage extends React.Component {
|
||||||
|
|
||||||
static async getInitialProps({query}) {
|
static async getInitialProps({query}) {
|
||||||
return {query};
|
return {query};
|
||||||
}
|
}
|
||||||
|
|
@ -40,38 +35,39 @@ class EditTournamentPage extends React.Component {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
requestTournament(this.props.query.code, () => {
|
requestTournament(this.props.query.code, () => {
|
||||||
this.setState({ validCode: true });
|
this.setState({validCode: true});
|
||||||
|
|
||||||
if(this._edittournamentcontent != null) {
|
if (this._edittournamentcontent != null) {
|
||||||
this._edittournamentcontent.notifyOfContentUpdate();
|
this._edittournamentcontent.notifyOfContentUpdate();
|
||||||
}
|
}
|
||||||
}, () => {
|
}, () => {
|
||||||
this.setState({ validCode: false });
|
this.setState({validCode: false});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { validCode } = this.state;
|
const {validCode} = this.state;
|
||||||
const { tournamentname, ownerUsername, isSignedIn, username } = this.props;
|
const {tournamentname, ownerUsername, isSignedIn, username} = this.props;
|
||||||
|
|
||||||
return (
|
return (<UserRestrictor>
|
||||||
<UserRestrictor>
|
<Option condition={validCode && isSignedIn && ownerUsername === username}>
|
||||||
<Option condition={ validCode && isSignedIn && ownerUsername === username }>
|
|
||||||
<div className='pb-5'>
|
<div className='pb-5'>
|
||||||
<Head>
|
<Head>
|
||||||
<title>Turnie.re - Turnier bearbeiten</title>
|
<title>Turnie.re - Turnier bearbeiten</title>
|
||||||
</Head>
|
</Head>
|
||||||
<TurniereNavigation/>
|
<TurniereNavigation/>
|
||||||
|
|
||||||
<BigImage text={ tournamentname }/>
|
<BigImage text={tournamentname}/>
|
||||||
<EditTournamentContent ref={(edittournamentcontent) => { this._edittournamentcontent = edittournamentcontent; }}/>
|
<EditTournamentContent ref={edittournamentcontent => {
|
||||||
|
this._edittournamentcontent = edittournamentcontent;
|
||||||
|
}}/>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>
|
||||||
</Option>
|
</Option>
|
||||||
<Option condition={ validCode && isSignedIn }>
|
<Option condition={validCode && isSignedIn}>
|
||||||
<ErrorPageComponent statusCode={ 403 }/>
|
<ErrorPageComponent statusCode={403}/>
|
||||||
</Option>
|
</Option>
|
||||||
<Option condition={ !isSignedIn }>
|
<Option condition={!isSignedIn}>
|
||||||
<div className="main generic-fullpage-bg">
|
<div className="main generic-fullpage-bg">
|
||||||
<Head>
|
<Head>
|
||||||
<title>Turnie.re - Turnier bearbeiten</title>
|
<title>Turnie.re - Turnier bearbeiten</title>
|
||||||
|
|
@ -85,33 +81,31 @@ class EditTournamentPage extends React.Component {
|
||||||
</div>
|
</div>
|
||||||
</Option>
|
</Option>
|
||||||
<Option condition={true}>
|
<Option condition={true}>
|
||||||
<ErrorPageComponent statusCode={ 404 }/>
|
<ErrorPageComponent statusCode={404}/>
|
||||||
</Option>
|
</Option>
|
||||||
</UserRestrictor>
|
</UserRestrictor>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToTournamentInfo(state) {
|
function mapStateToTournamentInfo(state) {
|
||||||
const { tournamentname, ownerUsername } = state.tournamentinfo;
|
const {tournamentname, ownerUsername} = state.tournamentinfo;
|
||||||
const { isSignedIn, username } = state.userinfo;
|
const {isSignedIn, username} = state.userinfo;
|
||||||
return { tournamentname, ownerUsername, isSignedIn, username };
|
return {tournamentname, ownerUsername, isSignedIn, username};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default connect(
|
export default connect(mapStateToTournamentInfo)(EditTournamentPage);
|
||||||
mapStateToTournamentInfo
|
|
||||||
)(EditTournamentPage);
|
|
||||||
|
|
||||||
class EditTournamentContent extends React.Component {
|
class EditTournamentContent extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<div className='mb-5'>
|
||||||
<div className='mb-5'>
|
|
||||||
<ReturnToTournamentButton/>
|
<ReturnToTournamentButton/>
|
||||||
<EditTournamentPropertiesField ref={(field) => { this._edittournamentpropertiesfield = field; }}/>
|
<EditTournamentPropertiesField ref={field => {
|
||||||
<EditTeamField ref={(field) => { this._editteamfield = field; }}/>
|
this._edittournamentpropertiesfield = field;
|
||||||
</div>
|
}}/>
|
||||||
);
|
<EditTeamField ref={field => {
|
||||||
|
this._editteamfield = field;
|
||||||
|
}}/>
|
||||||
|
</div>);
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyOfContentUpdate() {
|
notifyOfContentUpdate() {
|
||||||
|
|
@ -121,24 +115,21 @@ class EditTournamentContent extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
function ReturnToTournamentButton() {
|
function ReturnToTournamentButton() {
|
||||||
return (
|
return (<Container className="px-0">
|
||||||
<Container className="px-0">
|
|
||||||
<Button color="secondary" className="mb-5 w-100" href="./">Zurück zum Turnier</Button>
|
<Button color="secondary" className="mb-5 w-100" href="./">Zurück zum Turnier</Button>
|
||||||
</Container>
|
</Container>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class EditTournamentPropertiesField extends React.Component {
|
class EditTournamentPropertiesField extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<Card className="container">
|
||||||
<Card className="container">
|
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<h2>Turnier-Eigenschaften ändern</h2>
|
<h2>Turnier-Eigenschaften ändern</h2>
|
||||||
<VisibleEditTournamentForm ref={(form) => { this._visibleedittournamentform = form; }}/>
|
<VisibleEditTournamentForm ref={form => {
|
||||||
|
this._visibleedittournamentform = form;
|
||||||
|
}}/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyOfContentUpdate() {
|
notifyOfContentUpdate() {
|
||||||
|
|
@ -147,50 +138,49 @@ class EditTournamentPropertiesField extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
class EditTournamentForm extends React.Component {
|
class EditTournamentForm extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
name : '',
|
name: '', description: '', isPublic: false
|
||||||
description : '',
|
|
||||||
isPublic : false
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { name, description, isPublic } = this.state;
|
const {name, description, isPublic} = this.state;
|
||||||
|
|
||||||
return (
|
return (<div>
|
||||||
<div>
|
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="name">Turnier-Name</label>
|
<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) } />
|
<input className="form-control" type="text" name="name" id="edittournament-textfield-name"
|
||||||
|
value={name} placeholder={name} onChange={this.handleNameInput.bind(this)}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label htmlFor="name">Turnier-Beschreibung</label>
|
<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) } />
|
<input className="form-control" type="text" name="name" id="edittournament-textfield-description"
|
||||||
|
value={description} placeholder={description}
|
||||||
|
onChange={this.handleDescriptionInput.bind(this)}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group custom-control custom-checkbox">
|
<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) } />
|
<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>
|
<label htmlFor="isPublic" className="custom-control-label">Das Turnier öffentlich anzeigen</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<div className="input-group">
|
<div className="input-group">
|
||||||
<Button color="success" className="px-5" id="edittournament-button" onClick={ this.handleClick.bind(this) }>Ändern</Button>
|
<Button color="success" className="px-5" id="edittournament-button"
|
||||||
|
onClick={this.handleClick.bind(this)}>Ändern</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyOfContentUpdate() {
|
notifyOfContentUpdate() {
|
||||||
const { name, description, isPublic } = this.props;
|
const {name, description, isPublic} = this.props;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
name : name? name : '',
|
name: name ? name : '', description: description ? description : '', isPublic: isPublic
|
||||||
description : description? description : '',
|
|
||||||
isPublic : isPublic
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,39 +189,36 @@ class EditTournamentForm extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
handleNameInput(input) {
|
handleNameInput(input) {
|
||||||
this.setState({ name : input.target.value });
|
this.setState({name: input.target.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleDescriptionInput(input) {
|
handleDescriptionInput(input) {
|
||||||
this.setState({ description : input.target.value });
|
this.setState({description: input.target.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
handlePublicInput(input) {
|
handlePublicInput(input) {
|
||||||
this.setState({ public : input.target.value });
|
this.setState({public: input.target.value});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToTournamentFormProps(state) {
|
function mapStateToTournamentFormProps(state) {
|
||||||
const { name, description, isPublic } = state.tournamentinfo;
|
const {name, description, isPublic} = state.tournamentinfo;
|
||||||
return { name, description, isPublic };
|
return {name, description, isPublic};
|
||||||
}
|
}
|
||||||
|
|
||||||
const VisibleEditTournamentForm = connect(
|
const VisibleEditTournamentForm = connect(mapStateToTournamentFormProps, null, null,
|
||||||
mapStateToTournamentFormProps,
|
{withRef: true})(EditTournamentForm);
|
||||||
null, null, { withRef : true}
|
|
||||||
)(EditTournamentForm);
|
|
||||||
|
|
||||||
class EditTeamField extends React.Component {
|
class EditTeamField extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<Card className="container my-4">
|
||||||
<Card className="container my-4">
|
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<h2>Team-Namen ändern</h2>
|
<h2>Team-Namen ändern</h2>
|
||||||
<VisibleEditTeamNamesForm ref={(form) => { this._visibleeditteamnamesform = form; }}/>
|
<VisibleEditTeamNamesForm ref={form => {
|
||||||
|
this._visibleeditteamnamesform = form;
|
||||||
|
}}/>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyOfContentUpdate() {
|
notifyOfContentUpdate() {
|
||||||
|
|
@ -240,51 +227,49 @@ class EditTeamField extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
class EditTeamNamesForm extends React.Component {
|
class EditTeamNamesForm extends React.Component {
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
teams : []
|
teams: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { teams } = this.state;
|
const {teams} = this.state;
|
||||||
|
|
||||||
return (
|
return (<div>
|
||||||
<div>
|
|
||||||
<Table className="table-striped mt-3">
|
<Table className="table-striped mt-3">
|
||||||
<tbody>
|
<tbody>
|
||||||
{
|
{teams.map((team, index) => <tr key={index}>
|
||||||
teams.map((team, index) =>
|
<td><Button outline size="sm" className="changeTeamnameButton"
|
||||||
<tr key={index}>
|
id={'editteam-button-team_' + team.id}
|
||||||
<td><Button outline size="sm" className="changeTeamnameButton" id={ 'editteam-button-team_' + team.id } onClick={ this.handleClick.bind(this, index) }>Ändern</Button></td>
|
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>
|
<td className="w-100"><input className="form-control" type="text"
|
||||||
</tr>
|
id={'editteam-textfield-team_' + team.id} value={team.name}
|
||||||
)
|
placeholder={team.name}
|
||||||
}
|
onChange={this.handleNameInput.bind(this, index)}/></td>
|
||||||
|
</tr>)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
notifyOfContentUpdate() {
|
notifyOfContentUpdate() {
|
||||||
const { teams } = this.props;
|
const {teams} = this.props;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
teams : teams
|
teams: teams
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleNameInput(index, input) {
|
handleNameInput(index, input) {
|
||||||
let team = this.state.teams.slice();
|
const team = this.state.teams.slice();
|
||||||
|
|
||||||
team[index].name = input.target.value;
|
team[index].name = input.target.value;
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
teams : team
|
teams: team
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -298,12 +283,9 @@ class EditTeamNamesForm extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToTeamFormProps(state) {
|
function mapStateToTeamFormProps(state) {
|
||||||
const { teams } = state.tournamentinfo;
|
const {teams} = state.tournamentinfo;
|
||||||
return { teams };
|
return {teams};
|
||||||
}
|
}
|
||||||
|
|
||||||
const VisibleEditTeamNamesForm = connect(
|
const VisibleEditTeamNamesForm = connect(mapStateToTeamFormProps, null, null, {withRef: true})(EditTeamNamesForm);
|
||||||
mapStateToTeamFormProps,
|
|
||||||
null, null, { withRef : true }
|
|
||||||
)(EditTeamNamesForm);
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,18 @@ import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
class FullscreenTournamentPage extends React.Component {
|
class FullscreenTournamentPage extends React.Component {
|
||||||
|
|
||||||
static async getInitialProps({query}) {
|
static async getInitialProps({query}) {
|
||||||
return {query};
|
return {query};
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (<div>
|
||||||
<div>
|
|
||||||
<Head>
|
<Head>
|
||||||
<title>Turnie.re - Turnieranzeige (Vollbild)</title>
|
<title>Turnie.re - Turnieranzeige (Vollbild)</title>
|
||||||
</Head>
|
</Head>
|
||||||
<p>Turnieranzeige (Vollbild)</p>
|
<p>Turnieranzeige (Vollbild)</p>
|
||||||
<p>Code: {this.props.query.code}</p>
|
<p>Code: {this.props.query.code}</p>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import Head from 'next/head';
|
import Head from 'next/head';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { connect } from 'react-redux';
|
import {connect} from 'react-redux';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
Card,
|
Card,
|
||||||
|
|
@ -20,13 +20,12 @@ import {
|
||||||
Table
|
Table
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
|
|
||||||
import { ErrorPageComponent } from '../js/components/ErrorComponents';
|
import {ErrorPageComponent} from '../js/components/ErrorComponents';
|
||||||
import { Footer } from '../js/components/Footer';
|
import {Footer} from '../js/components/Footer';
|
||||||
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 {
|
import {
|
||||||
getRequest,
|
getRequest, getState
|
||||||
getState
|
|
||||||
} from '../js/api';
|
} from '../js/api';
|
||||||
|
|
||||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
|
@ -35,14 +34,12 @@ import '../static/everypage.css';
|
||||||
import '../static/css/tournament.css';
|
import '../static/css/tournament.css';
|
||||||
|
|
||||||
class PrivateTournamentPage extends React.Component {
|
class PrivateTournamentPage extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { id, description, isPublic, code, ownerUsername, playoffStages } = this.props.tournament;
|
const {id, description, isPublic, code, ownerUsername, playoffStages} = this.props.tournament;
|
||||||
const { isSignedIn, username } = this.props;
|
const {isSignedIn, username} = this.props;
|
||||||
|
|
||||||
// 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>
|
||||||
<EditButton id={id} ownerName={ownerUsername} isSignedIn={isSignedIn} username={username}/>
|
<EditButton id={id} ownerName={ownerUsername} isSignedIn={isSignedIn} username={username}/>
|
||||||
<p>{description}</p>
|
<p>{description}</p>
|
||||||
|
|
@ -55,30 +52,26 @@ class PrivateTournamentPage extends React.Component {
|
||||||
</ListGroup>
|
</ListGroup>
|
||||||
</Container>
|
</Container>
|
||||||
<div className='stages pt-5'>
|
<div className='stages pt-5'>
|
||||||
{playoffStages.map(stage =>
|
{playoffStages.map(stage => <Stage isSignedIn={isSignedIn} isOwner={username === ownerUsername}
|
||||||
<Stage isSignedIn={isSignedIn} isOwner={username === ownerUsername} level={getLevelName(stage.level)} matches={stage.matches} key={stage.level}/>)}
|
level={getLevelName(stage.level)} matches={stage.matches}
|
||||||
|
key={stage.level}/>)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapStateToTournamentPageProperties(state) {
|
function mapStateToTournamentPageProperties(state) {
|
||||||
const { isSignedIn, username } = state.userinfo;
|
const {isSignedIn, username} = state.userinfo;
|
||||||
return { isSignedIn, username };
|
return {isSignedIn, username};
|
||||||
}
|
}
|
||||||
|
|
||||||
const TournamentPage = connect(
|
const TournamentPage = connect(mapStateToTournamentPageProperties)(PrivateTournamentPage);
|
||||||
mapStateToTournamentPageProperties
|
|
||||||
)(PrivateTournamentPage);
|
|
||||||
|
|
||||||
function EditButton(props) {
|
function EditButton(props) {
|
||||||
const { id, ownerName, isSignedIn, username } = props;
|
const {id, ownerName, isSignedIn, username} = props;
|
||||||
|
|
||||||
if(isSignedIn && ownerName === username) {
|
if (isSignedIn && ownerName === username) {
|
||||||
return (
|
return (<a href={'/t/' + id + '/edit'} className='btn btn-outline-secondary'>Turnier bearbeiten</a>);
|
||||||
<a href={'/t/' + id + '/edit'} className='btn btn-outline-secondary'>Turnier bearbeiten</a>
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
@ -86,23 +79,23 @@ function EditButton(props) {
|
||||||
|
|
||||||
function getLevelName(levelNumber) {
|
function getLevelName(levelNumber) {
|
||||||
const names = ['Finale', 'Halbfinale', 'Viertelfinale', 'Achtelfinale'];
|
const names = ['Finale', 'Halbfinale', 'Viertelfinale', 'Achtelfinale'];
|
||||||
if(levelNumber < names.length){
|
if (levelNumber < names.length) {
|
||||||
return names[levelNumber];
|
return names[levelNumber];
|
||||||
}else {
|
} else {
|
||||||
return Math.pow(2, levelNumber) + 'tel-Finale';
|
return Math.pow(2, levelNumber) + 'tel-Finale';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Stage(props) {
|
function Stage(props) {
|
||||||
const { isSignedIn, isOwner } = 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} isSignedIn={isSignedIn} isOwner={isOwner}/></Col>
|
<Col className='minw-25' key={match.id}><Match match={match} isSignedIn={isSignedIn}
|
||||||
)))}
|
isOwner={isOwner}/></Col>)))}
|
||||||
</Row>
|
</Row>
|
||||||
</Container>
|
</Container>
|
||||||
</div>);
|
</div>);
|
||||||
|
|
@ -118,16 +111,18 @@ class Match extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleModal() {
|
toggleModal() {
|
||||||
const { isSignedIn, isOwner } = this.props;
|
const {isSignedIn, isOwner} = this.props;
|
||||||
|
|
||||||
if(isSignedIn && isOwner) {
|
if (isSignedIn && isOwner) {
|
||||||
this.setState({modal: !this.state.modal});
|
this.setState({modal: !this.state.modal});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let cardClass, smallMessage, borderClass;
|
let cardClass;
|
||||||
//possible states: single_team not_ready not_started in_progress team1_won team2_won undecided
|
let smallMessage;
|
||||||
|
let borderClass;
|
||||||
|
// possible states: single_team not_ready not_started in_progress team1_won team2_won undecided
|
||||||
switch (this.props.match.state) {
|
switch (this.props.match.state) {
|
||||||
case 'in_progress':
|
case 'in_progress':
|
||||||
cardClass = 'table-warning';
|
cardClass = 'table-warning';
|
||||||
|
|
@ -161,8 +156,7 @@ class Match extends React.Component {
|
||||||
smallMessage = 'Spiel beendet, unentschieden';
|
smallMessage = 'Spiel beendet, unentschieden';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (
|
return (<div className='mb-3'>
|
||||||
<div className='mb-3'>
|
|
||||||
<Card className='shadow-sm match' onClick={this.toggleModal}>
|
<Card className='shadow-sm match' onClick={this.toggleModal}>
|
||||||
<CardBody className={borderClass + ' border py-2 ' + cardClass}>
|
<CardBody className={borderClass + ' border py-2 ' + cardClass}>
|
||||||
<MatchTable match={this.props.match} borderColor={borderClass}/>
|
<MatchTable match={this.props.match} borderColor={borderClass}/>
|
||||||
|
|
@ -170,15 +164,14 @@ class Match extends React.Component {
|
||||||
</Card>
|
</Card>
|
||||||
<small className='text-muted'>{smallMessage}</small>
|
<small className='text-muted'>{smallMessage}</small>
|
||||||
<MatchModal title='Match' isOpen={this.state.modal} toggle={this.toggleModal} match={this.props.match}/>
|
<MatchModal title='Match' isOpen={this.state.modal} toggle={this.toggleModal} match={this.props.match}/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function MatchModal(props) {
|
function MatchModal(props) {
|
||||||
let title;
|
let title;
|
||||||
let actionButton = '';
|
let actionButton = '';
|
||||||
//possible states: single_team not_ready not_started in_progress team1_won team2_won undecided
|
// possible states: single_team not_ready not_started in_progress team1_won team2_won undecided
|
||||||
switch (props.match.state) {
|
switch (props.match.state) {
|
||||||
case 'in_progress':
|
case 'in_progress':
|
||||||
title = 'Spiel läuft';
|
title = 'Spiel läuft';
|
||||||
|
|
@ -204,8 +197,7 @@ function MatchModal(props) {
|
||||||
title = 'Spiel beendet';
|
title = 'Spiel beendet';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return (
|
return (<Modal isOpen={props.isOpen} toggle={props.toggle}>
|
||||||
<Modal isOpen={props.isOpen} toggle={props.toggle}>
|
|
||||||
<ModalHeader toggle={props.toggle}>{title}</ModalHeader>
|
<ModalHeader toggle={props.toggle}>{title}</ModalHeader>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
{props.match.state === 'in_progress' ? <EditableMatchTable match={props.match}/> :
|
{props.match.state === 'in_progress' ? <EditableMatchTable match={props.match}/> :
|
||||||
|
|
@ -215,13 +207,13 @@ function MatchModal(props) {
|
||||||
{actionButton}
|
{actionButton}
|
||||||
<Button color='secondary' onClick={props.toggle}>Abbrechen</Button>
|
<Button color='secondary' onClick={props.toggle}>Abbrechen</Button>
|
||||||
</ModalFooter>
|
</ModalFooter>
|
||||||
</Modal>
|
</Modal>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function MatchTable(props) {
|
function MatchTable(props) {
|
||||||
let team1Class, team2Class;
|
let team1Class;
|
||||||
//possible states: single_team not_ready not_started in_progress team1_won team2_won undecided
|
let team2Class;
|
||||||
|
// possible states: single_team not_ready not_started in_progress team1_won team2_won undecided
|
||||||
switch (props.match.state) {
|
switch (props.match.state) {
|
||||||
case 'in_progress':
|
case 'in_progress':
|
||||||
break;
|
break;
|
||||||
|
|
@ -243,9 +235,8 @@ function MatchTable(props) {
|
||||||
case 'undecided':
|
case 'undecided':
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(props.match.state === 'single_team'){
|
if (props.match.state === 'single_team') {
|
||||||
return (
|
return (<Table className='mb-0'>
|
||||||
<Table className='mb-0'>
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td className={'border-top-0 ' + team1Class}>{props.match.team1}</td>
|
<td className={'border-top-0 ' + team1Class}>{props.match.team1}</td>
|
||||||
|
|
@ -254,11 +245,9 @@ function MatchTable(props) {
|
||||||
<td className={props.borderColor + ' ' + team2Class}>kein Gegner</td>
|
<td className={props.borderColor + ' ' + team2Class}>kein Gegner</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>);
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (<Table className='mb-0'>
|
||||||
<Table className='mb-0'>
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<th className='stage border-top-0'>{props.match.scoreTeam1}</th>
|
<th className='stage border-top-0'>{props.match.scoreTeam1}</th>
|
||||||
|
|
@ -269,14 +258,12 @@ function MatchTable(props) {
|
||||||
<td className={props.borderColor + ' ' + team2Class}>{props.match.team2}</td>
|
<td className={props.borderColor + ' ' + team2Class}>{props.match.team2}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function EditableMatchTable(props) {
|
function EditableMatchTable(props) {
|
||||||
return (
|
return (<Table className='mb-0'>
|
||||||
<Table className='mb-0'>
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td className='scoreInput border-top-0'>
|
<td className='scoreInput border-top-0'>
|
||||||
|
|
@ -291,8 +278,7 @@ function EditableMatchTable(props) {
|
||||||
<td className='align-middle'>{props.match.team2}</td>
|
<td className='align-middle'>{props.match.team2}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</Table>
|
</Table>);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ScoreInput extends React.Component {
|
class ScoreInput extends React.Component {
|
||||||
|
|
@ -304,40 +290,41 @@ class ScoreInput extends React.Component {
|
||||||
this.decreaseScore = this.decreaseScore.bind(this);
|
this.decreaseScore = this.decreaseScore.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateScore(event){
|
updateScore(event) {
|
||||||
this.setState({score: event.target.value});
|
this.setState({score: event.target.value});
|
||||||
}
|
}
|
||||||
|
|
||||||
increaseScore(){
|
increaseScore() {
|
||||||
this.setState({score: Number(this.state.score) + 1});
|
this.setState({score: Number(this.state.score) + 1});
|
||||||
}
|
}
|
||||||
|
|
||||||
decreaseScore(){
|
decreaseScore() {
|
||||||
this.setState({score: Number(this.state.score) - 1});
|
this.setState({score: Number(this.state.score) - 1});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (<InputGroup>
|
return (<InputGroup>
|
||||||
<InputGroupAddon addonType="prepend"><Button onClick={this.decreaseScore} color='danger' outline={true}>-1</Button></InputGroupAddon>
|
<InputGroupAddon addonType="prepend"><Button onClick={this.decreaseScore} color='danger'
|
||||||
<Input className='font-weight-bold' value={this.state.score} onChange={this.updateScore} type='number' step='1' placeholder='0'/>
|
outline={true}>-1</Button></InputGroupAddon>
|
||||||
<InputGroupAddon addonType="append"><Button onClick={this.increaseScore} color='success'>+1</Button></InputGroupAddon>
|
<Input className='font-weight-bold' value={this.state.score} onChange={this.updateScore} type='number'
|
||||||
|
step='1' placeholder='0'/>
|
||||||
|
<InputGroupAddon addonType="append"><Button onClick={this.increaseScore}
|
||||||
|
color='success'>+1</Button></InputGroupAddon>
|
||||||
</InputGroup>);
|
</InputGroup>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertTournament(apiTournament) {
|
function convertTournament(apiTournament) {
|
||||||
let groupStage = null;
|
let groupStage = null;
|
||||||
let playoffStages = [];
|
const playoffStages = [];
|
||||||
for (let stage of apiTournament.stages) {
|
for (const stage of apiTournament.stages) {
|
||||||
if(stage.groups.length > 0){
|
if (stage.groups.length > 0) {
|
||||||
//group stage
|
// group stage
|
||||||
groupStage = {groups: stage.groups.map(group => convertGroup(group))};
|
groupStage = {groups: stage.groups.map(group => convertGroup(group))};
|
||||||
}else{
|
} else {
|
||||||
//playoff stage
|
// playoff stage
|
||||||
playoffStages.push({
|
playoffStages.push({
|
||||||
id: stage.id,
|
id: stage.id, level: stage.level, matches: stage.matches.map(match => convertMatch(match))
|
||||||
level: stage.level,
|
|
||||||
matches: stage.matches.map(match => convertMatch(match))
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -363,17 +350,16 @@ function convertGroup(apiGroup) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertMatch(apiMatch) {
|
function convertMatch(apiMatch) {
|
||||||
let result = {
|
const result = {
|
||||||
id: apiMatch.id,
|
id: apiMatch.id, state: apiMatch.state
|
||||||
state: apiMatch.state
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if(apiMatch.match_scores.length === 2) {
|
if (apiMatch.match_scores.length === 2) {
|
||||||
result.team1 = apiMatch.match_scores[0].team.name;
|
result.team1 = apiMatch.match_scores[0].team.name;
|
||||||
result.scoreTeam1 = apiMatch.match_scores[0].points;
|
result.scoreTeam1 = apiMatch.match_scores[0].points;
|
||||||
result.team2 = apiMatch.match_scores[1].team.name;
|
result.team2 = apiMatch.match_scores[1].team.name;
|
||||||
result.scoreTeam2 = apiMatch.match_scores[1].points;
|
result.scoreTeam2 = apiMatch.match_scores[1].points;
|
||||||
} else if(apiMatch.match_scores.length === 1) {
|
} else if (apiMatch.match_scores.length === 1) {
|
||||||
result.team1 = apiMatch.match_scores[0].team.name;
|
result.team1 = apiMatch.match_scores[0].team.name;
|
||||||
result.scoreTeam1 = apiMatch.match_scores[0].points;
|
result.scoreTeam1 = apiMatch.match_scores[0].points;
|
||||||
result.team2 = 'TBD';
|
result.team2 = 'TBD';
|
||||||
|
|
@ -389,7 +375,6 @@ function convertMatch(apiMatch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
class Main extends React.Component {
|
class Main extends React.Component {
|
||||||
|
|
||||||
static async getInitialProps({query}) {
|
static async getInitialProps({query}) {
|
||||||
return {query};
|
return {query};
|
||||||
}
|
}
|
||||||
|
|
@ -398,7 +383,7 @@ class Main extends React.Component {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
tournament : null
|
tournament: null
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -407,13 +392,13 @@ class Main extends React.Component {
|
||||||
|
|
||||||
getRequest(getState(), '/tournaments/' + code)
|
getRequest(getState(), '/tournaments/' + code)
|
||||||
.then(response => {
|
.then(response => {
|
||||||
this.setState({ status : response.status, tournament : convertTournament(response.data)});
|
this.setState({status: response.status, tournament: convertTournament(response.data)});
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch(err => {
|
||||||
if(err.response) {
|
if (err.response) {
|
||||||
this.setState({ status : err.response.status });
|
this.setState({status: err.response.status});
|
||||||
} else {
|
} else {
|
||||||
this.setState({ status : -1 });
|
this.setState({status: -1});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -422,11 +407,10 @@ class Main extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const tournamentName = this.state.tournament === null ? 'Turnier' : this.state.tournament.name;
|
const tournamentName = this.state.tournament === null ? 'Turnier' : this.state.tournament.name;
|
||||||
|
|
||||||
const { status, tournament } = this.state;
|
const {status, tournament} = this.state;
|
||||||
|
|
||||||
if (status === 200) {
|
if (status === 200) {
|
||||||
return (
|
return (<div>
|
||||||
<div>
|
|
||||||
<Head>
|
<Head>
|
||||||
<title>{tournamentName}: turnie.re</title>
|
<title>{tournamentName}: turnie.re</title>
|
||||||
</Head>
|
</Head>
|
||||||
|
|
@ -434,8 +418,7 @@ class Main extends React.Component {
|
||||||
<BigImage text={tournamentName}/>
|
<BigImage text={tournamentName}/>
|
||||||
<TournamentPage tournament={tournament}/>
|
<TournamentPage tournament={tournament}/>
|
||||||
<Footer/>
|
<Footer/>
|
||||||
</div>
|
</div>);
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return <ErrorPageComponent code={status}/>;
|
return <ErrorPageComponent code={status}/>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
10
server.js
10
server.js
|
|
@ -2,7 +2,7 @@ const express = require('express');
|
||||||
const next = require('next');
|
const next = require('next');
|
||||||
|
|
||||||
const dev = process.env.NODE_ENV !== 'production';
|
const dev = process.env.NODE_ENV !== 'production';
|
||||||
const app = next({ dev });
|
const app = next({dev});
|
||||||
const handle = app.getRequestHandler();
|
const handle = app.getRequestHandler();
|
||||||
|
|
||||||
app.prepare()
|
app.prepare()
|
||||||
|
|
@ -11,19 +11,19 @@ app.prepare()
|
||||||
|
|
||||||
server.get('/t/:code', (req, res) => {
|
server.get('/t/:code', (req, res) => {
|
||||||
const actualPage = '/tournament';
|
const actualPage = '/tournament';
|
||||||
const queryParam = { code: req.params.code };
|
const queryParam = {code: req.params.code};
|
||||||
app.render(req, res, actualPage, queryParam);
|
app.render(req, res, actualPage, queryParam);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.get('/t/:code/fullscreen', (req, res) => {
|
server.get('/t/:code/fullscreen', (req, res) => {
|
||||||
const actualPage = '/tournament-fullscreen';
|
const actualPage = '/tournament-fullscreen';
|
||||||
const queryParam = { code: req.params.code };
|
const queryParam = {code: req.params.code};
|
||||||
app.render(req, res, actualPage, queryParam);
|
app.render(req, res, actualPage, queryParam);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.get('/t/:code/edit', (req, res) => {
|
server.get('/t/:code/edit', (req, res) => {
|
||||||
const actualPage = '/tournament-edit';
|
const actualPage = '/tournament-edit';
|
||||||
const queryParam = { code: req.params.code };
|
const queryParam = {code: req.params.code};
|
||||||
app.render(req, res, actualPage, queryParam);
|
app.render(req, res, actualPage, queryParam);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -31,7 +31,7 @@ app.prepare()
|
||||||
return handle(req, res);
|
return handle(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.listen(dev ? 3000 : 80, (err) => {
|
server.listen(dev ? 3000 : 80, err => {
|
||||||
if (err) throw err;
|
if (err) throw err;
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -3255,6 +3255,11 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||||
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||||
|
|
||||||
|
eslint-config-google@^0.12.0:
|
||||||
|
version "0.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/eslint-config-google/-/eslint-config-google-0.12.0.tgz#b9bcc52d0f24cf946e862fe8b09c773ad21e511b"
|
||||||
|
integrity sha512-SHDM3nIRCJBACjf8c/H6FvCwRmKbphESNl3gJFBNbw4KYDLCONB3ABYLXDGF+iaVP9XSTND/Q5/PuGoFkp4xbg==
|
||||||
|
|
||||||
eslint-plugin-react@^7.11.1:
|
eslint-plugin-react@^7.11.1:
|
||||||
version "7.12.4"
|
version "7.12.4"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c"
|
resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue