diff --git a/js/api.js b/js/api.js index f5991ff..9808ca7 100644 --- a/js/api.js +++ b/js/api.js @@ -32,7 +32,7 @@ const actiontypes_userinfo = { 'STORE_AUTH_HEADERS' : 'STORE_AUTH_HEADERS', 'REHYDRATE' : 'USERINFO_REHYDRATE', - 'CLEAR' : 'USERINFO_CLEAR', + 'CLEAR' : 'USERINFO_CLEAR' }; const defaultstate_userinfo = { @@ -72,6 +72,16 @@ const defaultstate_tournamentinfo = { teams : [] }; +const actiontypes_tournamentlist = { + 'FETCH': 'FETCH', + 'FETCH_SUCCESS': 'FETCH_SUCCESS', + 'REHYDRATE': 'REHYDRATE' +}; + +const defaultstate_tournamentlist = { + tournaments: [] +}; + export function postRequest(state, url, data) { return axios.post(api_url + url, data, { headers : generateHeaders(state) @@ -332,14 +342,40 @@ const reducer_tournamentinfo = (state = defaultstate_tournamentinfo, action) => } }; +const reducer_tournamentlist = (state = defaultstate_tournamentlist, action) => { + switch (action.type) { + case actiontypes_tournamentlist.FETCH: + getRequest(action.state, '/tournaments?type=' + action.parameters.type).then((resp) => { + __store.dispatch({ + type: actiontypes_tournamentlist.FETCH_SUCCESS, + parameters: resp.data + }); + storeOptionalToken(resp); + action.parameters.successCallback(resp.data); + }).catch((error) => { + if(error.response) { + storeOptionalToken(error.response); + } + action.parameters.errorCallback(); + }); + return state; + case actiontypes_tournamentlist.FETCH_SUCCESS: + return Object.assign({}, state, {tournaments: action.parameters}); + default: + return state; + } +}; + const reducers = { userinfo: reducer_userinfo, - tournamentinfo: reducer_tournamentinfo + tournamentinfo: reducer_tournamentinfo, + tournamentlist: reducer_tournamentlist }; const default_applicationstate = { userinfo : defaultstate_userinfo, - tournamentinfo: defaultstate_tournamentinfo + tournamentinfo: defaultstate_tournamentinfo, + tournamentlist: defaultstate_tournamentlist }; var __store; @@ -451,6 +487,18 @@ export function getState() { return __store.getState(); } +export function requestTournamentList(type, successCallback, errorCallback) { + __store.dispatch({ + type: actiontypes_tournamentlist.FETCH, + parameters: { + type: type, + successCallback: successCallback, + errorCallback: errorCallback + }, + state: __store.getState() + }); +} + function rehydrateApplicationState() { const persistedState = localStorage.getItem('reduxState') ? JSON.parse(localStorage.getItem('reduxState')) : @@ -465,6 +513,10 @@ function rehydrateApplicationState() { type : actiontypes_tournamentinfo.REHYDRATE, parameters : Object.assign({}, persistedState.tournamentinfo) }); + __store.dispatch({ + type : actiontypes_tournamentlist.REHYDRATE, + parameters : Object.assign({}, persistedState.tournamentlist) + }); applicationHydrated = true; } } diff --git a/js/components/Navigation.js b/js/components/Navigation.js index 8c86753..c14e8ac 100644 --- a/js/components/Navigation.js +++ b/js/components/Navigation.js @@ -41,11 +41,7 @@ export class TurniereNavigation extends React.Component { - + @@ -61,6 +57,18 @@ function Navlink(props) { ); } +class SmartNavLinks extends React.Component { + + render() { + return (); + } +} + function Betabadge() { return (BETA); } @@ -92,12 +100,15 @@ class InvisibleLoginLogoutButtons extends React.Component { } } -const mapStateToLoginLogoutButtonProperties = (state) => { +const mapStateToUserinfo = (state) => { const { isSignedIn, username } = state.userinfo; return { isSignedIn, username }; }; const LoginLogoutButtons = connect( - mapStateToLoginLogoutButtonProperties + mapStateToUserinfo )(InvisibleLoginLogoutButtons); +const NavLinks = connect( + mapStateToUserinfo +)(SmartNavLinks); \ No newline at end of file diff --git a/js/components/TournamentList.js b/js/components/TournamentList.js new file mode 100644 index 0000000..9a0ac00 --- /dev/null +++ b/js/components/TournamentList.js @@ -0,0 +1,39 @@ +import React from 'react'; +import {requestTournamentList} from '../api'; + +export default class TournamentList extends React.Component { + constructor(props) { + super(props); + this.state = { + tournaments: [] + }; + } + + componentDidMount() { + requestTournamentList(this.props.type, tournaments => { + this.setState({ + tournaments: tournaments + }); + }, () => {}); + } + + render() { + if (this.state.tournaments.length === 0) { + return

keine + Turniere vorhanden

; + } else { + return this.state.tournaments.map(item => ( + //The code should be item.code but the api just supports it this way by now + + )); + } + } +} + +function TournamentListEntry(props) { + return ( + + {props.name} + + ); +} \ No newline at end of file diff --git a/pages/list.js b/pages/list.js index 768b105..1cf8496 100644 --- a/pages/list.js +++ b/pages/list.js @@ -1,22 +1,16 @@ -import Head from 'next/head'; -import React from 'react'; -import { - Card, - CardBody, - Container -} from 'reactstrap'; +import Head from 'next/head'; +import React from 'react'; +import {Card, CardBody, Container} from 'reactstrap'; -import { TurniereNavigation } from '../js/components/Navigation'; -import { Footer } from '../js/components/Footer'; -import { - getRequest, - getState -} from '../js/api'; +import {TurniereNavigation} from '../js/components/Navigation'; +import {Footer} from '../js/components/Footer'; import '../static/everypage.css'; +import TournamentList from '../js/components/TournamentList'; +import {connect} from 'react-redux'; + +export default class PublicTournamentsPage extends React.Component { -export default class ListPage extends React.Component { - render() { return (
@@ -25,7 +19,7 @@ export default class ListPage extends React.Component {
- +
@@ -33,55 +27,38 @@ export default class ListPage extends React.Component { } } -class TournamentList extends React.Component { - constructor(props) { - super(props); - this.state = { - error: null, - isLoaded: false, - items: [] - }; - } +function mapStateToProperties(state) { + const {isSignedIn} = state.userinfo; + return {isSignedIn}; +} - componentDidMount() { - getRequest(getState(), '/tournaments?type=public') - .then( - response => { - this.setState({ - isLoaded: true, - items: response.data - }); - }, - error => { - this.setState({ - isLoaded: true, - error - }); - } - ); - } +const PublicTournamentPageContent = connect( + mapStateToProperties, +)(PublicTournaments); - render() { - return ( - - - -

Öffentliche Turniere

- {this.state.items.map(item => ( - //The code should be item.code but the api just supports it this way by now - - ))} -
-
+function PublicTournaments(props) { + if (props.isSignedIn) { + return (
+ + - ); + + zu den privaten Turnieren + +
); + + } else { + return ( + + ); } } -function TournamentListEntry(props) { - return ( - - {props.name} - - ); +function PublicTournamentsCard() { + return ( + +

Öffentliche Turniere

+ +
+
); } diff --git a/pages/private.js b/pages/private.js new file mode 100644 index 0000000..63eaae0 --- /dev/null +++ b/pages/private.js @@ -0,0 +1,83 @@ +import Head from 'next/head'; +import React from 'react'; +import {connect} from 'react-redux'; + +import {Card, CardBody, Container,} from 'reactstrap'; + +import {TurniereNavigation} from '../js/components/Navigation'; +import {Footer} from '../js/components/Footer'; +import {Option, UserRestrictor} from '../js/components/UserRestrictor'; +import {Login} from '../js/components/Login'; + +import '../static/everypage.css'; +import TournamentList from '../js/components/TournamentList'; + +class PrivateTournamentsPage extends React.Component { + + render() { + const {isSignedIn} = this.props; + + return ( + + + + + ); + } +} + +function mapStateToProperties(state) { + const {isSignedIn} = state.userinfo; + return {isSignedIn}; +} + +const PrivateTournamentListPage = connect( + mapStateToProperties, +)(PrivateTournamentsPage); + +export default PrivateTournamentListPage; + +function PrivateTournamentsPageContent() { + return (
+ + + + + zu den öffentlichen Turnieren + +
); +} + +class PrivateTournamentsCard extends React.Component { + render() { + return ( + + +

Private Turniere

+ +
+
+ ); + } +} \ No newline at end of file