From 2e9d6353c42dee5090e9b79d5ab3f71ed7a38976 Mon Sep 17 00:00:00 2001 From: Felix Hamme Date: Mon, 3 Dec 2018 13:41:28 +0100 Subject: [PATCH 01/15] Design public tournament list --- pages/list.js | 69 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/pages/list.js b/pages/list.js index 0425ab5..6e9574a 100644 --- a/pages/list.js +++ b/pages/list.js @@ -1,10 +1,73 @@ import Head from 'next/head' +import '../static/everypage.css' +import {Footer, TurniereNavigation} from "../js/CommonComponents"; +import React from "react"; +import {Card, CardBody, Container} from "reactstrap"; +import {getRequest} from "../js/api"; export default () => ( -
+
- Turnie.re - Turnierliste + Öffentliche Turniere: turnie.re -

Turnierliste

+ +
+ +
+
) + +class TournamentList extends React.Component { + constructor(props) { + super(props); + this.state = { + error: null, + isLoaded: false, + items: [] + }; + } + + componentDidMount() { + getRequest('/tournaments?type=public',{}) + .then( + response => { + console.log('response:'); + console.log(response); + this.setState({ + isLoaded: true, + items: response.data.data + }); + }, + error => { + this.setState({ + isLoaded: true, + error + }); + } + ) + } + + render() { + return ( + + + +

Öffentliche Turniere

+ {this.state.items.map(item => ( + + ))} +
+
+
+ ); + } +} + +function TournamentListEntry(props) { + return ( + + {props.name} + + ); +} \ No newline at end of file From d0337fb6409a78acea2ad4d56e15fdce290f6c8d Mon Sep 17 00:00:00 2001 From: JP1998 Date: Mon, 3 Dec 2018 14:30:48 +0100 Subject: [PATCH 02/15] Add actually working login and logout --- js/CommonComponents.js | 15 ++------ js/api.js | 49 +++++++++++++++++------- pages/login.js | 87 +++++++++++++++++++++++++++++++++++------- pages/register.js | 84 ++++++++++++++++++++++++++++------------ 4 files changed, 172 insertions(+), 63 deletions(-) diff --git a/js/CommonComponents.js b/js/CommonComponents.js index b8407ae..1ed65ed 100644 --- a/js/CommonComponents.js +++ b/js/CommonComponents.js @@ -15,6 +15,8 @@ import { connect } from 'react-redux' import React from "react"; +import { logout } from './api' + export function BigImage(props) { return (
@@ -74,23 +76,14 @@ function Betabadge() { class InvisibleLoginLogoutButtons extends React.Component { - logoutClick() { - console.log("Logged out."); - - /* - /users/sign_out <- DELETE Token invalidieren - /users/validate_token <- GET Token valide? - */ - } - render() { - const { isSignedIn, username, logout } = this.props + const { isSignedIn, username } = this.props if(isSignedIn) { return ( - + ); } else { diff --git a/js/api.js b/js/api.js index 9f45781..79a686c 100644 --- a/js/api.js +++ b/js/api.js @@ -17,6 +17,8 @@ const actiontypes_userinfo = { 'LOGIN_RESULT_SUCCESS' : 'LOGIN_RESULT_SUCCESS', 'LOGIN_RESULT_ERROR' : 'LOGIN_RESULT_ERROR', + 'LOGOUT' : 'LOGOUT', + 'STORE_AUTH_HEADERS' : 'STORE_AUTH_HEADERS', 'REHYDRATE' : 'USERINFO_REHYDRATE', @@ -34,31 +36,30 @@ const defaultstate_userinfo = { uid : null } -export function postRequest(url, data) { +export function postRequest(state, url, data) { return axios.post(api_url + url, data, { - headers : generateHeaders() + headers : generateHeaders(state) }); } -export function getRequest(url, data) { +export function getRequest(state, url, data) { return axios.get(api_url + url, data, { - headers : generateHeaders() + headers : generateHeaders(state) }); } -export function deleteRequest(url, data) { +export function deleteRequest(state, url, data) { return axios.delete(api_url + url, data, { - headers : generateHeaders() + headers : generateHeaders(state) }); } -function generateHeaders() { - var userinfostate = __store.getState().userinfo; - if(userinfostate.isSignedIn) { +function generateHeaders(state) { + if(state.isSignedIn) { return { - 'access-token' : userinfostate.accesstoken, - 'client' : userinfostate.client, - 'uid' : userinfostate.uid + 'access-token' : state.accesstoken, + 'client' : state.client, + 'uid' : state.uid }; } else { return {}; @@ -81,6 +82,9 @@ function storeOptionalToken(response) { function checkForAuthenticationHeaders(response) { if(response.headers) { + + console.log(response); + const requiredHeaders = [ 'access-token', 'client', 'uid', 'expiry', // TODO: Add last header that is required (I don't remember it right now lol) ]; @@ -97,7 +101,7 @@ function checkForAuthenticationHeaders(response) { const reducer_userinfo = (state = defaultstate_userinfo, action) => { switch(action.type) { case actiontypes_userinfo.REGISTER: - postRequest('/users', { + postRequest(state, '/users', { 'username' : action.parameters.username, 'email' : action.parameters.email, 'password' : action.parameters.password @@ -138,7 +142,7 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => { errorMessages : action.parameters.errorMessages }); case actiontypes_userinfo.LOGIN: - postRequest('/users/sign_in', { + postRequest(state, '/users/sign_in', { email : action.parameters.email, password : action.parameters.password }).then((resp) => { @@ -180,7 +184,20 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => { error : true, errorMessages : action.parameters.errorMessages }); + + case actiontypes_userinfo.LOGOUT: + return Object.assign({}, state, { + isSignedIn : false, + username : null, + + accesstoken : null, + client : null, + expiry : null, + uid : null + }); + case actiontypes_userinfo.STORE_AUTH_HEADERS: + console.log("Token has been stored."); return Object.assign({}, state, { accesstoken : action.parameters.accesstoken, client : action.parameters.client, @@ -242,6 +259,10 @@ export function login(email, password) { }) } +export function logout() { + __store.dispatch({ type : actiontypes_userinfo.LOGOUT }); +} + export function getState() { return __store.getState(); } diff --git a/pages/login.js b/pages/login.js index 20fd2cc..2c9ee22 100644 --- a/pages/login.js +++ b/pages/login.js @@ -3,6 +3,8 @@ import '../static/everypage.css' import {Footer, TurniereNavigation} from "../js/CommonComponents"; import React from "react"; import {Button, Card, CardBody, Container, Form, FormGroup, Input, Label} from "reactstrap"; +import { login } from '../js/api' +import { connect } from 'react-redux' export default () => (
@@ -34,18 +36,75 @@ function Login() { ); } -function LoginForm() { - return ( -
- - - - - - - - - -
- ); +class LoginErrorList extends React.Component { + + render() { + const { error, errorMessages } = this.props; + if(error) { + return ( +
    + { errorMessages.map((message, index) => +
  • + + {message} +
  • + + ) } +
+ ); + } else { + return null; + } + } +} + +const mapStateToErrorMessages = (state) => { + const { errorMessages, error } = state.userinfo; + return { errorMessages, error } +}; + +const VisibleLoginErrorList = connect( + mapStateToErrorMessages +)(LoginErrorList); + + +class LoginForm extends React.Component { + + constructor(props) { + super(props); + + this.state = { + email : '', + password : '' + }; + } + + render() { + return ( +
+ + + + + + + + + + + + ); + } + + handlePasswordInput(input) { + this.setState({ password : input.target.value }); + } + + handleEmailInput(input) { + this.setState({ email : input.target.value }); + } } \ No newline at end of file diff --git a/pages/register.js b/pages/register.js index 4a03dd9..e622716 100644 --- a/pages/register.js +++ b/pages/register.js @@ -3,6 +3,7 @@ import '../static/everypage.css' import {Footer, TurniereNavigation} from "../js/CommonComponents"; import React from "react"; import {Button, Card, CardBody, Container, Form, FormGroup, FormText, Input, Label} from "reactstrap"; +import { register } from '../js/api' export default () => (
@@ -34,30 +35,65 @@ function Register() { ); } -function RegisterForm() { - return ( -
- - - - Wenn du anderen dein Turnier zeigst, können sie deinen Benutzernamen sehen. - - - - - Deine E-Mail-Adresse kann nur von dir gesehen werden. - - - - - Dein Passwort muss mindestens 12 Zeichen lang sein. Alle Zeichen sind erlaubt. - - - Du akzeptierst die Datenschutzbestimmungen, wenn du auf Registrieren klickst. - - -
- ); +class RegisterForm extends React.Component { + + constructor(props) { + super(props); + + this.state = { + username : '', + email : '', + password : '' + }; + } + + handleRegisterClick(state) { + const { username, email, password } = state; + + console.log(state); + + console.log(username); + console.log(email); + console.log(password); + } + + render() { + return ( +
+ + + + Wenn du anderen dein Turnier zeigst, können sie deinen Benutzernamen sehen. + + + + + Deine E-Mail-Adresse kann nur von dir gesehen werden. + + + + + Dein Passwort muss mindestens 12 Zeichen lang sein. Alle Zeichen sind erlaubt. + + + Du akzeptierst die Datenschutzbestimmungen, wenn du auf Registrieren klickst. + + +
+ ); + } + + handlePasswordInput(input) { + this.setState({ password : input.target.value }); + } + + handleEmailInput(input) { + this.setState({ email : input.target.value }); + } + + handleUsernameInput(input) { + this.setState({ username : input.target.value }); + } } function AccountRequirementMarketing() { From f85863d9652e18d5352a7d60309fe188605a18fe Mon Sep 17 00:00:00 2001 From: JP1998 Date: Mon, 3 Dec 2018 14:41:59 +0100 Subject: [PATCH 03/15] Remove header, that is no longer being transmitted --- js/api.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/js/api.js b/js/api.js index 79a686c..3852aae 100644 --- a/js/api.js +++ b/js/api.js @@ -82,11 +82,8 @@ function storeOptionalToken(response) { function checkForAuthenticationHeaders(response) { if(response.headers) { - - console.log(response); - const requiredHeaders = [ - 'access-token', 'client', 'uid', 'expiry', // TODO: Add last header that is required (I don't remember it right now lol) + 'access-token', 'client', 'uid', 'expiry' ]; for(var i = 0; i < requiredHeaders.length; i++) { if(!response.headers[requiredHeaders[i]]) { @@ -186,6 +183,12 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => { }); case actiontypes_userinfo.LOGOUT: + deleteRequest(state, '/users/sign_out', {}).then((resp) => { + + }).catch((error) => { + + }); + /* return Object.assign({}, state, { isSignedIn : false, username : null, @@ -195,9 +198,9 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => { expiry : null, uid : null }); + */ case actiontypes_userinfo.STORE_AUTH_HEADERS: - console.log("Token has been stored."); return Object.assign({}, state, { accesstoken : action.parameters.accesstoken, client : action.parameters.client, From df75387164cb7b63c412f9bc910932244006c0d2 Mon Sep 17 00:00:00 2001 From: JP1998 Date: Mon, 3 Dec 2018 15:20:14 +0100 Subject: [PATCH 04/15] Fix login and logout to actually work Because of several issues the auth token has not been stored, which lead to severe errors when trying to log out. This issue has now been solved. --- js/api.js | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/js/api.js b/js/api.js index 3852aae..5eb2b52 100644 --- a/js/api.js +++ b/js/api.js @@ -17,7 +17,8 @@ const actiontypes_userinfo = { 'LOGIN_RESULT_SUCCESS' : 'LOGIN_RESULT_SUCCESS', 'LOGIN_RESULT_ERROR' : 'LOGIN_RESULT_ERROR', - 'LOGOUT' : 'LOGOUT', + 'LOGOUT' : 'LOGOUT', + 'APPLY_SIGN_OUT' : 'APPLY_SIGN_OUT', 'STORE_AUTH_HEADERS' : 'STORE_AUTH_HEADERS', @@ -42,14 +43,14 @@ export function postRequest(state, url, data) { }); } -export function getRequest(state, url, data) { - return axios.get(api_url + url, data, { +export function getRequest(state, url) { + return axios.get(api_url + url, { headers : generateHeaders(state) }); } -export function deleteRequest(state, url, data) { - return axios.delete(api_url + url, data, { +export function deleteRequest(state, url) { + return axios.delete(api_url + url, { headers : generateHeaders(state) }); } @@ -71,10 +72,10 @@ function storeOptionalToken(response) { __store.dispatch({ type : actiontypes_userinfo.STORE_AUTH_HEADERS, parameters : { - accesstoken : resp.headers['access-token'], - client : resp.headers['client'], - expiry : resp.headers['expiry'], - uid : resp.headers['uid'] + accesstoken : response.headers['access-token'], + client : response.headers['client'], + expiry : response.headers['expiry'], + uid : response.headers['uid'] } }) } @@ -90,7 +91,7 @@ function checkForAuthenticationHeaders(response) { return false; } } - return false; + return true; } return false; } @@ -183,23 +184,24 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => { }); case actiontypes_userinfo.LOGOUT: - deleteRequest(state, '/users/sign_out', {}).then((resp) => { - + deleteRequest(state, '/users/sign_out').then((resp) => { + __store.dispatch({ type : actiontypes_userinfo.APPLY_SIGN_OUT }); }).catch((error) => { - + __store.dispatch({ type : actiontypes_userinfo.APPLY_SIGN_OUT }); }); - /* + return Object.assign({}, state, {}); + case actiontypes_userinfo.APPLY_SIGN_OUT: return Object.assign({}, state, { isSignedIn : false, username : null, + error : false, + errorMessages : [], accesstoken : null, client : null, expiry : null, uid : null }); - */ - case actiontypes_userinfo.STORE_AUTH_HEADERS: return Object.assign({}, state, { accesstoken : action.parameters.accesstoken, From 13f7373f6f7018516b28898d0cfaa85dcbfdc750 Mon Sep 17 00:00:00 2001 From: JP1998 Date: Mon, 3 Dec 2018 15:29:26 +0100 Subject: [PATCH 05/15] Add a functioning registration --- pages/register.js | 49 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/pages/register.js b/pages/register.js index e622716..00b3cfa 100644 --- a/pages/register.js +++ b/pages/register.js @@ -4,6 +4,7 @@ import {Footer, TurniereNavigation} from "../js/CommonComponents"; import React from "react"; import {Button, Card, CardBody, Container, Form, FormGroup, FormText, Input, Label} from "reactstrap"; import { register } from '../js/api' +import { connect } from 'react-redux' export default () => (
@@ -35,6 +36,41 @@ function Register() { ); } +class RegisterErrorList extends React.Component { + + render() { + const { error, errorMessages } = this.props; + if(error) { + return ( +
    + { errorMessages.map((message, index) => +
  • + + {message} +
  • + + ) } +
+ ); + } else { + return null; + } + } +} + +const mapStateToErrorMessages = (state) => { + const { errorMessages, error } = state.userinfo; + return { errorMessages, error } +}; + +const VisibleRegisterErrorList = connect( + mapStateToErrorMessages +)(RegisterErrorList); + class RegisterForm extends React.Component { constructor(props) { @@ -47,16 +83,6 @@ class RegisterForm extends React.Component { }; } - handleRegisterClick(state) { - const { username, email, password } = state; - - console.log(state); - - console.log(username); - console.log(email); - console.log(password); - } - render() { return (
@@ -78,7 +104,8 @@ class RegisterForm extends React.Component { Du akzeptierst die Datenschutzbestimmungen, wenn du auf Registrieren klickst. - + + ); } From ba12956abc4709f9710bbccd1cac82c8f4a0e7b9 Mon Sep 17 00:00:00 2001 From: JP1998 Date: Mon, 3 Dec 2018 15:48:05 +0100 Subject: [PATCH 06/15] Add verification of credentials after loading page --- js/api.js | 61 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/js/api.js b/js/api.js index 5eb2b52..a760ada 100644 --- a/js/api.js +++ b/js/api.js @@ -9,20 +9,24 @@ const api_url = 'https://api.turnie.re'; const actiontypes_userinfo = { - 'REGISTER' : 'REGISTER', - 'REGISTER_RESULT_SUCCESS' : 'REGISTER_RESULT_SUCCESS', - 'REGISTER_RESULT_ERROR' : 'REGISTER_RESULT_ERROR', + 'REGISTER' : 'REGISTER', + 'REGISTER_RESULT_SUCCESS' : 'REGISTER_RESULT_SUCCESS', + 'REGISTER_RESULT_ERROR' : 'REGISTER_RESULT_ERROR', - 'LOGIN' : 'LOGIN', - 'LOGIN_RESULT_SUCCESS' : 'LOGIN_RESULT_SUCCESS', - 'LOGIN_RESULT_ERROR' : 'LOGIN_RESULT_ERROR', + 'LOGIN' : 'LOGIN', + 'LOGIN_RESULT_SUCCESS' : 'LOGIN_RESULT_SUCCESS', + 'LOGIN_RESULT_ERROR' : 'LOGIN_RESULT_ERROR', + + 'LOGOUT' : 'LOGOUT', - 'LOGOUT' : 'LOGOUT', - 'APPLY_SIGN_OUT' : 'APPLY_SIGN_OUT', + 'VERIFY_CREDENTIALS' : 'VERIFY_CREDENTIALS', + 'VERIFY_CREDENTIALS_SUCCESS' : 'VERIFY_CREDENTIALS_SUCCESS', + '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', } const defaultstate_userinfo = { @@ -185,12 +189,30 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => { case actiontypes_userinfo.LOGOUT: deleteRequest(state, '/users/sign_out').then((resp) => { - __store.dispatch({ type : actiontypes_userinfo.APPLY_SIGN_OUT }); + __store.dispatch({ type : actiontypes_userinfo.CLEAR }); }).catch((error) => { - __store.dispatch({ type : actiontypes_userinfo.APPLY_SIGN_OUT }); + __store.dispatch({ type : actiontypes_userinfo.CLEAR }); }); return Object.assign({}, state, {}); - case actiontypes_userinfo.APPLY_SIGN_OUT: + case actiontypes_userinfo.STORE_AUTH_HEADERS: + return Object.assign({}, state, { + accesstoken : action.parameters.accesstoken, + client : action.parameters.client, + expiry : action.parameters.expiry, + uid : action.parameters.uid + }); + + case actiontypes_userinfo.VERIFY_CREDENTIALS: + getRequest(state, '/users/validate_token').then((resp) => { + storeOptionalToken(resp); + }).catch((error) => { + __store.dispatch({ type: actiontypes_userinfo.CLEAR }); + }); + return Object.assign({}, state, {}); + + case actiontypes_userinfo.REHYDRATE: + return Object.assign({}, state, action.parameters); + case actiontypes_userinfo.CLEAR: return Object.assign({}, state, { isSignedIn : false, username : null, @@ -202,15 +224,6 @@ const reducer_userinfo = (state = defaultstate_userinfo, action) => { expiry : null, uid : null }); - case actiontypes_userinfo.STORE_AUTH_HEADERS: - return Object.assign({}, state, { - accesstoken : action.parameters.accesstoken, - client : action.parameters.client, - expiry : action.parameters.expiry, - uid : action.parameters.uid - }); - case actiontypes_userinfo.REHYDRATE: - return Object.assign({}, state, action.parameters); default: return state; } } @@ -240,7 +253,9 @@ export function initializeStore(initialState = default_applicationstate) { export function verifyCredentials() { rehydrateApplicationState(); - // TODO: Actually perform a verification of the loaded credentials + if(__store.getState().userinfo.isSignedIn) { + __store.dispatch({ type: actiontypes_userinfo.VERIFY_CREDENTIALS }); + } } export function register(username, email, password) { From 88f14b29e3f062f6f628b497fdd72856c378455a Mon Sep 17 00:00:00 2001 From: JP1998 Date: Mon, 3 Dec 2018 15:59:43 +0100 Subject: [PATCH 07/15] Add config file for hound --- .hound.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .hound.yml diff --git a/.hound.yml b/.hound.yml new file mode 100644 index 0000000..6540cc8 --- /dev/null +++ b/.hound.yml @@ -0,0 +1 @@ +fail_on_violations: true From 1b5bb473c5cc2ef666b72ad5527a8b20f6f2a8cb Mon Sep 17 00:00:00 2001 From: JP1998 Date: Mon, 3 Dec 2018 16:09:52 +0100 Subject: [PATCH 08/15] Add a proper linter for style checks --- .hound.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.hound.yml b/.hound.yml index 6540cc8..618f683 100644 --- a/.hound.yml +++ b/.hound.yml @@ -1 +1,7 @@ fail_on_violations: true + +jshint: + enabled: false + +eslint: + enabled: true From 4b99c4b2dd93fa10acaa717d5f377c16393f0fdc Mon Sep 17 00:00:00 2001 From: JP1998 Date: Thu, 6 Dec 2018 09:11:52 +0100 Subject: [PATCH 09/15] Add proper config for eslint --- .eslintrc.json | 30 +++++ .hound.yml | 1 + package.json | 1 + yarn.lock | 322 +++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 346 insertions(+), 8 deletions(-) create mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..df85702 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "env": { + "browser": true, + "es6": true, + "node": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 2018, + "sourceType": "module" + }, + "rules": { + "indent": [ + "error", + 4 + ], + "linebreak-style": [ + "error", + "windows" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "always" + ] + } +} diff --git a/.hound.yml b/.hound.yml index 618f683..d86b9a7 100644 --- a/.hound.yml +++ b/.hound.yml @@ -5,3 +5,4 @@ jshint: eslint: enabled: true + config_file: .eslintrc diff --git a/package.json b/package.json index cbe7f53..20b6cb6 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "redux-thunk": "^2.3.0" }, "devDependencies": { + "eslint": "^5.9.0", "react-editable-list": "0.0.3" } } diff --git a/yarn.lock b/yarn.lock index a526424..a411c76 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1060,11 +1060,21 @@ acorn-dynamic-import@^3.0.0: dependencies: acorn "^5.0.0" +acorn-jsx@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" + integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== + acorn@^5.0.0, acorn@^5.6.2: version "5.7.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== +acorn@^6.0.2: + version "6.0.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" + integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== + ajv-errors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.0.tgz#ecf021fa108fd17dfb5e6b383f2dd233e31ffc59" @@ -1085,6 +1095,16 @@ ajv@^6.0.1, ajv@^6.1.0: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.5.3, ajv@^6.6.1: + version "6.6.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.6.1.tgz#6360f5ed0d80f232cc2b294c362d5dc2e538dd61" + integrity sha512-ZoJjft5B+EJBjUyu9C9Hc0OZyPZSSlOF+plzouTrg6UlA8f+e/n8NIgBFG/9tppJtpPWfthHakK7juJdNDODww== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ansi-colors@^3.0.0: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.1.tgz#9638047e4213f3428a11944a7d4b31cba0a3ff95" @@ -1110,12 +1130,17 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-regex@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" + integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -1275,6 +1300,11 @@ ast-types@0.11.5: resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.5.tgz#9890825d660c03c28339f315e9fa0a360e31ec28" integrity sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw== +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" @@ -2312,6 +2342,18 @@ call-me-maybe@^1.0.1: resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= + camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" @@ -2411,6 +2453,11 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -2815,6 +2862,13 @@ debug@^3.1.0: dependencies: ms "^2.1.1" +debug@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" + integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== + dependencies: + ms "^2.1.1" + decamelize@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -2837,6 +2891,11 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + define-properties@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -2958,6 +3017,13 @@ dir-glob@^2.0.0: arrify "^1.0.1" path-type "^3.0.0" +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + dom-helpers@^3.3.1: version "3.4.0" resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" @@ -3141,11 +3207,81 @@ eslint-scope@^4.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-utils@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" + integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + +eslint@^5.9.0: + version "5.9.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" + integrity sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.5.3" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^2.1.0" + eslint-scope "^4.0.0" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^4.0.0" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + imurmurhash "^0.1.4" + inquirer "^6.1.0" + is-resolvable "^1.1.0" + js-yaml "^3.12.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.5" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^2.0.1" + require-uncached "^1.0.3" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.0.2" + text-table "^0.2.0" + +espree@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" + integrity sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w== + dependencies: + acorn "^6.0.2" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + esprima@^4.0.0, esprima@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + esrecurse@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" @@ -3153,7 +3289,7 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" -estraverse@^4.1.0, estraverse@^4.1.1: +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= @@ -3350,6 +3486,11 @@ fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + fastparse@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" @@ -3375,6 +3516,14 @@ figures@^2.0.0: dependencies: escape-string-regexp "^1.0.5" +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" @@ -3458,6 +3607,16 @@ first-chunk-stream@^2.0.0: dependencies: readable-stream "^2.0.2" +flat-cache@^1.2.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" + integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== + dependencies: + circular-json "^0.3.1" + graceful-fs "^4.1.2" + rimraf "~2.6.2" + write "^0.2.1" + flow-parser@^0.*: version "0.87.0" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.87.0.tgz#a6d0e0b70f2cebdc15febb4eaf149877edbf145d" @@ -3559,6 +3718,11 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -3688,6 +3852,11 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.8.0.tgz#c1ef45ee9bed6badf0663c5cb90e8d1adec1321d" integrity sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA== +globals@^11.7.0: + version "11.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" + integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== + globals@^9.18.0: version "9.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" @@ -4028,6 +4197,11 @@ ignore@^3.3.5: resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + import-cwd@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" @@ -4126,6 +4300,25 @@ inquirer@^6.0.0: strip-ansi "^4.0.0" through "^2.3.6" +inquirer@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.1.tgz#9943fc4882161bdb0b0c9276769c75b32dbfcd52" + integrity sha512-088kl3DRT2dLU5riVMKKr1DlImd6X7smDhpXUCkJDCKvTEJeRiXh0G132HG9u5a+6Ylw9plFRY7RuTnwohYSpg== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.0" + figures "^2.0.0" + lodash "^4.17.10" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.1.0" + string-width "^2.1.0" + strip-ansi "^5.0.0" + through "^2.3.6" + interpret@^1.0.0, interpret@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" @@ -4406,6 +4599,11 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" +is-resolvable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" @@ -4501,7 +4699,7 @@ js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= -js-yaml@^3.9.0: +js-yaml@^3.12.0, js-yaml@^3.9.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== @@ -4581,6 +4779,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + json5@^0.5.0, json5@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" @@ -4642,6 +4845,14 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + listr-silent-renderer@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" @@ -4761,7 +4972,7 @@ lodash.tonumber@^4.0.3: resolved "https://registry.yarnpkg.com/lodash.tonumber/-/lodash.tonumber-4.0.3.tgz#0b96b31b35672793eb7f5a63ee791f1b9e9025d9" integrity sha1-C5azGzVnJ5Prf1pj7nkfG56QJdk= -lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: +lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== @@ -5176,6 +5387,11 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + needle@^2.2.1: version "2.2.4" resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" @@ -5473,6 +5689,18 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" @@ -5689,7 +5917,7 @@ path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.1: +path-is-inside@^1.0.1, path-is-inside@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= @@ -5775,6 +6003,11 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== + popper.js@^1.14.1: version "1.14.4" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.14.4.tgz#8eec1d8ff02a5a3a152dd43414a15c7b79fd69b6" @@ -5857,6 +6090,11 @@ postcss@^7.0.0: source-map "^0.6.1" supports-color "^5.5.0" +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" @@ -5902,6 +6140,11 @@ process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" @@ -6360,6 +6603,11 @@ regex-not@^1.0.0, regex-not@^1.0.2: extend-shallow "^3.0.2" safe-regex "^1.1.0" +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + regexpu-core@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-1.0.0.tgz#86a763f58ee4d7c2f6b102e4764050de7ed90c6b" @@ -6461,6 +6709,14 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -6476,6 +6732,11 @@ resolve-dir@^1.0.0: expand-tilde "^2.0.0" global-modules "^1.0.0" +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -6520,7 +6781,7 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: +rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== @@ -6628,7 +6889,7 @@ scoped-regex@^1.0.0: resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8" integrity sha1-o0a7Gs1CB65wvXwMfKnlZra63bg= -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== @@ -6787,6 +7048,15 @@ slice-ansi@1.0.0: dependencies: is-fullwidth-code-point "^2.0.0" +slice-ansi@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.0.0.tgz#5373bdb8559b45676e8541c66916cdd6251612e7" + integrity sha512-4j2WTWjp3GsZ+AOagyzVbzp4vWGtZ0hEZ/gDY/uTvm6MTxUfTUIsnMIFb1bn8o0RuXiqUw15H1bue8f22Vw2oQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + slide@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" @@ -7052,6 +7322,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" + integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow== + dependencies: + ansi-regex "^4.0.0" + strip-ansi@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" @@ -7082,7 +7359,7 @@ strip-eof@^1.0.0: resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= -strip-json-comments@~2.0.1: +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= @@ -7145,6 +7422,16 @@ table@^4.0.3: slice-ansi "1.0.0" string-width "^2.1.1" +table@^5.0.2: + version "5.1.1" + resolved "https://registry.yarnpkg.com/table/-/table-5.1.1.tgz#92030192f1b7b51b6eeab23ed416862e47b70837" + integrity sha512-NUjapYb/qd4PeFW03HnAuOJ7OMcBkJlqeClWxeNlQ0lXGSb52oZXGzkO0/I0ARegQ2eUT1g2VDJH0eUxDRcHmw== + dependencies: + ajv "^6.6.1" + lodash "^4.17.11" + slice-ansi "2.0.0" + string-width "^2.1.1" + tapable@^1.0.0, tapable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.0.tgz#0d076a172e3d9ba088fd2272b2668fb8d194b78c" @@ -7305,6 +7592,13 @@ tty-browserify@0.0.0: resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" @@ -7753,6 +8047,11 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + worker-farm@^1.5.2: version "1.6.0" resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" @@ -7802,6 +8101,13 @@ write-file-webpack-plugin@4.3.2: mkdirp "^0.5.1" moment "^2.22.1" +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= + dependencies: + mkdirp "^0.5.1" + xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" From 5aa97e162dba1f86ffeecbdd5c7ebc99b3dd8f6d Mon Sep 17 00:00:00 2001 From: JP1998 Date: Thu, 6 Dec 2018 09:57:51 +0100 Subject: [PATCH 10/15] Add actually functioning style check and fix style in api.js --- .eslintrc.json | 8 +- js/api.js | 256 ++++++++++++++++++++++++------------------------- package.json | 1 + yarn.lock | 28 +++++- 4 files changed, 161 insertions(+), 132 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index df85702..6efdb03 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -4,10 +4,16 @@ "es6": true, "node": true }, + "plugins": [ + "react" + ], "extends": "eslint:recommended", "parserOptions": { "ecmaVersion": 2018, - "sourceType": "module" + "sourceType": "module", + "ecmaFeatures": { + "jsx": true + } }, "rules": { "indent": [ diff --git a/js/api.js b/js/api.js index a760ada..3c5db29 100644 --- a/js/api.js +++ b/js/api.js @@ -1,13 +1,12 @@ -import { createStore, applyMiddleware, combineReducers } from 'redux' -import { composeWithDevTools } from 'redux-devtools-extension' -import thunkMiddleware from 'redux-thunk' -import { errorMessages } from './constants' +import { createStore, applyMiddleware, combineReducers } from 'redux'; +import { composeWithDevTools } from 'redux-devtools-extension'; +import thunkMiddleware from 'redux-thunk'; +import { errorMessages } from './constants'; const axios = require('axios'); const api_url = 'https://api.turnie.re'; - const actiontypes_userinfo = { 'REGISTER' : 'REGISTER', 'REGISTER_RESULT_SUCCESS' : 'REGISTER_RESULT_SUCCESS', @@ -27,7 +26,7 @@ const actiontypes_userinfo = { 'REHYDRATE' : 'USERINFO_REHYDRATE', 'CLEAR' : 'USERINFO_CLEAR', -} +}; const defaultstate_userinfo = { isSignedIn : false, @@ -39,7 +38,7 @@ const defaultstate_userinfo = { client : null, expiry : null, uid : null -} +}; export function postRequest(state, url, data) { return axios.post(api_url + url, data, { @@ -81,7 +80,7 @@ function storeOptionalToken(response) { expiry : response.headers['expiry'], uid : response.headers['uid'] } - }) + }); } } @@ -102,139 +101,136 @@ function checkForAuthenticationHeaders(response) { const reducer_userinfo = (state = defaultstate_userinfo, action) => { switch(action.type) { - case actiontypes_userinfo.REGISTER: - postRequest(state, '/users', { - 'username' : action.parameters.username, - 'email' : action.parameters.email, - 'password' : action.parameters.password - }).then((resp) => { + case actiontypes_userinfo.REGISTER: + postRequest(state, '/users', { + 'username' : action.parameters.username, + 'email' : action.parameters.email, + 'password' : action.parameters.password + }).then((resp) => { + __store.dispatch({ + type : actiontypes_userinfo.REGISTER_RESULT_SUCCESS + }); + storeOptionalToken(resp); + }).catch((error) => { + if (error.response) { __store.dispatch({ - type : actiontypes_userinfo.REGISTER_RESULT_SUCCESS - }); - storeOptionalToken(resp); - }).catch((error) => { - if (error.response) { - __store.dispatch({ - 'type' : actiontypes_userinfo.REGISTER_RESULT_ERROR, - 'parameters' : { - 'errorMessages' : error.response.data.errors.full_messages - } - }); - storeOptionalToken(error.response); - } else { - __store.dispatch({ - 'type' : actiontypes_userinfo.REGISTER_RESULT_ERROR, - 'parameters' : { - 'errorMessages' : [ - errorMessages['registration_errorunknown']['en'] - ] - } - }) - } - }); - return Object.assign({}, state, {}); - case actiontypes_userinfo.REGISTER_RESULT_SUCCESS: - return Object.assign({}, state, { - error : false, - errorMessages : [] - }); - case actiontypes_userinfo.REGISTER_RESULT_ERROR: - return Object.assign({}, state, { - error : true, - errorMessages : action.parameters.errorMessages - }); - case actiontypes_userinfo.LOGIN: - postRequest(state, '/users/sign_in', { - email : action.parameters.email, - password : action.parameters.password - }).then((resp) => { - __store.dispatch({ - type : actiontypes_userinfo.LOGIN_RESULT_SUCCESS, - parameters : { - username : resp.data.data.username, + 'type' : actiontypes_userinfo.REGISTER_RESULT_ERROR, + 'parameters' : { + 'errorMessages' : error.response.data.errors.full_messages } }); - storeOptionalToken(resp); - }).catch((error) => { - if(error.response) { - __store.dispatch({ - 'type' : actiontypes_userinfo.LOGIN_RESULT_ERROR, - 'parameters' : { - 'errorMessages' : error.response.data.errors - } - }); - storeOptionalToken(error.response); - } else { - __store.dispatch({ - 'type' : actiontypes_userinfo.LOGIN_RESULT_ERROR, - 'parameters' : { - 'errorMessages' : [ errorMessages['login_errorunknown']['en'] ] - } - }); + storeOptionalToken(error.response); + } else { + __store.dispatch({ + 'type' : actiontypes_userinfo.REGISTER_RESULT_ERROR, + 'parameters' : { + 'errorMessages' : [ + errorMessages['registration_errorunknown']['en'] + ] + } + }); + } + }); + return Object.assign({}, state, {}); + case actiontypes_userinfo.REGISTER_RESULT_SUCCESS: + return Object.assign({}, state, { + error : false, + errorMessages : [] + }); + case actiontypes_userinfo.REGISTER_RESULT_ERROR: + return Object.assign({}, state, { + error : true, + errorMessages : action.parameters.errorMessages + }); + case actiontypes_userinfo.LOGIN: + postRequest(state, '/users/sign_in', { + email : action.parameters.email, + password : action.parameters.password + }).then((resp) => { + __store.dispatch({ + type : actiontypes_userinfo.LOGIN_RESULT_SUCCESS, + parameters : { + username : resp.data.data.username, } }); - return Object.assign({}, state, {}); - case actiontypes_userinfo.LOGIN_RESULT_SUCCESS: - return Object.assign({}, state, { - isSignedIn : true, - error : false, - errorMessages : [], - username : action.parameters.username, - }); - case actiontypes_userinfo.LOGIN_RESULT_ERROR: - return Object.assign({}, state, { - error : true, - errorMessages : action.parameters.errorMessages - }); - - case actiontypes_userinfo.LOGOUT: - deleteRequest(state, '/users/sign_out').then((resp) => { - __store.dispatch({ type : actiontypes_userinfo.CLEAR }); - }).catch((error) => { - __store.dispatch({ type : actiontypes_userinfo.CLEAR }); - }); - return Object.assign({}, state, {}); - case actiontypes_userinfo.STORE_AUTH_HEADERS: - return Object.assign({}, state, { - accesstoken : action.parameters.accesstoken, - client : action.parameters.client, - expiry : action.parameters.expiry, - uid : action.parameters.uid - }); - - case actiontypes_userinfo.VERIFY_CREDENTIALS: - getRequest(state, '/users/validate_token').then((resp) => { - storeOptionalToken(resp); - }).catch((error) => { - __store.dispatch({ type: actiontypes_userinfo.CLEAR }); - }); - return Object.assign({}, state, {}); + storeOptionalToken(resp); + }).catch((error) => { + if(error.response) { + __store.dispatch({ + 'type' : actiontypes_userinfo.LOGIN_RESULT_ERROR, + 'parameters' : { + 'errorMessages' : error.response.data.errors + } + }); + storeOptionalToken(error.response); + } else { + __store.dispatch({ + 'type' : actiontypes_userinfo.LOGIN_RESULT_ERROR, + 'parameters' : { + 'errorMessages' : [ errorMessages['login_errorunknown']['en'] ] + } + }); + } + }); + return Object.assign({}, state, {}); + case actiontypes_userinfo.LOGIN_RESULT_SUCCESS: + return Object.assign({}, state, { + isSignedIn : true, + error : false, + errorMessages : [], + username : action.parameters.username, + }); + case actiontypes_userinfo.LOGIN_RESULT_ERROR: + return Object.assign({}, state, { + error : true, + errorMessages : action.parameters.errorMessages + }); + case actiontypes_userinfo.LOGOUT: + deleteRequest(state, '/users/sign_out').then(() => { + __store.dispatch({ type : actiontypes_userinfo.CLEAR }); + }).catch(() => { + __store.dispatch({ type : actiontypes_userinfo.CLEAR }); + }); + return Object.assign({}, state, {}); + case actiontypes_userinfo.STORE_AUTH_HEADERS: + return Object.assign({}, state, { + accesstoken : action.parameters.accesstoken, + client : action.parameters.client, + expiry : action.parameters.expiry, + uid : action.parameters.uid + }); + case actiontypes_userinfo.VERIFY_CREDENTIALS: + getRequest(state, '/users/validate_token').then((resp) => { + storeOptionalToken(resp); + }).catch(() => { + __store.dispatch({ type: actiontypes_userinfo.CLEAR }); + }); + return Object.assign({}, state, {}); + case actiontypes_userinfo.REHYDRATE: + return Object.assign({}, state, action.parameters); + case actiontypes_userinfo.CLEAR: + return Object.assign({}, state, { + isSignedIn : false, + username : null, + error : false, + errorMessages : [], - case actiontypes_userinfo.REHYDRATE: - return Object.assign({}, state, action.parameters); - case actiontypes_userinfo.CLEAR: - return Object.assign({}, state, { - isSignedIn : false, - username : null, - error : false, - errorMessages : [], - - accesstoken : null, - client : null, - expiry : null, - uid : null - }); - default: return state; + accesstoken : null, + client : null, + expiry : null, + uid : null + }); + default: return state; } -} +}; const reducers = { userinfo: reducer_userinfo -} +}; const default_applicationstate = { userinfo : defaultstate_userinfo -} +}; var __store; @@ -245,7 +241,7 @@ export function initializeStore(initialState = default_applicationstate) { composeWithDevTools(applyMiddleware(thunkMiddleware)) ); __store.subscribe(() => { - localStorage.setItem('reduxState', JSON.stringify(__store.getState())) + localStorage.setItem('reduxState', JSON.stringify(__store.getState())); }); return __store; } @@ -276,7 +272,7 @@ export function login(email, password) { email: email, password: password } - }) + }); } export function logout() { diff --git a/package.json b/package.json index 20b6cb6..50ad571 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ }, "devDependencies": { "eslint": "^5.9.0", + "eslint-plugin-react": "^7.11.1", "react-editable-list": "0.0.3" } } diff --git a/yarn.lock b/yarn.lock index a411c76..042a220 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1227,6 +1227,14 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= +array-includes@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.0.3.tgz#184b48f62d92d7452bb31b323165c7f8bd02266d" + integrity sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.7.0" + array-map@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" @@ -3169,7 +3177,7 @@ error@^7.0.2: string-template "~0.2.1" xtend "~4.0.0" -es-abstract@^1.5.1: +es-abstract@^1.5.1, es-abstract@^1.7.0: version "1.12.0" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== @@ -3199,6 +3207,17 @@ 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" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +eslint-plugin-react@^7.11.1: + version "7.11.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz#c01a7af6f17519457d6116aa94fc6d2ccad5443c" + integrity sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw== + dependencies: + array-includes "^3.0.3" + doctrine "^2.1.0" + has "^1.0.3" + jsx-ast-utils "^2.0.1" + prop-types "^15.6.2" + eslint-scope@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" @@ -4794,6 +4813,13 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= +jsx-ast-utils@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz#e801b1b39985e20fffc87b40e3748080e2dcac7f" + integrity sha1-6AGxs5mF4g//yHtA43SAgOLcrH8= + dependencies: + array-includes "^3.0.3" + junk@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/junk/-/junk-1.0.3.tgz#87be63488649cbdca6f53ab39bec9ccd2347f592" From 9124edc3f23f75389acc374e221a30e85ff60754 Mon Sep 17 00:00:00 2001 From: JP1998 Date: Sun, 9 Dec 2018 23:46:21 +0100 Subject: [PATCH 11/15] Fix all the styling issues in all the files --- .eslintrc.json | 2 + js/CommonComponents.js | 14 +- js/EditableStringList.js | 20 +- js/components/BigImage.js | 2 +- js/constants.js | 2 +- js/redux/reduxStoreBinder.js | 34 +- next.config.js | 4 +- pages/_app.js | 38 +- pages/_error.js | 92 ++-- pages/create.js | 33 +- pages/faq.js | 146 ++--- pages/imprint.js | 122 ++--- pages/index.js | 21 +- pages/list.js | 4 +- pages/login.js | 19 +- pages/privacy.js | 969 ++++++++++++++++----------------- pages/register.js | 19 +- pages/tournament-fullscreen.js | 7 +- pages/tournament.js | 9 +- server.js | 56 +- 20 files changed, 798 insertions(+), 815 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 6efdb03..60df449 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -16,6 +16,8 @@ } }, "rules": { + "react/jsx-uses-react": "error", + "react/jsx-uses-vars": "error", "indent": [ "error", 4 diff --git a/js/CommonComponents.js b/js/CommonComponents.js index 1ed65ed..408ab37 100644 --- a/js/CommonComponents.js +++ b/js/CommonComponents.js @@ -11,11 +11,11 @@ import { NavLink } 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'; export function BigImage(props) { return ( @@ -77,7 +77,7 @@ function Betabadge() { class InvisibleLoginLogoutButtons extends React.Component { render() { - const { isSignedIn, username } = this.props + const { isSignedIn, username } = this.props; if(isSignedIn) { return ( @@ -100,12 +100,12 @@ class InvisibleLoginLogoutButtons extends React.Component { const mapStateToLoginLogoutButtonProperties = (state) => { const { isSignedIn, username } = state.userinfo; - return { isSignedIn, username } -} + return { isSignedIn, username }; +}; const LoginLogoutButtons = connect( mapStateToLoginLogoutButtonProperties -)(InvisibleLoginLogoutButtons) +)(InvisibleLoginLogoutButtons); export function Footer() { return ( diff --git a/js/EditableStringList.js b/js/EditableStringList.js index a7cfda0..64ef704 100644 --- a/js/EditableStringList.js +++ b/js/EditableStringList.js @@ -1,5 +1,5 @@ -import React from "react"; -import {Alert, Button, Input, InputGroup, InputGroupAddon} from "reactstrap"; +import React from 'react'; +import { Alert, Button, Input, InputGroup, InputGroupAddon } from 'reactstrap'; export default class EditableStringList extends React.Component { constructor(props) { @@ -31,17 +31,14 @@ export default class EditableStringList extends React.Component { if ((typeof this.state.entries !== 'undefined') && this.state.entries.length > 0) { return (
- - {this.state.entries.map((text) => )} + + {this.state.entries.map((text) => )}
); } else { return (
- + {this.props.placeholder}
); @@ -64,8 +61,7 @@ class StringInput extends React.Component { render() { return ( - { + { if (e.key === 'Enter') { this.submit(); return false; @@ -73,10 +69,10 @@ class StringInput extends React.Component { }}/> + onClick={() => this.submit()}>{this.props.addButtonText} - ) + ); } submit() { diff --git a/js/components/BigImage.js b/js/components/BigImage.js index e442ab7..b89f6ff 100644 --- a/js/components/BigImage.js +++ b/js/components/BigImage.js @@ -1,4 +1,4 @@ -import React from "react"; +import React from 'react'; export function BigImage(props) { return ( diff --git a/js/constants.js b/js/constants.js index a0bc2e2..80ed3d7 100644 --- a/js/constants.js +++ b/js/constants.js @@ -7,5 +7,5 @@ export const errorMessages = { login_errorunknown : { en : 'An unknown error prevented a successful login.' } -} +}; diff --git a/js/redux/reduxStoreBinder.js b/js/redux/reduxStoreBinder.js index e685a1f..179d2a0 100644 --- a/js/redux/reduxStoreBinder.js +++ b/js/redux/reduxStoreBinder.js @@ -1,20 +1,20 @@ -import React from 'react' -import { initializeStore } from '../api' +import React from 'react'; +import { initializeStore } from '../api'; -const isServer = typeof window === 'undefined' -const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__' +const isServer = typeof window === 'undefined'; +const __NEXT_REDUX_STORE__ = '__NEXT_REDUX_STORE__'; function getOrCreateStore (initialState) { // Always make a new store if server, otherwise state is shared between requests if (isServer) { - return initializeStore(initialState) + return initializeStore(initialState); } // Create store if unavailable on the client and set it on the window object if (!window[__NEXT_REDUX_STORE__]) { - window[__NEXT_REDUX_STORE__] = initializeStore(initialState) + window[__NEXT_REDUX_STORE__] = initializeStore(initialState); } - return window[__NEXT_REDUX_STORE__] + return window[__NEXT_REDUX_STORE__]; } export default (App) => { @@ -22,29 +22,29 @@ export default (App) => { static async getInitialProps (appContext) { // Get or Create the store with `undefined` as initialState // This allows you to set a custom default initialState - const reduxStore = getOrCreateStore() + const reduxStore = getOrCreateStore(); // Provide the store to getInitialProps of pages - appContext.ctx.reduxStore = reduxStore + appContext.ctx.reduxStore = reduxStore; - let appProps = {} + let appProps = {}; if (typeof App.getInitialProps === 'function') { - appProps = await App.getInitialProps(appContext) + appProps = await App.getInitialProps(appContext); } return { ...appProps, initialReduxState: reduxStore.getState() - } + }; } constructor (props) { - super(props) - this.reduxStore = getOrCreateStore(props.initialReduxState) + super(props); + this.reduxStore = getOrCreateStore(props.initialReduxState); } render () { - return + return ; } - } -} + }; +}; diff --git a/next.config.js b/next.config.js index f8bd78a..f332296 100644 --- a/next.config.js +++ b/next.config.js @@ -1,3 +1,3 @@ -const withCSS = require('@zeit/next-css') -module.exports = withCSS() \ No newline at end of file +const withCSS = require('@zeit/next-css'); +module.exports = withCSS(); \ No newline at end of file diff --git a/pages/_app.js b/pages/_app.js index 9edc4f4..3bf91cd 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -1,25 +1,25 @@ -import App, {Container} from 'next/app' -import React from 'react' -import { Provider } from 'react-redux' -import withReduxStore from '../js/redux/reduxStoreBinder' -import { verifyCredentials } from '../js/api' +import App, {Container} from 'next/app'; +import React from 'react'; +import { Provider } from 'react-redux'; +import withReduxStore from '../js/redux/reduxStoreBinder'; +import { verifyCredentials } from '../js/api'; class TurniereApp extends App { - componentDidMount() { - verifyCredentials(); - } + componentDidMount() { + verifyCredentials(); + } - render () { - const {Component, pageProps, reduxStore} = this.props - return ( - - - - - - ) - } + render () { + const {Component, pageProps, reduxStore} = this.props; + return ( + + + + + + ); + } } -export default withReduxStore(TurniereApp) +export default withReduxStore(TurniereApp); diff --git a/pages/_error.js b/pages/_error.js index 300cb4a..202f1ca 100644 --- a/pages/_error.js +++ b/pages/_error.js @@ -1,15 +1,15 @@ -import Head from 'next/head' -import React from 'react' -import {Footer, TurniereNavigation} from "../js/CommonComponents"; +import Head from 'next/head'; +import React from 'react'; +import {Footer, TurniereNavigation} from '../js/CommonComponents'; import 'bootstrap/dist/css/bootstrap.min.css'; -import {Container} from "reactstrap"; -import '../static/everypage.css' -import '../static/css/error.css' +import {Container} from 'reactstrap'; +import '../static/everypage.css'; +import '../static/css/error.css'; export default class Error extends React.Component { static getInitialProps({ res, err }) { const statusCode = res ? res.statusCode : err ? err.statusCode : 400; - return { statusCode } + return { statusCode }; } render() { @@ -22,7 +22,7 @@ export default class Error extends React.Component {
- ) + ); } } @@ -44,43 +44,43 @@ function ErrorPage(props){ function ErrorMessage(props) { switch (props.code) { - case 400: - return (
-

Deine Anfrage ist fehlerhaft.

-

- Wir empfehlen, die eingegebene Seite über die Startseite zu suchen. -

-
); - case 403: - return (
-

Du bist nicht autorisiert, diese Seite aufzurufen.

-

- Bitte stelle sicher, dass Du angemeldet bist und auf dieses Turnier oder dieses Match zugreifen darfst. -

-

- Wir empfehlen, die eingegebene Seite über die Startseite zu suchen. -

-
); - case 404: - return (
-

Die aufgerufene Seite wurde leider nicht gefunden.

-

- Entweder hast Du dich vertippt, oder die gesuchte Seite gibt es nicht. -

-

- Wir empfehlen, die eingegebene Seite über die Startseite zu suchen. -

-
); - case 500: - return (
-

Diese Seite funktioniert nicht.

-

- turnie.re kann Deine Anfrage im Moment nicht verarbeiten. Bitte versuche es später erneut. -

-
); - default: - return (
-

Ein unbekannter Fehler ist aufgetreten.

-
); + case 400: + return (
+

Deine Anfrage ist fehlerhaft.

+

+ Wir empfehlen, die eingegebene Seite über die Startseite zu suchen. +

+
); + case 403: + return (
+

Du bist nicht autorisiert, diese Seite aufzurufen.

+

+ Bitte stelle sicher, dass Du angemeldet bist und auf dieses Turnier oder dieses Match zugreifen darfst. +

+

+ Wir empfehlen, die eingegebene Seite über die Startseite zu suchen. +

+
); + case 404: + return (
+

Die aufgerufene Seite wurde leider nicht gefunden.

+

+ Entweder hast Du dich vertippt, oder die gesuchte Seite gibt es nicht. +

+

+ Wir empfehlen, die eingegebene Seite über die Startseite zu suchen. +

+
); + case 500: + return (
+

Diese Seite funktioniert nicht.

+

+ turnie.re kann Deine Anfrage im Moment nicht verarbeiten. Bitte versuche es später erneut. +

+
); + default: + return (
+

Ein unbekannter Fehler ist aufgetreten.

+
); } } \ No newline at end of file diff --git a/pages/create.js b/pages/create.js index fbe38f9..d2ee8db 100644 --- a/pages/create.js +++ b/pages/create.js @@ -1,9 +1,22 @@ -import Head from 'next/head' -import '../static/everypage.css' -import {Footer, TurniereNavigation} from "../js/CommonComponents"; -import React from "react"; -import {Button, Card, CardBody, Container, CustomInput, Fade, Form, FormGroup, Input, Label} from "reactstrap"; -import EditableStringList from "../js/EditableStringList"; +import Head from 'next/head'; +import '../static/everypage.css'; +import { Footer, TurniereNavigation } from '../js/CommonComponents'; +import React from 'react'; + +import { + Button, + Card, + CardBody, + Container, + CustomInput, + Fade, + Form, + FormGroup, + Input, + Label +} from 'reactstrap'; + +import EditableStringList from '../js/EditableStringList'; export default () => (
@@ -16,7 +29,7 @@ export default () => (
-) +); function CreateTournamentCard() { return ( @@ -53,12 +66,12 @@ class CreateTournamentForm extends React.Component { + label="Turnier öffentlich anzeigen (schreibgeschützt)"/> + baseClassActive="d-block"> @@ -72,7 +85,7 @@ class CreateTournamentForm extends React.Component {

Teams

+ onChange={this.teamListUpdate} inputPlaceholder="Teamname"/>
); diff --git a/pages/faq.js b/pages/faq.js index 8dc0f79..57e3bdb 100644 --- a/pages/faq.js +++ b/pages/faq.js @@ -1,9 +1,9 @@ -import Head from 'next/head' -import React from 'react' +import Head from 'next/head'; +import React from 'react'; import {Col, Container, Row} from 'reactstrap'; import 'bootstrap/dist/css/bootstrap.min.css'; -import {BigImage, Footer, TurniereNavigation} from '../js/CommonComponents.js' -import '../static/everypage.css' +import { BigImage, Footer, TurniereNavigation } from '../js/CommonComponents.js'; +import '../static/everypage.css'; function Main() { return ( @@ -33,25 +33,28 @@ function GeneralFaq() { mit allen Leuten teilen kannst, ohne dir Gedanken machen zu müssen, wer gegen wen spielen muss. Du trägst ein, wer gewonnen hat, und turnie.re sagt, wer als nächstes spielt.

- -

Für welche Sportarten ist turnie.re geeignet?

-

- turnie.re ist prinzipiell für jede Sportart geeignet. Die einzige Vor­aus­setzung ist, dass - in jedem Spiel zwei Mannschaften oder Spieler gegeinander antreten und dass derjenige mit - den meisten Punkten gewinnt. -

- -

Für welche Anzahl an Teams ist turnie.re geeignet?

-

- turnie.re ist unabhängig von der Anzahl der Teams nutzbar. -

- -

Fallen für die Nutzung von turnie.re Kosten an?

-

- 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. -

- + + +

Für welche Sportarten ist turnie.re geeignet?

+

+ turnie.re ist prinzipiell für jede Sportart geeignet. Die einzige Vor­aus­setzung ist, dass + in jedem Spiel zwei Mannschaften oder Spieler gegeinander antreten und dass derjenige mit + den meisten Punkten gewinnt. +

+ + +

Für welche Anzahl an Teams ist turnie.re geeignet?

+

+ turnie.re ist unabhängig von der Anzahl der Teams nutzbar. +

+ + +

Fallen für die Nutzung von turnie.re Kosten an?

+

+ 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. +

+
); @@ -69,40 +72,46 @@ function AccountFaq() { dich als berechtigt verifizieren können, benötigst du einen Acoount, sodass wir dir die entsprechenden Bearbeitungsrechte zuteilen können.

- -

Welche Daten muss ich bei der Accounterstellung angeben?

-

- Um einen Account anzulegen musst du einen Nutzernamen, eine gültige E-Mailadresse sowie ein - Passwort angeben. -

- -

Wie werden meine Daten verarbeitet?

-

- Deine Daten werden in unserer Datenbank gespeichert. Eine Weitergabe dieser Daten an Dritte - erfolgt nicht!

-

- Zusätlich wird dein Passwort verschlüsselt gespeichert, das bedeutet auch wir kennen dein - Passwort nicht und dein Account wird zuverlässig geschützt. -

- -

Wie kann ich meinen Nutzernamen ändern?

-

- Über deinen Nutzernamen, der in der Kopfzeile angezeigt wird, gelangst du auf deine - Profilseite. Hier kannst du deinen Nutzernamen ändern. -

- -

Wie kann ich meine E-Mailadresse ändern?

-

- Über deinen Nutzernamen, der in der Kopfzeile angezeigt wird, gelangst du auf deine - Profilseite. Hier kannst du deine E-Mailadresse ändern ändern. -

- -

Wie kann ich mein Passwort ändern?

-

- Auf deiner Profilseite findest du einen "Passwort ändern" Button. Auf der sich dann - öffnenden Seite kannst du dein Passwort ändern. -

- + + +

Welche Daten muss ich bei der Accounterstellung angeben?

+

+ Um einen Account anzulegen musst du einen Nutzernamen, eine gültige E-Mailadresse sowie ein + Passwort angeben. +

+ + +

Wie werden meine Daten verarbeitet?

+

+ Deine Daten werden in unserer Datenbank gespeichert. Eine Weitergabe dieser Daten an Dritte + erfolgt nicht! +

+

+ Zusätlich wird dein Passwort verschlüsselt gespeichert, das bedeutet auch wir kennen dein + Passwort nicht und dein Account wird zuverlässig geschützt. +

+ + +

Wie kann ich meinen Nutzernamen ändern?

+

+ Über deinen Nutzernamen, der in der Kopfzeile angezeigt wird, gelangst du auf deine + Profilseite. Hier kannst du deinen Nutzernamen ändern. +

+ + +

Wie kann ich meine E-Mailadresse ändern?

+

+ Über deinen Nutzernamen, der in der Kopfzeile angezeigt wird, gelangst du auf deine + Profilseite. Hier kannst du deine E-Mailadresse ändern ändern. +

+ + +

Wie kann ich mein Passwort ändern?

+

+ Auf deiner Profilseite findest du einen "Passwort ändern" Button. Auf der sich dann + öffnenden Seite kannst du dein Passwort ändern. +

+
); @@ -121,15 +130,16 @@ function TournamentFaq() { Über "Turnier erstellen" gelangst du auf die "Turnier erstellen" Seite. Auf dieser kannst du deinem Turnier einen Namen geben und eine (optionale) Beschreibung hinzufügen. Dann kannst du dein Turnier öffentlich oder privat erstellen, die Teams - für die Spielpaarungen mischen lassen und eine Gruppenphase hinzufügen. Im Feld "Teams" kannst du die + für die Spielpaarungen mischen lassen und eine Gruppenphase + hinzufügen. Im Feld "Teams" kannst du die teilnehmenden Teams eintragen und hinzufügen.

Wenn du die Option Gruppenphase aktiviert hast, kannst du zusätzlich noch die Größe der Gruppen angeben.

- + +

Was ist der Unterschied zwischen einem öffentlichen und einem privaten Turnier?

@@ -147,7 +157,8 @@ function TournamentFaq() { Trotzdem bleibt der Turnierersteller der Einzige, der die Turnierinformationen bearbeiten und Spielstände eintragen kann.

- + +

Was bedeutet "Teams mischen"?

Die Spielpaarungen werden anhand der Eingabereihenfolge der Teams erstellt. So spielt z.B. @@ -157,7 +168,8 @@ function TournamentFaq() { Wenn du das nicht möchtest kannst du die Option "Teams mischen" aktivieren und die Spielpaarungen werden in einer zufälligen Reihenfolge erstellt.

- + +

Was passiert wenn ich die Gruppenphase aktiviere?

Grundsätzlich erstellt turnie.re dir einen Spielplan für ein Turnier ohne @@ -168,7 +180,8 @@ function TournamentFaq() {

Bitte beachte, dass die Anzahl der Teams durch die Gruppengröße teilbar sein muss.

- + +

Wie kann ich Teams hinzufügen?

Auf der "Turnier erstellen" Seite kannst du im Feld "Teams" deine Teams eintragen.

@@ -177,14 +190,15 @@ function TournamentFaq() { Button "Team hinzufügen" das Team deinem Turnier hinzufügen. Du kannst aber auch deine Teams als eine mit Kommas getrennte Liste eingeben und dann hinzufügen.

- - + +

Wie starte ich ein Spiel?

Auf der Turnierübersicht Seite gibt es für jede Partie einen "Spiel starten" Button. Über diesen kannst du einfach das jeweilige Spiel starten.

- + +

Wie trage ich einen Spielstand für eine Partie ein?

Auf der Turnierübersicht Seite gibt es für jede Partie einen "Spielstand ändern" Button. diff --git a/pages/imprint.js b/pages/imprint.js index 27a980e..feec607 100644 --- a/pages/imprint.js +++ b/pages/imprint.js @@ -1,9 +1,9 @@ -import Head from 'next/head' -import React from 'react' +import Head from 'next/head'; +import React from 'react'; import {Container} from 'reactstrap'; import 'bootstrap/dist/css/bootstrap.min.css'; -import {BigImage, Footer, TurniereNavigation} from '../js/CommonComponents.js' -import '../static/everypage.css' +import {BigImage, Footer, TurniereNavigation} from '../js/CommonComponents.js'; +import '../static/everypage.css'; function Main() { return ( @@ -14,68 +14,58 @@ function Main() { } function ImprintText(){ - return ( -

- Angaben gemäß §5 TMG: -

-

- Jonas Seydel
- August-Euler-Weg 3
- 76133 Karlsruhe
- Germany
-

- -

- Vertreten durch
- Jonas Seydel -

- -

- Kontakt
- jon@s-seydel.de -

- - -

Haftungsausschluss

- -

Haftung für Inhalte

- -

- Die Inhalte unserer Seiten wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit und Aktualität - der Inhalte können wir jedoch keine Gewähr übernehmen. Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene - Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als - 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. -

- -

Haftung für Links

- -

- Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können - wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der - 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. -

- -

Urheberrecht

- -

- Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht. - Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes - bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser Seite sind - 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. -

- - - ); + return ( + +

+ Angaben gemäß §5 TMG: +

+

+ Jonas Seydel
+ August-Euler-Weg 3
+ 76133 Karlsruhe
+ Germany
+

+

+ Vertreten durch
+ Jonas Seydel +

+

+ Kontakt
+ jon@s-seydel.de +

+

Haftungsausschluss

+

Haftung für Inhalte

+

+ Die Inhalte unserer Seiten wurden mit größter Sorgfalt erstellt. Für die Richtigkeit, Vollständigkeit und Aktualität + der Inhalte können wir jedoch keine Gewähr übernehmen. Als Diensteanbieter sind wir gemäß § 7 Abs.1 TMG für eigene + Inhalte auf diesen Seiten nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als + 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. +

+

Haftung für Links

+

+ Unser Angebot enthält Links zu externen Webseiten Dritter, auf deren Inhalte wir keinen Einfluss haben. Deshalb können + wir für diese fremden Inhalte auch keine Gewähr übernehmen. Für die Inhalte der verlinkten Seiten ist stets der + 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. +

+

Urheberrecht

+

+ Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen dem deutschen Urheberrecht. + Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art der Verwertung außerhalb der Grenzen des Urheberrechtes + bedürfen der schriftlichen Zustimmung des jeweiligen Autors bzw. Erstellers. Downloads und Kopien dieser Seite sind + 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. +

+
+ ); } diff --git a/pages/index.js b/pages/index.js index fe833b5..dee8a02 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,16 +1,16 @@ -import Head from 'next/head' -import React from 'react' +import Head from 'next/head'; +import React from 'react'; -import {Alert, Button, Card, CardBody} from 'reactstrap'; +import { Alert, Button, Card, CardBody } from 'reactstrap'; import 'bootstrap/dist/css/bootstrap.min.css'; -import { BigImage, Footer, TurniereNavigation } from '../js/CommonComponents.js' +import { BigImage, Footer, TurniereNavigation } from '../js/CommonComponents.js'; -import '../static/everypage.css' -import '../static/css/index.css' +import '../static/everypage.css'; +import '../static/css/index.css'; -import { connect } from 'react-redux' +import { connect } from 'react-redux'; function Main() { return ( @@ -26,7 +26,6 @@ function Marketing() { return (
-

Für jede Sportart

@@ -88,12 +87,10 @@ function MainBottomSummary() {

Ich habe einen Turniercode bekommen. Was nun?

- Der Turniercode führt dich direkt zu einem Turnier. Gebe dafür den Code oben - ein, dann wirst du sofort weitergeleitet. + Der Turniercode führt dich direkt zu einem Turnier. Gebe dafür den Code + oben ein, dann wirst du sofort weitergeleitet.

-

diff --git a/pages/list.js b/pages/list.js index 0425ab5..8dfe530 100644 --- a/pages/list.js +++ b/pages/list.js @@ -1,4 +1,4 @@ -import Head from 'next/head' +import Head from 'next/head'; export default () => (

@@ -7,4 +7,4 @@ export default () => (

Turnierliste

-) +); diff --git a/pages/login.js b/pages/login.js index 2c9ee22..6acc489 100644 --- a/pages/login.js +++ b/pages/login.js @@ -1,10 +1,10 @@ -import Head from 'next/head' -import '../static/everypage.css' -import {Footer, TurniereNavigation} from "../js/CommonComponents"; -import React from "react"; -import {Button, Card, CardBody, Container, Form, FormGroup, Input, Label} from "reactstrap"; -import { login } from '../js/api' -import { connect } from 'react-redux' +import Head from 'next/head'; +import '../static/everypage.css'; +import {Footer, TurniereNavigation} from '../js/CommonComponents'; +import React from 'react'; +import { Button, Card, CardBody, Container, Form, FormGroup, Input, Label } from 'reactstrap'; +import { login } from '../js/api'; +import { connect } from 'react-redux'; export default () => (
@@ -17,7 +17,7 @@ export default () => (
-) +); function Login() { return ( @@ -37,7 +37,6 @@ function Login() { } class LoginErrorList extends React.Component { - render() { const { error, errorMessages } = this.props; if(error) { @@ -64,7 +63,7 @@ class LoginErrorList extends React.Component { const mapStateToErrorMessages = (state) => { const { errorMessages, error } = state.userinfo; - return { errorMessages, error } + return { errorMessages, error }; }; const VisibleLoginErrorList = connect( diff --git a/pages/privacy.js b/pages/privacy.js index 08f8e9d..9f0c2b9 100644 --- a/pages/privacy.js +++ b/pages/privacy.js @@ -1,9 +1,9 @@ -import Head from 'next/head' -import React from 'react' +import Head from 'next/head'; +import React from 'react'; import {Container} from 'reactstrap'; import 'bootstrap/dist/css/bootstrap.min.css'; -import {BigImage, Footer, TurniereNavigation} from '../js/CommonComponents.js' -import '../static/everypage.css' +import { BigImage, Footer, TurniereNavigation } from '../js/CommonComponents.js'; +import '../static/everypage.css'; function Main() { return ( @@ -14,504 +14,477 @@ function Main() { } function PrivacyText(){ - return ( -

- Die nachfolgende Datenschutzerklärung gilt für die Nutzung unseres Online-Angebots turnie.re (nachfolgend - „Website“).
- Wir messen dem Datenschutz große Bedeutung bei. Die Erhebung und Verarbeitung Ihrer personenbezogenen Daten - geschieht - unter Beachtung der geltenden datenschutzrechtlichen Vorschriften, insbesondere der - Datenschutzgrundverordnung - (DSGVO). -

+ return ( + +

+ Die nachfolgende Datenschutzerklärung gilt für die Nutzung unseres Online-Angebots turnie.re (nachfolgend + „Website“).
+ Wir messen dem Datenschutz große Bedeutung bei. Die Erhebung und Verarbeitung Ihrer personenbezogenen Daten + geschieht + unter Beachtung der geltenden datenschutzrechtlichen Vorschriften, insbesondere der + Datenschutzgrundverordnung + (DSGVO). +

+

1 Verantwortlicher

+

+ Verantwortlicher für die Erhebung, Verarbeitung und Nutzung Ihrer personenbezogenen Daten im Sinne von Art. + 4 Nr. 7 + DSGVO ist +

+

+ Jonas Seydel
+ August-Euler-Weg 3
+ 76133 Karlsruhe
+ Germany
+ jon@s-seydel.de
+

+

+ Sofern Sie der Erhebung, Verarbeitung oder Nutzung Ihrer Daten durch uns nach Maßgabe dieser + Datenschutzbestimmungen + insgesamt oder für einzelne Maßnahmen widersprechen wollen, können Sie Ihren Widerspruch an den + Verantwortlichen + richten.
+ Sie können diese Datenschutzerklärung jederzeit speichern und ausdrucken. +

+

2 Allgemeine Zwecke der Verarbeitung

+

+ Wir verwenden personenbezogene Daten zum Zweck des Betriebs der Website. +

+

3 Welche Daten wir verwenden und warum

+

3.1 Hosting

+

+ Die von uns in Anspruch genommenen Hosting-Leistungen dienen der Zurverfügungstellung der folgenden + Leistungen: + Infrastruktur- und Plattformdienstleistungen, Rechenkapazität, Speicherplatz und Datenbankdienste, + Sicherheitsleistungen sowie technische Wartungsleistungen, die wir zum Zweck des Betriebs der Website + einsetzen.
+ Hierbei verarbeiten wir, bzw. unser Hostinganbieter Bestandsdaten, Kontaktdaten, Inhaltsdaten, + Vertragsdaten, + Nutzungsdaten, Meta- und Kommunikationsdaten von Kunden, Interessenten und Besuchern dieser Website auf + Grundlage + unserer berechtigten Interessen an einer effizienten und sicheren Zurverfügungstellung unserer Website gem. + Art. 6 + Abs. 1 S. 1 f) DSGVO i.V.m. Art. 28 DSGVO. +

+

3.2 Zugriffsdaten

+

+ Wir sammeln Informationen über Sie, wenn Sie diese Website nutzen. Wir erfassen automatisch Informationen + über Ihr + Nutzungsverhalten und Ihre Interaktion mit uns und registrieren Daten zu Ihrem Computer oder Mobilgerät. Wir + erheben, + speichern und nutzen Daten über jeden Zugriff auf unsere Website (sogenannte Serverlogfiles). Zu den + Zugriffsdaten + gehören: +

+
    +
  • Name und URL der abgerufenen Datei
  • +
  • Datum und Uhrzeit des Abrufs
  • +
  • übertragene Datenmenge
  • +
  • Meldung über erfolgreichen Abruf (HTTP response code)
  • +
  • Browsertyp und Browserversion
  • +
  • Betriebssystem
  • +
  • Referer URL (d.h. die zuvor besuchte Seite)
  • +
  • Websites, die vom System des Nutzers über unsere Website aufgerufen werden
  • +
  • Internet-Service-Provider des Nutzers
  • +
  • IP-Adresse und der anfragende Provider
  • +
+

+ Wir nutzen diese Protokolldaten ohne Zuordnung zu Ihrer Person oder sonstiger Profilerstellung für + statistische + Auswertungen zum Zweck des Betriebs, der Sicherheit und der Optimierung unserer Website, aber auch zur + anonymen + Erfassung der Anzahl der Besucher auf unserer Website (traffic) sowie zum Umfang und zur Art der Nutzung + unserer + Website und Dienste, ebenso zu Abrechnungszwecken, um die Anzahl der von Kooperationspartnern erhaltenen + 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.
+ Hierin liegt auch unser berechtigtes Interesse gemäß Art 6 Abs. 1 S. 1 f) DSGVO.
+ Wir behalten uns vor, die Protokolldaten nachträglich zu überprüfen, wenn aufgrund konkreter Anhaltspunkte + der + berechtigte Verdacht einer rechtswidrigen Nutzung besteht. IP-Adressen speichern wir für einen begrenzten + Zeitraum in + den Logfiles, wenn dies für Sicherheitszwecke erforderlich oder für die Leistungserbringung oder die + Abrechnung einer + Leistung nötig ist, z. B. wenn Sie eines unserer Angebote nutzen. Nach Abbruch des Vorgangs der Bestellung + oder nach + Zahlungseingang löschen wir die IP-Adresse, wenn diese für Sicherheitszwecke nicht mehr erforderlich ist. + 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.). +

+

3.3 Cookies

+

+ Wir verwenden sogenannte Session-Cookies, um unsere Website zu optimieren. Ein Session-Cookie ist eine + kleine + 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 sich + verschiedene + Anfragen Ihres Browsers der gemeinsamen Sitzung zuordnen lassen. Dadurch kann Ihr Rechner wiedererkannt + 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.
+ Wir verwenden in geringem Umfang auch persistente Cookies (ebenfalls kleine Textdateien, die auf Ihrem + Endgerät + abgelegt werden), die auf Ihrem Endgerät verbleiben und es uns ermöglichen, Ihren Browser beim nächsten + Besuch + wiederzuerkennen. Diese Cookies werden auf Ihrer Festplatte gespeichert und löschen sich nach der + 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 + Informationen + auf der Seite anzeigen.
+ Unser berechtigtes Interesse an der Nutzung der Cookies gemäß Art 6 Abs. 1 S. 1 f) DSGVO liegt darin, unsere + Website + nutzerfreundlicher, effektiver und sicherer zu machen.
+ In den Cookies werden etwa folgende Daten und Informationen gespeichert: +

+
    +
  • Log-In-Informationen
  • +
  • Spracheinstellungen
  • +
  • eingegebene Suchbegriffe
  • +
  • Informationen über die Anzahl der Aufrufe unserer Website sowie Nutzung einzelner Funktionen unseres + Internetauftritts. +
  • +
+

+ 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 + oder + ä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, beispielsweise darüber, + welche + Seiten unseres Shops besucht wurden, welche Produkte angesehen wurden, etc.
+ Sie können Ihren Browser so einstellen, dass Sie über das Setzen von Cookies vorab informiert werden und im + Einzelfall + entscheiden können, ob Sie die Annahme von Cookies für bestimmte Fälle oder generell ausschließen, oder dass + Cookies + komplett verhindert werden. Dadurch kann die Funktionalität der Website eingeschränkt werden. +

+

3.4 Nutzerkonto

+

Sie können auf unserer Website ein Nutzerkonto anlegen. Wünschen Sie dies, so benötigen wir die beim Login + abgefragten + personenbezogenen Daten. Beim späteren Einloggen werden nur Ihre Email bzw. Benutzername und das von Ihnen + gewählte + Passwort benötigt.
+ Für die Neuregistrierung erheben wir Stammdaten (z. B. Name, Adresse), Kommunikationsdaten (z. B. + E-Mail-Adresse) + sowie Zugangsdaten (Benutzername u. Passwort).
+ Sie können ein einmal angelegtes Nutzerkonto jederzeit von uns löschen lassen, ohne dass hierfür andere + als die + Ü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 + personenbezogenen Daten + löschen, soweit wir diese nicht noch zur Abwicklung von Bestellungen oder aufgrund gesetzlicher + Aufbewahrungspflichten + speichern müssen.
+ Rechtgrundlage für die Verarbeitung dieser Daten ist Ihre Einwilligung gemäß Art. 6 Abs. 1 S. 1 a) + DSGVO. +

+

3.5 E-Mail Kontakt

+

+ 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. + Erfolgt die Datenverarbeitung zur Durchführung vorvertraglicher Maßnahmen, die auf Ihre Anfrage hin + erfolgen, bzw., + wenn Sie bereits unser Kunde sind, zur Durchführung des Vertrages, ist Rechtsgrundlage für diese + Datenverarbeitung + Art. 6 Abs. 1 S. 1 b) DSGVO. + Weitere personenbezogene Daten verarbeiten wir nur, wenn Sie dazu einwilligen (Art. 6 Abs. 1 S. 1 a) DSGVO) + oder wir + 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. +

+

4 Speicherdauer

+

+ Sofern nicht spezifisch angegeben speichern wir personenbezogene Daten nur so lange, wie dies zur Erfüllung + der + verfolgten Zwecke notwendig ist.
+ In einigen Fällen sieht der Gesetzgeber die Aufbewahrung von personenbezogenen Daten vor, etwa im Steuer- + oder + Handelsrecht. In diesen Fällen werden die Daten von uns lediglich für diese gesetzlichen Zwecke weiter + gespeichert, + aber nicht anderweitig verarbeitet und nach Ablauf der gesetzlichen Aufbewahrungsfrist gelöscht. +

+

5 Ihre Rechte als von der Datenverarbeitung Betroffener

+

+ Nach den anwendbaren Gesetzen haben Sie verschiedene Rechte bezüglich Ihrer personenbezogenen Daten. Möchten + Sie diese + Rechte geltend machen, so richten Sie Ihre Anfrage bitte per E-Mail oder per Post unter eindeutiger + Identifizierung + Ihrer Person an die in Ziffer 1 genannte Adresse.
+ Nachfolgend finden Sie eine Übersicht über Ihre Rechte. +

+

5.1 Recht auf Bestätigung und Auskunft

+

+ Sie haben das Recht auf eine übersichtliche Auskunft über die Verarbeitung Ihrer personenbezogenen + Daten.
+ Im Einzelnen:
-

1 Verantwortlicher

-

- Verantwortlicher für die Erhebung, Verarbeitung und Nutzung Ihrer personenbezogenen Daten im Sinne von Art. - 4 Nr. 7 - DSGVO ist -

-

- Jonas Seydel
- August-Euler-Weg 3
- 76133 Karlsruhe
- Germany
- jon@s-seydel.de
-

-

- Sofern Sie der Erhebung, Verarbeitung oder Nutzung Ihrer Daten durch uns nach Maßgabe dieser - Datenschutzbestimmungen - insgesamt oder für einzelne Maßnahmen widersprechen wollen, können Sie Ihren Widerspruch an den - Verantwortlichen - richten.
- Sie können diese Datenschutzerklärung jederzeit speichern und ausdrucken. -

+ Sie haben jederzeit das Recht, von uns eine Bestätigung darüber zu erhalten, ob Sie betreffende + personenbezogene Daten + verarbeitet werden. Ist dies der Fall, so haben Sie das Recht, von uns eine unentgeltliche Auskunft über die + zu Ihnen + gespeicherten personenbezogenen Daten nebst einer Kopie dieser Daten zu verlangen. Des Weiteren besteht ein + Recht auf + folgende Informationen: +

+
    +
  1. die Verarbeitungszwecke;
  2. +
  3. die Kategorien personenbezogener Daten, die verarbeitet werden;
  4. +
  5. die Empfänger oder Kategorien von Empfängern, gegenüber denen die personenbezogenen Daten offengelegt + worden sind + oder noch offengelegt werden, insbesondere bei Empfängern in Drittländern oder bei internationalen + Organisationen; +
  6. +
  7. falls möglich, die geplante Dauer, für die die personenbezogenen Daten gespeichert werden, oder, falls + dies nicht + möglich ist, die Kriterien für die Festlegung dieser Dauer; +
  8. +
  9. das Bestehen eines Rechts auf Berichtigung oder Löschung der Sie betreffenden personenbezogenen Daten + oder auf + Einschränkung der Verarbeitung durch den Verantwortlichen oder eines Widerspruchsrechts gegen diese + Verarbeitung; +
  10. +
  11. das Bestehen eines Beschwerderechts bei einer Aufsichtsbehörde;
  12. +
  13. wenn die personenbezogenen Daten nicht bei Ihnen erhoben werden, alle verfügbaren Informationen über die + Herkunft + der Daten; +
  14. +
  15. das Bestehen einer automatisierten Entscheidungsfindung einschließlich Profiling gemäß Art. 22 Abs. 1 + und 4 DSGVO + und – zumindest in diesen Fällen – aussagekräftige Informationen über die involvierte Logik sowie die + Tragweite + und die angestrebten Auswirkungen einer derartigen Verarbeitung für Sie. +
  16. +
+

+ Werden personenbezogene Daten an ein Drittland oder an eine internationale Organisation übermittelt, so + haben Sie das + Recht, über die geeigneten Garantien gemäß Art. 46 DSGVO im Zusammenhang mit der Übermittlung unterrichtet + zu werden. +

+

5.2 Recht auf Berichtigung

+

+ Sie haben das Recht, von uns die Berichtigung und ggf. auch Vervollständigung Sie betreffender + personenbezogener Daten + zu verlangen.
+ Im Einzelnen:
+ Sie haben das Recht, von uns unverzüglich die Berichtigung Sie betreffender unrichtiger personenbezogener + Daten zu + verlangen. Unter Berücksichtigung der Zwecke der Verarbeitung haben Sie das Recht, die Vervollständigung + unvollständiger personenbezogener Daten – auch mittels einer ergänzenden Erklärung – zu verlangen.
+

+

5.3 Recht auf Löschung ("Recht auf Vergessenwerden")

+

+ In einer Reihe von Fällen sind wir verpflichtet, Sie betreffende personenbezogene Daten zu löschen.
+ Im Einzelnen:
+ Sie haben gemäß Art. 17 Abs. 1 DSGVO das Recht, von uns zu verlangen, dass Sie betreffende personenbezogene + Daten + unverzüglich gelöscht werden, und wir sind verpflichtet, personenbezogene Daten unverzüglich zu löschen, + sofern einer + der folgenden Gründe zutrifft: +

+
    +
  1. Die personenbezogenen Daten sind für die Zwecke, für die sie erhoben oder auf sonstige Weise verarbeitet + wurden, + nicht mehr notwendig. +
  2. +
  3. Sie widerrufen Ihre Einwilligung, auf die sich die Verarbeitung gemäß Art. 6 Abs. 1 S. 1 a) DSGVO oder + Art. 9 Abs. + 2 a) DSGVO stützte, und es fehlt an einer anderweitigen Rechtsgrundlage für die Verarbeitung. +
  4. +
  5. Sie legen gemäß Art. 21 Abs. 1 DSGVO Widerspruch gegen die Verarbeitung ein und es liegen keine + vorrangigen + berechtigten Gründe für die Verarbeitung vor, oder Sie legen gemäß Art. 21 Abs. 2 DSGVO Widerspruch + gegen die + Verarbeitung ein. +
  6. +
  7. Die personenbezogenen Daten wurden unrechtmäßig verarbeitet.
  8. +
  9. Die Löschung der personenbezogenen Daten ist zur Erfüllung einer rechtlichen Verpflichtung nach dem + Unionsrecht + oder dem Recht der Mitgliedstaaten erforderlich, dem wir unterliegen. +
  10. +
  11. Die personenbezogenen Daten wurden in Bezug auf angebotene Dienste der Informationsgesellschaft gemäß + Art. 8 Abs. + 1 DSGVO erhoben. +
  12. +
+

+ Haben wir die personenbezogenen Daten öffentlich gemacht und sind wir gemäß Art. 17 Abs. 1 DSGVO zu deren + Löschung + 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 Verantwortliche, die die + personenbezogenen + 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. +

+

5.4 Recht auf Einschränkung der Verarbeitung

+

+ In einer Reihe von Fällen sind Sie berechtigt, von uns eine Einschränkung der Verarbeitung Ihrer + personenbezogenen + Daten zu verlangen.
+ Im Einzelnen:
+ Sie haben das Recht, von uns die Einschränkung der Verarbeitung zu verlangen, wenn eine der folgenden + Voraussetzungen + gegeben ist: +

+
    +
  1. die Richtigkeit der personenbezogenen Daten wird von Ihnen bestritten, und zwar für eine Dauer, die es + uns + ermöglicht, die Richtigkeit der personenbezogenen Daten zu überprüfen, +
  2. +
  3. die Verarbeitung unrechtmäßig ist und Sie die Löschung der personenbezogenen Daten ablehnten und + stattdessen die + Einschränkung der Nutzung der personenbezogenen Daten verlangt haben; +
  4. +
  5. wir die personenbezogenen Daten für die Zwecke der Verarbeitung nicht länger benötigen, Sie die Daten + jedoch zur + Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen benötigen, oder +
  6. +
  7. Sie Widerspruch gegen die Verarbeitung gemäß Art. 21 Abs. 1 DSGVO eingelegt haben, solange noch nicht + feststeht, + ob die berechtigten Gründe unseres Unternehmens gegenüber den Ihren überwiegen. +
  8. +
+

5.5 Recht auf Datenübertragbarkeit

+

+ Sie haben das Recht, Sie betreffende personenbezogene Daten maschinenlesbar zu erhalten, zu übermitteln, + oder von uns + übermitteln zu lasen.
+ Im Einzelnen:
+ Sie haben das Recht, die Sie betreffenden personenbezogenen Daten, die Sie uns bereitgestellt haben, in + einem + strukturierten, gängigen und maschinenlesbaren Format zu erhalten, und Sie haben das Recht, diese Daten + einem anderen + Verantwortlichen ohne Behinderung durch uns zu übermitteln, sofern +

+
    +
  1. die Verarbeitung auf einer Einwilligung gemäß Art. 6 Abs. 1 S. 1 a) DSGVO oder Art. 9 Abs. 2 a) DSGVO + oder auf + einem Vertrag gemäß Art. 6 Abs. 1 S. 1 b) DSGVO beruht und +
  2. +
  3. die Verarbeitung mithilfe automatisierter Verfahren erfolgt.
  4. +
+

+ Bei der Ausübung Ihres Rechts auf Datenübertragbarkeit gemäß Absatz 1 haben Sie das Recht, zu erwirken, dass + die + personenbezogenen Daten direkt von uns einem anderen Verantwortlichen übermittelt werden, soweit dies + technisch + machbar ist. +

+

5.6 Widerspruchsrecht

+

+ Sie haben das Recht, auch einer rechtmäßigen Verarbeitung Ihrer personenbezogenen Daten durch uns zu + widersprechen, + wenn sich dies aus Ihrer besonderen Situation begründet und unsere Interessen an der Verarbeitung nicht + überwiegen.
+ Im Einzelnen:
+ Sie haben das Recht, aus Gründen, die sich aus Ihrer besonderen Situation ergeben, jederzeit gegen die + Verarbeitung + Sie betreffender personenbezogener Daten, die aufgrund von Art. 6 Abs. 1 S. 1 e) oder f) DSGVO erfolgt, + Widerspruch + einzulegen; dies gilt auch für ein auf diese Bestimmungen gestütztes Profiling. Wir verarbeiten die + personenbezogenen + 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, Ausübung oder + Verteidigung von Rechtsansprüchen.
+ Werden personenbezogene Daten von uns verarbeitet, um Direktwerbung zu betreiben, so haben Sie das Recht, + jederzeit + Widerspruch gegen die Verarbeitung Sie betreffender personenbezogener Daten zum Zwecke derartiger Werbung + einzulegen; + dies gilt auch für das Profiling, soweit es mit solcher Direktwerbung in Verbindung steht.
+ 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 + Forschungszwecken + oder zu statistischen Zwecken gemäß Art. 89 Abs. 1 DSGVO erfolgt, Widerspruch einzulegen, es sei denn, die + Verarbeitung ist zur Erfüllung einer im öffentlichen Interesse liegenden Aufgabe erforderlich.
+

+

5.7 Automatisierte Entscheidungen einschließlich Profiling

+

+ Sie haben das Recht, nicht einer ausschließlich auf einer automatisierten Verarbeitung – einschließlich + Profiling – + beruhenden Entscheidung unterworfen zu werden, die Ihnen gegenüber rechtliche Wirkung entfaltet oder Sie in + ähnlicher + Weise erheblich beeinträchtigt.
+ Eine automatisierte Entscheidungsfindung auf der Grundlage der erhobenen personenbezogenen Daten findet + nicht statt. +

+

5.8 Recht auf Widerruf einer datenschutzrechtlichen Einwilligung

+

+ Sie haben das Recht, eine Einwilligung zur Verarbeitung personenbezogener Daten jederzeit zu widerrufen. +

-

2 Allgemeine Zwecke der Verarbeitung

-

- Wir verwenden personenbezogene Daten zum Zweck des Betriebs der Website. -

- - -

3 Welche Daten wir verwenden und warum

- -

3.1 Hosting

-

- Die von uns in Anspruch genommenen Hosting-Leistungen dienen der Zurverfügungstellung der folgenden - Leistungen: - Infrastruktur- und Plattformdienstleistungen, Rechenkapazität, Speicherplatz und Datenbankdienste, - Sicherheitsleistungen sowie technische Wartungsleistungen, die wir zum Zweck des Betriebs der Website - einsetzen.
- Hierbei verarbeiten wir, bzw. unser Hostinganbieter Bestandsdaten, Kontaktdaten, Inhaltsdaten, - Vertragsdaten, - Nutzungsdaten, Meta- und Kommunikationsdaten von Kunden, Interessenten und Besuchern dieser Website auf - Grundlage - unserer berechtigten Interessen an einer effizienten und sicheren Zurverfügungstellung unserer Website gem. - Art. 6 - Abs. 1 S. 1 f) DSGVO i.V.m. Art. 28 DSGVO. -

- -

3.2 Zugriffsdaten

-

- Wir sammeln Informationen über Sie, wenn Sie diese Website nutzen. Wir erfassen automatisch Informationen - über Ihr - Nutzungsverhalten und Ihre Interaktion mit uns und registrieren Daten zu Ihrem Computer oder Mobilgerät. Wir - erheben, - speichern und nutzen Daten über jeden Zugriff auf unsere Website (sogenannte Serverlogfiles). Zu den - Zugriffsdaten - gehören: -

-
    -
  • Name und URL der abgerufenen Datei
  • -
  • Datum und Uhrzeit des Abrufs
  • -
  • übertragene Datenmenge
  • -
  • Meldung über erfolgreichen Abruf (HTTP response code)
  • -
  • Browsertyp und Browserversion
  • -
  • Betriebssystem
  • -
  • Referer URL (d.h. die zuvor besuchte Seite)
  • -
  • Websites, die vom System des Nutzers über unsere Website aufgerufen werden
  • -
  • Internet-Service-Provider des Nutzers
  • -
  • IP-Adresse und der anfragende Provider
  • -
-

- Wir nutzen diese Protokolldaten ohne Zuordnung zu Ihrer Person oder sonstiger Profilerstellung für - statistische - Auswertungen zum Zweck des Betriebs, der Sicherheit und der Optimierung unserer Website, aber auch zur - anonymen - Erfassung der Anzahl der Besucher auf unserer Website (traffic) sowie zum Umfang und zur Art der Nutzung - unserer - Website und Dienste, ebenso zu Abrechnungszwecken, um die Anzahl der von Kooperationspartnern erhaltenen - 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.
- Hierin liegt auch unser berechtigtes Interesse gemäß Art 6 Abs. 1 S. 1 f) DSGVO.
- Wir behalten uns vor, die Protokolldaten nachträglich zu überprüfen, wenn aufgrund konkreter Anhaltspunkte - der - berechtigte Verdacht einer rechtswidrigen Nutzung besteht. IP-Adressen speichern wir für einen begrenzten - Zeitraum in - den Logfiles, wenn dies für Sicherheitszwecke erforderlich oder für die Leistungserbringung oder die - Abrechnung einer - Leistung nötig ist, z. B. wenn Sie eines unserer Angebote nutzen. Nach Abbruch des Vorgangs der Bestellung - oder nach - Zahlungseingang löschen wir die IP-Adresse, wenn diese für Sicherheitszwecke nicht mehr erforderlich ist. - 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.). -

- -

3.3 Cookies

-

- Wir verwenden sogenannte Session-Cookies, um unsere Website zu optimieren. Ein Session-Cookie ist eine - kleine - 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 sich - verschiedene - Anfragen Ihres Browsers der gemeinsamen Sitzung zuordnen lassen. Dadurch kann Ihr Rechner wiedererkannt - 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.
- Wir verwenden in geringem Umfang auch persistente Cookies (ebenfalls kleine Textdateien, die auf Ihrem - Endgerät - abgelegt werden), die auf Ihrem Endgerät verbleiben und es uns ermöglichen, Ihren Browser beim nächsten - Besuch - wiederzuerkennen. Diese Cookies werden auf Ihrer Festplatte gespeichert und löschen sich nach der - 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 - Informationen - auf der Seite anzeigen.
- Unser berechtigtes Interesse an der Nutzung der Cookies gemäß Art 6 Abs. 1 S. 1 f) DSGVO liegt darin, unsere - Website - nutzerfreundlicher, effektiver und sicherer zu machen.
- In den Cookies werden etwa folgende Daten und Informationen gespeichert: -

-
    -
  • Log-In-Informationen
  • -
  • Spracheinstellungen
  • -
  • eingegebene Suchbegriffe
  • -
  • Informationen über die Anzahl der Aufrufe unserer Website sowie Nutzung einzelner Funktionen unseres - Internetauftritts. -
  • -
-

- 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 - oder - ä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, beispielsweise darüber, - welche - Seiten unseres Shops besucht wurden, welche Produkte angesehen wurden, etc.
- Sie können Ihren Browser so einstellen, dass Sie über das Setzen von Cookies vorab informiert werden und im - Einzelfall - entscheiden können, ob Sie die Annahme von Cookies für bestimmte Fälle oder generell ausschließen, oder dass - Cookies - komplett verhindert werden. Dadurch kann die Funktionalität der Website eingeschränkt werden. -

- -

3.4 Nutzerkonto

-

Sie können auf unserer Website ein Nutzerkonto anlegen. Wünschen Sie dies, so benötigen wir die beim Login - abgefragten - personenbezogenen Daten. Beim späteren Einloggen werden nur Ihre Email bzw. Benutzername und das von Ihnen - gewählte - Passwort benötigt.
- Für die Neuregistrierung erheben wir Stammdaten (z. B. Name, Adresse), Kommunikationsdaten (z. B. - E-Mail-Adresse) - sowie Zugangsdaten (Benutzername u. Passwort).
- Sie können ein einmal angelegtes Nutzerkonto jederzeit von uns löschen lassen, ohne dass hierfür andere - als die - Ü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 - personenbezogenen Daten - löschen, soweit wir diese nicht noch zur Abwicklung von Bestellungen oder aufgrund gesetzlicher - Aufbewahrungspflichten - speichern müssen.
- Rechtgrundlage für die Verarbeitung dieser Daten ist Ihre Einwilligung gemäß Art. 6 Abs. 1 S. 1 a) - DSGVO. -

- -

3.5 E-Mail Kontakt

-

- 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. - Erfolgt die Datenverarbeitung zur Durchführung vorvertraglicher Maßnahmen, die auf Ihre Anfrage hin - erfolgen, bzw., - wenn Sie bereits unser Kunde sind, zur Durchführung des Vertrages, ist Rechtsgrundlage für diese - Datenverarbeitung - Art. 6 Abs. 1 S. 1 b) DSGVO. - Weitere personenbezogene Daten verarbeiten wir nur, wenn Sie dazu einwilligen (Art. 6 Abs. 1 S. 1 a) DSGVO) - oder wir - 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. -

- - -

4 Speicherdauer

-

- Sofern nicht spezifisch angegeben speichern wir personenbezogene Daten nur so lange, wie dies zur Erfüllung - der - verfolgten Zwecke notwendig ist.
- In einigen Fällen sieht der Gesetzgeber die Aufbewahrung von personenbezogenen Daten vor, etwa im Steuer- - oder - Handelsrecht. In diesen Fällen werden die Daten von uns lediglich für diese gesetzlichen Zwecke weiter - gespeichert, - aber nicht anderweitig verarbeitet und nach Ablauf der gesetzlichen Aufbewahrungsfrist gelöscht. -

- - -

5 Ihre Rechte als von der Datenverarbeitung Betroffener

-

- Nach den anwendbaren Gesetzen haben Sie verschiedene Rechte bezüglich Ihrer personenbezogenen Daten. Möchten - Sie diese - Rechte geltend machen, so richten Sie Ihre Anfrage bitte per E-Mail oder per Post unter eindeutiger - Identifizierung - Ihrer Person an die in Ziffer 1 genannte Adresse.
- Nachfolgend finden Sie eine Übersicht über Ihre Rechte. -

- -

5.1 Recht auf Bestätigung und Auskunft

-

- Sie haben das Recht auf eine übersichtliche Auskunft über die Verarbeitung Ihrer personenbezogenen - Daten.
- Im Einzelnen:
- - Sie haben jederzeit das Recht, von uns eine Bestätigung darüber zu erhalten, ob Sie betreffende - personenbezogene Daten - verarbeitet werden. Ist dies der Fall, so haben Sie das Recht, von uns eine unentgeltliche Auskunft über die - zu Ihnen - gespeicherten personenbezogenen Daten nebst einer Kopie dieser Daten zu verlangen. Des Weiteren besteht ein - Recht auf - folgende Informationen: -

-
    -
  1. die Verarbeitungszwecke;
  2. -
  3. die Kategorien personenbezogener Daten, die verarbeitet werden;
  4. -
  5. die Empfänger oder Kategorien von Empfängern, gegenüber denen die personenbezogenen Daten offengelegt - worden sind - oder noch offengelegt werden, insbesondere bei Empfängern in Drittländern oder bei internationalen - Organisationen; -
  6. -
  7. falls möglich, die geplante Dauer, für die die personenbezogenen Daten gespeichert werden, oder, falls - dies nicht - möglich ist, die Kriterien für die Festlegung dieser Dauer; -
  8. -
  9. das Bestehen eines Rechts auf Berichtigung oder Löschung der Sie betreffenden personenbezogenen Daten - oder auf - Einschränkung der Verarbeitung durch den Verantwortlichen oder eines Widerspruchsrechts gegen diese - Verarbeitung; -
  10. -
  11. das Bestehen eines Beschwerderechts bei einer Aufsichtsbehörde;
  12. -
  13. wenn die personenbezogenen Daten nicht bei Ihnen erhoben werden, alle verfügbaren Informationen über die - Herkunft - der Daten; -
  14. -
  15. das Bestehen einer automatisierten Entscheidungsfindung einschließlich Profiling gemäß Art. 22 Abs. 1 - und 4 DSGVO - und – zumindest in diesen Fällen – aussagekräftige Informationen über die involvierte Logik sowie die - Tragweite - und die angestrebten Auswirkungen einer derartigen Verarbeitung für Sie. -
  16. -
- -

- Werden personenbezogene Daten an ein Drittland oder an eine internationale Organisation übermittelt, so - haben Sie das - Recht, über die geeigneten Garantien gemäß Art. 46 DSGVO im Zusammenhang mit der Übermittlung unterrichtet - zu werden. -

- -

5.2 Recht auf Berichtigung

-

- Sie haben das Recht, von uns die Berichtigung und ggf. auch Vervollständigung Sie betreffender - personenbezogener Daten - zu verlangen.
- Im Einzelnen:
- Sie haben das Recht, von uns unverzüglich die Berichtigung Sie betreffender unrichtiger personenbezogener - Daten zu - verlangen. Unter Berücksichtigung der Zwecke der Verarbeitung haben Sie das Recht, die Vervollständigung - unvollständiger personenbezogener Daten – auch mittels einer ergänzenden Erklärung – zu verlangen.
-

- -

5.3 Recht auf Löschung ("Recht auf Vergessenwerden")

-

- In einer Reihe von Fällen sind wir verpflichtet, Sie betreffende personenbezogene Daten zu löschen.
- Im Einzelnen:
- Sie haben gemäß Art. 17 Abs. 1 DSGVO das Recht, von uns zu verlangen, dass Sie betreffende personenbezogene - Daten - unverzüglich gelöscht werden, und wir sind verpflichtet, personenbezogene Daten unverzüglich zu löschen, - sofern einer - der folgenden Gründe zutrifft: -

-
    -
  1. Die personenbezogenen Daten sind für die Zwecke, für die sie erhoben oder auf sonstige Weise verarbeitet - wurden, - nicht mehr notwendig. -
  2. -
  3. Sie widerrufen Ihre Einwilligung, auf die sich die Verarbeitung gemäß Art. 6 Abs. 1 S. 1 a) DSGVO oder - Art. 9 Abs. - 2 a) DSGVO stützte, und es fehlt an einer anderweitigen Rechtsgrundlage für die Verarbeitung. -
  4. -
  5. Sie legen gemäß Art. 21 Abs. 1 DSGVO Widerspruch gegen die Verarbeitung ein und es liegen keine - vorrangigen - berechtigten Gründe für die Verarbeitung vor, oder Sie legen gemäß Art. 21 Abs. 2 DSGVO Widerspruch - gegen die - Verarbeitung ein. -
  6. -
  7. Die personenbezogenen Daten wurden unrechtmäßig verarbeitet.
  8. -
  9. Die Löschung der personenbezogenen Daten ist zur Erfüllung einer rechtlichen Verpflichtung nach dem - Unionsrecht - oder dem Recht der Mitgliedstaaten erforderlich, dem wir unterliegen. -
  10. -
  11. Die personenbezogenen Daten wurden in Bezug auf angebotene Dienste der Informationsgesellschaft gemäß - Art. 8 Abs. - 1 DSGVO erhoben. -
  12. -
-

- Haben wir die personenbezogenen Daten öffentlich gemacht und sind wir gemäß Art. 17 Abs. 1 DSGVO zu deren - Löschung - 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 Verantwortliche, die die - personenbezogenen - 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. -

- -

5.4 Recht auf Einschränkung der Verarbeitung

-

- In einer Reihe von Fällen sind Sie berechtigt, von uns eine Einschränkung der Verarbeitung Ihrer - personenbezogenen - Daten zu verlangen.
- Im Einzelnen:
- Sie haben das Recht, von uns die Einschränkung der Verarbeitung zu verlangen, wenn eine der folgenden - Voraussetzungen - gegeben ist: -

-
    -
  1. die Richtigkeit der personenbezogenen Daten wird von Ihnen bestritten, und zwar für eine Dauer, die es - uns - ermöglicht, die Richtigkeit der personenbezogenen Daten zu überprüfen, -
  2. -
  3. die Verarbeitung unrechtmäßig ist und Sie die Löschung der personenbezogenen Daten ablehnten und - stattdessen die - Einschränkung der Nutzung der personenbezogenen Daten verlangt haben; -
  4. -
  5. wir die personenbezogenen Daten für die Zwecke der Verarbeitung nicht länger benötigen, Sie die Daten - jedoch zur - Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen benötigen, oder -
  6. -
  7. Sie Widerspruch gegen die Verarbeitung gemäß Art. 21 Abs. 1 DSGVO eingelegt haben, solange noch nicht - feststeht, - ob die berechtigten Gründe unseres Unternehmens gegenüber den Ihren überwiegen. -
  8. -
- -

5.5 Recht auf Datenübertragbarkeit

-

- Sie haben das Recht, Sie betreffende personenbezogene Daten maschinenlesbar zu erhalten, zu übermitteln, - oder von uns - übermitteln zu lasen.
- Im Einzelnen:
- Sie haben das Recht, die Sie betreffenden personenbezogenen Daten, die Sie uns bereitgestellt haben, in - einem - strukturierten, gängigen und maschinenlesbaren Format zu erhalten, und Sie haben das Recht, diese Daten - einem anderen - Verantwortlichen ohne Behinderung durch uns zu übermitteln, sofern -

-
    -
  1. die Verarbeitung auf einer Einwilligung gemäß Art. 6 Abs. 1 S. 1 a) DSGVO oder Art. 9 Abs. 2 a) DSGVO - oder auf - einem Vertrag gemäß Art. 6 Abs. 1 S. 1 b) DSGVO beruht und -
  2. -
  3. die Verarbeitung mithilfe automatisierter Verfahren erfolgt.
  4. -
-

- Bei der Ausübung Ihres Rechts auf Datenübertragbarkeit gemäß Absatz 1 haben Sie das Recht, zu erwirken, dass - die - personenbezogenen Daten direkt von uns einem anderen Verantwortlichen übermittelt werden, soweit dies - technisch - machbar ist. -

- -

5.6 Widerspruchsrecht

-

- Sie haben das Recht, auch einer rechtmäßigen Verarbeitung Ihrer personenbezogenen Daten durch uns zu - widersprechen, - wenn sich dies aus Ihrer besonderen Situation begründet und unsere Interessen an der Verarbeitung nicht - überwiegen.
- Im Einzelnen:
- Sie haben das Recht, aus Gründen, die sich aus Ihrer besonderen Situation ergeben, jederzeit gegen die - Verarbeitung - Sie betreffender personenbezogener Daten, die aufgrund von Art. 6 Abs. 1 S. 1 e) oder f) DSGVO erfolgt, - Widerspruch - einzulegen; dies gilt auch für ein auf diese Bestimmungen gestütztes Profiling. Wir verarbeiten die - personenbezogenen - 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, Ausübung oder - Verteidigung von Rechtsansprüchen.
- Werden personenbezogene Daten von uns verarbeitet, um Direktwerbung zu betreiben, so haben Sie das Recht, - jederzeit - Widerspruch gegen die Verarbeitung Sie betreffender personenbezogener Daten zum Zwecke derartiger Werbung - einzulegen; - dies gilt auch für das Profiling, soweit es mit solcher Direktwerbung in Verbindung steht.
- 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 - Forschungszwecken - oder zu statistischen Zwecken gemäß Art. 89 Abs. 1 DSGVO erfolgt, Widerspruch einzulegen, es sei denn, die - Verarbeitung ist zur Erfüllung einer im öffentlichen Interesse liegenden Aufgabe erforderlich.
-

- -

5.7 Automatisierte Entscheidungen einschließlich Profiling

-

- Sie haben das Recht, nicht einer ausschließlich auf einer automatisierten Verarbeitung – einschließlich - Profiling – - beruhenden Entscheidung unterworfen zu werden, die Ihnen gegenüber rechtliche Wirkung entfaltet oder Sie in - ähnlicher - Weise erheblich beeinträchtigt.
- Eine automatisierte Entscheidungsfindung auf der Grundlage der erhobenen personenbezogenen Daten findet - nicht statt. -

- -

5.8 Recht auf Widerruf einer datenschutzrechtlichen Einwilligung

-

- Sie haben das Recht, eine Einwilligung zur Verarbeitung personenbezogener Daten jederzeit zu widerrufen. -

- -

5.9 Recht auf Beschwerde bei einer Aufsichtsbehörde

-

- 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, - dass die - Verarbeitung der Sie betreffenden personenbezogenen Daten rechtswidrig ist. -

- - -

6 Datensicherheit

-

- Wir sind um die Sicherheit Ihrer Daten im Rahmen der geltenden Datenschutzgesetze und technischen - Möglichkeiten - maximal bemüht.
- Ihre persönlichen Daten werden bei uns verschlüsselt übertragen. Dies gilt für Ihre Bestellungen und auch - für das - Kundenlogin. Wir nutzen das Codierungssystem SSL (Secure Socket Layer), weisen jedoch darauf hin, dass die - Datenübertragung im Internet (z.B. bei der Kommunikation per E-Mail) Sicherheitslücken aufweisen kann. Ein - lückenloser - Schutz der Daten vor dem Zugriff durch Dritte ist nicht möglich.
- Zur Sicherung Ihrer Daten unterhalten wir technische und organisatorische Sicherungsmaßnahmen entsprechend - Art. 32 - DSGVO, die wir immer wieder dem Stand der Technik anpassen.
- Wir gewährleisten außerdem nicht, dass unser Angebot zu bestimmten Zeiten zur Verfügung steht; Störungen, - Unterbrechungen oder Ausfälle können nicht ausgeschlossen werden. Die von uns verwendeten Server werden - regelmäßig - sorgfältig gesichert. -

- - -

7 Weitergabe von Daten an Dritte, keine Datenübertragung ins Nicht-EU-Ausland

-

- Grundsätzlich verwenden wir Ihre personenbezogenen Daten nur innerhalb unseres Unternehmens.
- Wenn und soweit wir Dritte im Rahmen der Erfüllung von Verträgen einschalten (etwa Logistik-Dienstleister), - erhalten - diese personenbezogene Daten nur in dem Umfang, in welchem die Übermittlung für die entsprechende Leistung - erforderlich ist.
- Für den Fall, dass wir bestimmte Teile der Datenverarbeitung auslagern („Auftragsverarbeitung“), - verpflichten wir - Auftragsverarbeiter vertraglich dazu, personenbezogene Daten nur im Einklang mit den Anforderungen der - Datenschutzgesetze zu verwenden und den Schutz der Rechte der betroffenen Person zu gewährleisten.
- Eine Datenübertragung an Stellen oder Personen außerhalb der EU außerhalb des in dieser Erklärung in Ziffer - 4 - genannten Falls findet nicht statt und ist nicht geplant. -

- - -

8 Datenschutzbeauftragter

-

- Sollten Sie noch Fragen oder Bedenken zum Datenschutz haben, so wenden Sie sich bitte an unseren - Datenschutzbeauftragten: -

-

- Jonas Seydel
- August-Euler-Weg 3
- 76133 Karlsruhe
- Germany
- jon@s-seydel.de -

- -
); +

5.9 Recht auf Beschwerde bei einer Aufsichtsbehörde

+

+ 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, + dass die + Verarbeitung der Sie betreffenden personenbezogenen Daten rechtswidrig ist. +

+

6 Datensicherheit

+

+ Wir sind um die Sicherheit Ihrer Daten im Rahmen der geltenden Datenschutzgesetze und technischen + Möglichkeiten + maximal bemüht.
+ Ihre persönlichen Daten werden bei uns verschlüsselt übertragen. Dies gilt für Ihre Bestellungen und auch + für das + Kundenlogin. Wir nutzen das Codierungssystem SSL (Secure Socket Layer), weisen jedoch darauf hin, dass die + Datenübertragung im Internet (z.B. bei der Kommunikation per E-Mail) Sicherheitslücken aufweisen kann. Ein + lückenloser + Schutz der Daten vor dem Zugriff durch Dritte ist nicht möglich.
+ Zur Sicherung Ihrer Daten unterhalten wir technische und organisatorische Sicherungsmaßnahmen entsprechend + Art. 32 + DSGVO, die wir immer wieder dem Stand der Technik anpassen.
+ Wir gewährleisten außerdem nicht, dass unser Angebot zu bestimmten Zeiten zur Verfügung steht; Störungen, + Unterbrechungen oder Ausfälle können nicht ausgeschlossen werden. Die von uns verwendeten Server werden + regelmäßig + sorgfältig gesichert. +

+

7 Weitergabe von Daten an Dritte, keine Datenübertragung ins Nicht-EU-Ausland

+

+ Grundsätzlich verwenden wir Ihre personenbezogenen Daten nur innerhalb unseres Unternehmens.
+ Wenn und soweit wir Dritte im Rahmen der Erfüllung von Verträgen einschalten (etwa Logistik-Dienstleister), + erhalten + diese personenbezogene Daten nur in dem Umfang, in welchem die Übermittlung für die entsprechende Leistung + erforderlich ist.
+ Für den Fall, dass wir bestimmte Teile der Datenverarbeitung auslagern („Auftragsverarbeitung“), + verpflichten wir + Auftragsverarbeiter vertraglich dazu, personenbezogene Daten nur im Einklang mit den Anforderungen der + Datenschutzgesetze zu verwenden und den Schutz der Rechte der betroffenen Person zu gewährleisten.
+ Eine Datenübertragung an Stellen oder Personen außerhalb der EU außerhalb des in dieser Erklärung in Ziffer + 4 + genannten Falls findet nicht statt und ist nicht geplant. +

+

8 Datenschutzbeauftragter

+

+ Sollten Sie noch Fragen oder Bedenken zum Datenschutz haben, so wenden Sie sich bitte an unseren + Datenschutzbeauftragten: +

+

+ Jonas Seydel
+ August-Euler-Weg 3
+ 76133 Karlsruhe
+ Germany
+ jon@s-seydel.de +

+
+ ); } diff --git a/pages/register.js b/pages/register.js index 00b3cfa..cf0365f 100644 --- a/pages/register.js +++ b/pages/register.js @@ -1,10 +1,10 @@ -import Head from 'next/head' -import '../static/everypage.css' -import {Footer, TurniereNavigation} from "../js/CommonComponents"; -import React from "react"; -import {Button, Card, CardBody, Container, Form, FormGroup, FormText, Input, Label} from "reactstrap"; -import { register } from '../js/api' -import { connect } from 'react-redux' +import Head from 'next/head'; +import '../static/everypage.css'; +import {Footer, TurniereNavigation} from '../js/CommonComponents'; +import React from 'react'; +import { Button, Card, CardBody, Container, Form, FormGroup, FormText, Input, Label } from 'reactstrap'; +import { register } from '../js/api'; +import { connect } from 'react-redux'; export default () => (
@@ -18,7 +18,7 @@ export default () => (
-) +); function Register() { return ( @@ -37,7 +37,6 @@ function Register() { } class RegisterErrorList extends React.Component { - render() { const { error, errorMessages } = this.props; if(error) { @@ -64,7 +63,7 @@ class RegisterErrorList extends React.Component { const mapStateToErrorMessages = (state) => { const { errorMessages, error } = state.userinfo; - return { errorMessages, error } + return { errorMessages, error }; }; const VisibleRegisterErrorList = connect( diff --git a/pages/tournament-fullscreen.js b/pages/tournament-fullscreen.js index 2f7aff1..09cde55 100644 --- a/pages/tournament-fullscreen.js +++ b/pages/tournament-fullscreen.js @@ -1,9 +1,10 @@ -import Head from 'next/head' +import Head from 'next/head'; +import React from 'react'; class FullscreenTournamentPage extends React.Component { static async getInitialProps({query}) { - return {query} + return {query}; } render() { @@ -19,4 +20,4 @@ class FullscreenTournamentPage extends React.Component { } } -export default FullscreenTournamentPage \ No newline at end of file +export default FullscreenTournamentPage; diff --git a/pages/tournament.js b/pages/tournament.js index a2010b7..bba1bf2 100644 --- a/pages/tournament.js +++ b/pages/tournament.js @@ -1,10 +1,11 @@ -import Head from 'next/head' -import "../style.css" +import Head from 'next/head'; +import React from 'react'; +import '../style.css'; class TournamentPage extends React.Component { static async getInitialProps({query}) { - return {query} + return {query}; } render() { @@ -20,4 +21,4 @@ class TournamentPage extends React.Component { } } -export default TournamentPage \ No newline at end of file +export default TournamentPage; diff --git a/server.js b/server.js index deb6403..daccc7d 100644 --- a/server.js +++ b/server.js @@ -1,36 +1,34 @@ -const express = require('express') -const next = require('next') +const express = require('express'); +const next = require('next'); -const dev = process.env.NODE_ENV !== 'production' -const app = next({ dev }) -const handle = app.getRequestHandler() +const dev = process.env.NODE_ENV !== 'production'; +const app = next({ dev }); +const handle = app.getRequestHandler(); app.prepare() -.then(() => { - const server = express() + .then(() => { + const server = express(); - server.get('/t/:code', (req, res) => { - const actualPage = '/tournament' - const queryParam = { code: req.params.code } - app.render(req, res, actualPage, queryParam) - }) + server.get('/t/:code', (req, res) => { + const actualPage = '/tournament'; + const queryParam = { code: req.params.code }; + app.render(req, res, actualPage, queryParam); + }); - server.get('/t/:code/fullscreen', (req, res) => { - const actualPage = '/tournament-fullscreen' - const queryParam = { code: req.params.code } - app.render(req, res, actualPage, queryParam) - }) + server.get('/t/:code/fullscreen', (req, res) => { + const actualPage = '/tournament-fullscreen'; + const queryParam = { code: req.params.code }; + app.render(req, res, actualPage, queryParam); + }); - server.get('*', (req, res) => { - return handle(req, res) - }) + server.get('*', (req, res) => { + return handle(req, res); + }); - server.listen(3000, (err) => { - if (err) throw err - console.log('> Ready on http://localhost:3000') - }) -}) -.catch((ex) => { - console.error(ex.stack) - process.exit(1) -}) + server.listen(3000, (err) => { + if (err) throw err; + }); + }) + .catch(() => { + process.exit(1); + }); From 504746934c07dc02031e84ea6c22d8015cb5abd1 Mon Sep 17 00:00:00 2001 From: JP1998 Date: Tue, 11 Dec 2018 08:38:56 +0100 Subject: [PATCH 12/15] Add proper name for eslint config file --- .hound.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.hound.yml b/.hound.yml index d86b9a7..fc4f352 100644 --- a/.hound.yml +++ b/.hound.yml @@ -5,4 +5,4 @@ jshint: eslint: enabled: true - config_file: .eslintrc + config_file: .eslintrc.json From 7205e0b65b32e1113d30c164184be0de20f1b21e Mon Sep 17 00:00:00 2001 From: JP1998 Date: Tue, 11 Dec 2018 08:42:35 +0100 Subject: [PATCH 13/15] Change eslint rule to only accept unix linebreaks --- .eslintrc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 60df449..1744b88 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -24,7 +24,7 @@ ], "linebreak-style": [ "error", - "windows" + "unix" ], "quotes": [ "error", From 5c55ff025b1e52600852d390e218dc1c061944bb Mon Sep 17 00:00:00 2001 From: Felix Hamme Date: Wed, 12 Dec 2018 18:43:53 +0100 Subject: [PATCH 14/15] Update data processing in public tournament list due to changed api --- pages/list.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pages/list.js b/pages/list.js index 6e9574a..9b92722 100644 --- a/pages/list.js +++ b/pages/list.js @@ -36,7 +36,7 @@ class TournamentList extends React.Component { console.log(response); this.setState({ isLoaded: true, - items: response.data.data + items: response.data }); }, error => { @@ -55,7 +55,8 @@ class TournamentList extends React.Component {

Öffentliche Turniere

{this.state.items.map(item => ( - + //The code should be item.code but the api just supports it this way by now + ))}
From 8612b88ff748252dacf163732078487e9e41c650 Mon Sep 17 00:00:00 2001 From: JP1998 Date: Wed, 12 Dec 2018 21:25:01 +0100 Subject: [PATCH 15/15] Resolve conflicts and style issues --- pages/list.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/pages/list.js b/pages/list.js index 1005258..8e03fa4 100644 --- a/pages/list.js +++ b/pages/list.js @@ -1,9 +1,9 @@ -import Head from 'next/head' -import '../static/everypage.css' -import {Footer, TurniereNavigation} from "../js/CommonComponents"; -import React from "react"; -import {Card, CardBody, Container} from "reactstrap"; -import {getRequest} from "../js/api"; +import Head from 'next/head'; +import '../static/everypage.css'; +import { Footer, TurniereNavigation } from '../js/CommonComponents'; +import React from 'react'; +import { Card, CardBody, Container } from 'reactstrap'; +import { getRequest, getState } from '../js/api'; export default () => (
@@ -16,7 +16,7 @@ export default () => (
-) +); class TournamentList extends React.Component { constructor(props) { @@ -29,11 +29,9 @@ class TournamentList extends React.Component { } componentDidMount() { - getRequest('/tournaments?type=public',{}) + getRequest(getState(), '/tournaments?type=public') .then( response => { - console.log('response:'); - console.log(response); this.setState({ isLoaded: true, items: response.data @@ -45,7 +43,7 @@ class TournamentList extends React.Component { error }); } - ) + ); } render() { @@ -67,7 +65,7 @@ class TournamentList extends React.Component { function TournamentListEntry(props) { return ( - + {props.name} );