From 29726daed475143e07d41b95f3f2c795f195be6b Mon Sep 17 00:00:00 2001 From: larsmhar Date: Wed, 31 Oct 2018 15:57:23 +0100 Subject: [PATCH] Fixed #17 started on error handling #23 --- backend/src/server.js | 1 + database.db | Bin 654336 -> 654336 bytes frontend/src/App.js | 31 ++++++++++++++--- frontend/src/actions/filmActions.js | 9 ++--- frontend/src/actions/types.js | 1 + frontend/src/actions/userActions.js | 19 +++++++++++ frontend/src/components/Errors.js | 20 +++++++++++ frontend/src/components/Items.js | 9 ++--- frontend/src/components/Login.css | 15 ++++++++ frontend/src/components/Login.js | 49 +++++++++++++++++++++++++++ frontend/src/reducers/index.js | 4 ++- frontend/src/reducers/userReducer.js | 28 +++++++++++++++ frontend/src/screens/Film.js | 31 ++++++++++------- frontend/src/screens/Filmspage.js | 15 ++++++++ frontend/src/screens/Frontpage.js | 4 +-- frontend/src/store/store.js | 9 ++++- 16 files changed, 216 insertions(+), 29 deletions(-) create mode 100644 frontend/src/actions/userActions.js create mode 100644 frontend/src/components/Errors.js create mode 100644 frontend/src/components/Login.css create mode 100644 frontend/src/components/Login.js create mode 100644 frontend/src/reducers/userReducer.js create mode 100644 frontend/src/screens/Filmspage.js diff --git a/backend/src/server.js b/backend/src/server.js index f4eaf3a..4bddf30 100644 --- a/backend/src/server.js +++ b/backend/src/server.js @@ -164,6 +164,7 @@ const getFilms = function( args ) { }; const getUser = function( args ) { + console.log( 'Getting user', args ); return new Promise( ( resolve, reject ) => { db.get( 'SELECT * FROM user WHERE username = $username', args.username ).then( function( result ) { if ( result ) { diff --git a/database.db b/database.db index befd76ed6e881916ba95242085426d09b5c91021..f5c474e16baf7ca256fe802dc3b8ff737a606d8f 100644 GIT binary patch delta 238 zcmXwyF-yZh07mcfE?%ytlt9737BeW_L~TVnm;3~OfM7dC5NY>-7$-p~qN9_ur9)SL zLY=#$=x|F*C(Yns6dc|+J-(OZjU;c}Zp!vut>d=E?shUdeWK>m60FFWa?dL-Trr@_ zF%hkCsHy~&iYvE_q2J%zZyp^UG>4Jiag4c)^>wUefm6UF*6MLuf=uwmf^2kt!!Y!s z@;ZomFFrZz_68RZi<#Q+VI}zHvnYRz11}?VkrIB_aln|85CZ0cC3EsW>y5HcUH(5Y XS-z`4Nm8p)>!x-swK}!lvo+Np;?P4T delta 225 zcmZqpq2BOAeS$Qj!9*EnRs#k-#;A=c3z((2nOzx}KQKRFzQ8<{`2h0<=2qrX=2YfT zX4lCIEFznYSeTdv8IZtX5PPyKyDAe0M{^E)dk#Az5HkTW^Y$EemKhhgn3&%(Fn?!$ z%lvy|K`--U1rBd^S%?AC-`-{s=V4<0#=!iC`5W^S<|ms4IUY013NSFRGBYwVF)=f9 za&iIHGBLknV1CE^1FGaYGrJ7LgzfJhvk0;}f diff --git a/frontend/src/App.js b/frontend/src/App.js index 3da3e6f..381a23e 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -1,14 +1,22 @@ import React, { Component } from 'react'; import logo from './logo.svg'; import './App.css'; +import { connect } from 'react-redux'; +import Filmspage from './screens/Filmspage'; import Frontpage from './screens/Frontpage'; import Film from './screens/Film'; -import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; +import { BrowserRouter as Router, Route, Link, Redirect } from 'react-router-dom'; class App extends Component { + + checkLogin( component, destination ) { + return this.props.user.user.data.user ? : component; + } render() { + //localStorage.setItem("thing", "datum") + console.log(localStorage.getItem("thing")) return (
@@ -16,12 +24,27 @@ class App extends Component {
Filmlr
{/* Had to set margin-top here, because setting in css didn't work?*/} - - + {/* + + !!this.props.user.user.data ? + () + : + + } /> + */} + {console.log( this.props.user.user.data.user )} + this.checkLogin( , 'films' ) } /> + +
); } } -export default App; +const mapStateToProps = state => ( { + 'user': state.user +} ); + +export default connect( mapStateToProps )( App ); + diff --git a/frontend/src/actions/filmActions.js b/frontend/src/actions/filmActions.js index e3cf3f3..56cd296 100644 --- a/frontend/src/actions/filmActions.js +++ b/frontend/src/actions/filmActions.js @@ -1,12 +1,13 @@ -import { FETCH_FILMS, FETCH_FILM, LOADING, LOADED, UPDATE_LIKED, UPDATE_WATCHED} from './types'; +import { FETCH_FILMS, FETCH_FILM, LOADING, LOADED, UPDATE_LIKED, UPDATE_WATCHED } from './types'; -export const fetchFilms = () => dispatch => { - //console.log( 'fetching all films' ); +export const fetchFilms = (uid) => dispatch => { + console.log( 'fetching all films' ); + console.log("uid", uid) dispatch( { 'type': LOADING} ); fetch( 'http://localhost:4000/graphql', { 'method': 'POST', 'headers': { 'Content-Type': 'application/json' }, - 'body': JSON.stringify( { 'query': '{ films { id title poster } userWatched(uid:1) {id watched} userLiked(uid:1) {id liked} }' } ), + 'body': JSON.stringify( { 'query': '{ films { id title poster } userWatched(uid: ' + uid + ') {id watched} userLiked(uid: ' + uid + ') {id liked} }' } ), } ) .then( res => { return res.json(); diff --git a/frontend/src/actions/types.js b/frontend/src/actions/types.js index 5f6dad4..7fc6ede 100644 --- a/frontend/src/actions/types.js +++ b/frontend/src/actions/types.js @@ -4,3 +4,4 @@ export const LOADING = 'LOADING'; export const LOADED = 'LOADED'; export const UPDATE_LIKED = 'UPDATE_LIKED'; export const UPDATE_WATCHED = 'UPDATE_WATCHED'; +export const GET_USER = 'GET_USER'; diff --git a/frontend/src/actions/userActions.js b/frontend/src/actions/userActions.js new file mode 100644 index 0000000..c0e70b0 --- /dev/null +++ b/frontend/src/actions/userActions.js @@ -0,0 +1,19 @@ +import { LOADING, GET_USER } from './types'; + +export const getUser = ( username ) => dispatch => { + //console.log( JSON.stringify( { 'query': '{ films (id: ' + '"' + id + '"' + ') { id title poster } }' } ) ); + //console.log("Typeof", typeof id) + //console.log("fetching single film with id", id) + console.log( 'Gotting users' ); + dispatch( { 'type': LOADING} ); + fetch( 'http://localhost:4000/graphql', { + 'method': 'POST', + 'headers': { 'Content-Type': 'application/json' }, + 'body': JSON.stringify( { 'query': '{ user (username: "' + username + '") { uid username } }' } ), + } ) + .then( res => res.json() ) + .then( user => dispatch( { + 'type': GET_USER, + 'payload': user + } ) ); +}; diff --git a/frontend/src/components/Errors.js b/frontend/src/components/Errors.js new file mode 100644 index 0000000..e5efa19 --- /dev/null +++ b/frontend/src/components/Errors.js @@ -0,0 +1,20 @@ +import React from 'react'; +import { Component } from 'react'; +import { connect } from 'react-redux'; + +class Errors extends Component { + render() { + return ( +
+ {this.props.user.user.errors.map( error => +
{error.message}
)} +
+ ); + } +} + +const mapStateToProps = state => ( { + 'user': state.user +} ); + +export default connect( mapStateToProps )( Errors ); diff --git a/frontend/src/components/Items.js b/frontend/src/components/Items.js index b70d43d..ae634af 100644 --- a/frontend/src/components/Items.js +++ b/frontend/src/components/Items.js @@ -8,7 +8,7 @@ import { BrowserRouter as Router, Route, Link } from 'react-router-dom'; class Items extends Component { componentWillMount() { - this.props.fetchFilms(); + this.props.fetchFilms( this.props.user.user.data.user.uid ); } generateClass( id ) { @@ -19,9 +19,9 @@ class Items extends Component { render() { const films = this.props.films.data.films.map( film => - +
-
{film.title}
+
{film.title}
poster
); @@ -39,7 +39,8 @@ Items.propTypes = { }; const mapStateToProps = state => ( { - 'films': state.films.items + 'films': state.films.items, + 'user': state.user, } ); export default connect( mapStateToProps, { fetchFilms } )( Items ); diff --git a/frontend/src/components/Login.css b/frontend/src/components/Login.css new file mode 100644 index 0000000..a17cdb7 --- /dev/null +++ b/frontend/src/components/Login.css @@ -0,0 +1,15 @@ +.userField { + background-color: #485563; + color: #f5f5f5; + border: 0.09em solid hsl(150, 8%, 55%); + margin-right: 0.5em; + width: 20vw; + padding: 0.5em; +} + +.loginBtn { + padding: 0.5em; + border: 0.09em solid #e4cc0c; + color: #f5f5f5; + background-color: #102027; +} \ No newline at end of file diff --git a/frontend/src/components/Login.js b/frontend/src/components/Login.js new file mode 100644 index 0000000..1918ae7 --- /dev/null +++ b/frontend/src/components/Login.js @@ -0,0 +1,49 @@ +import React from 'react'; +import { Component } from 'react'; +import { connect } from 'react-redux'; + +import { getUser } from '../actions/userActions'; +import Errors from './Errors'; + +import './Login.css'; + +class Login extends Component { + + constructor( props ) { + super( props ); + this.state = { + 'username': '', + }; + this.onHandleSubmit = this.onHandleSubmit.bind( this ); + this.onUsernameChange = this.onUsernameChange.bind( this ); + } + + onHandleSubmit( e ) { + e.preventDefault(); + this.props.getUser( this.state.username ); + } + + onUsernameChange( e ) { + this.setState( { 'username': e.target.value } ); + } + + render() { + let error; + if ( 'errors' in this.props.user.user ) { + error = (

PPP

); + } + return ( +
+ + + {error} +
+ ); + } +} + +const mapStateToProps = state => ( { + 'user': state.user +} ); + +export default connect( mapStateToProps, { getUser } )( Login ); diff --git a/frontend/src/reducers/index.js b/frontend/src/reducers/index.js index d05a0e0..4d41142 100644 --- a/frontend/src/reducers/index.js +++ b/frontend/src/reducers/index.js @@ -1,6 +1,8 @@ import { combineReducers } from 'redux'; import filmReducer from './filmReducer'; +import userReducer from './userReducer'; export default combineReducers( { - 'films': filmReducer + 'films': filmReducer, + 'user': userReducer, } ); diff --git a/frontend/src/reducers/userReducer.js b/frontend/src/reducers/userReducer.js new file mode 100644 index 0000000..ec621d8 --- /dev/null +++ b/frontend/src/reducers/userReducer.js @@ -0,0 +1,28 @@ +import { LOADING, LOADED, GET_USER } from '../actions/types'; + +const initialState = { + 'items': [], +}; + +export default function( state = initialState, action ) { + switch ( action.type ) { + case GET_USER: + return { + ...state, + 'user': action.payload, + 'loaded': true, + }; + case LOADING: + return { + ...state, + 'loaded': false, + }; + case LOADED: + return { + ...state, + 'loaded': true, + }; + default: + return state; + } +} diff --git a/frontend/src/screens/Film.js b/frontend/src/screens/Film.js index b3e41cb..8afe707 100644 --- a/frontend/src/screens/Film.js +++ b/frontend/src/screens/Film.js @@ -9,8 +9,8 @@ class Film extends Component { componentWillMount() { //console.log( this.props.match.params.id ); - this.props.fetchFilms(); - this.props.fetchFilm( this.props.match.params.id, 1 ); + this.props.fetchFilms( this.props.user.user.data.user.uid ); + this.props.fetchFilm( this.props.match.params.id, this.props.user.user.data.user.uid ); } constructor( props ) { @@ -23,11 +23,12 @@ class Film extends Component { } handleClick( e ) { + console.log( this.props.user.user.data ) if ( e.target.id === 'liked' ) { - this.props.updateLiked( this.props.match.params.id, 1 ); - this.setState( {'liked': !this.state.liked} ); + this.props.updateLiked( this.props.match.params.id, this.props.user.user.data.user.uid ); + //this.setState( {'liked': !this.state.liked} ); } else if ( e.target.id === 'watched' ) { - this.props.updateWatched( this.props.match.params.id, 1 ); + this.props.updateWatched( this.props.match.params.id, this.props.user.user.data.user.uid ); this.setState( {'watched':!this.state.watched} ); } @@ -42,12 +43,16 @@ class Film extends Component { //console.log( this.props.film.data.films ); console.log( this.props.film ); let film; - if ( this.props.loaded) { - console.log(this.props) + if ( this.props.loaded ) { + console.log( this.props ); - console.log( this.state.liked, !!this.props.film[0]['liked'] ) - if ( this.state.liked != !!this.props.film[0]['liked'] ) this.setState( { 'liked': !!this.props.film[0]['liked'] } ) - if ( this.state.watched != !!this.props.film[0]['watched'] ) this.setState( { 'watched': !!this.props.film[0]['watched'] } ) + console.log( this.state.liked, !!this.props.film[0]['liked'] ); + if ( this.state.liked != !!this.props.film[0]['liked'] ) { + this.setState( { 'liked': !!this.props.film[0]['liked'] } ); + } + if ( this.state.watched != !!this.props.film[0]['watched'] ) { + this.setState( { 'watched': !!this.props.film[0]['watched'] } ); + } /* this.props.userLiked.forEach( x => { if ( x['id'] == this.props.film[0]['id'] & this.state.favorite != true ) this.setState( { 'favorite': true }, console.log( 'Liked' ) ); @@ -71,9 +76,8 @@ class Film extends Component { visibility ); - } - else { - film =
loading
; + } else { + film =
; } return ( [film] @@ -94,6 +98,7 @@ const mapStateToProps = state => ( { 'userLiked': state.films.items.data.userLiked, 'userWatched': state.films.items.data.userWatched, 'loaded': state.films.loaded, + 'user': state.user, } ); export default connect( mapStateToProps, { fetchFilm, fetchFilms, updateLiked, updateWatched } )( Film ); diff --git a/frontend/src/screens/Filmspage.js b/frontend/src/screens/Filmspage.js new file mode 100644 index 0000000..e0be24d --- /dev/null +++ b/frontend/src/screens/Filmspage.js @@ -0,0 +1,15 @@ +import React, { Component } from 'react'; + +import Items from '../components/Items'; + +class Filmspage extends Component { + render() { + return ( +
+ +
+ ); + } +} + +export default Filmspage; diff --git a/frontend/src/screens/Frontpage.js b/frontend/src/screens/Frontpage.js index 8217316..0b0d4fc 100644 --- a/frontend/src/screens/Frontpage.js +++ b/frontend/src/screens/Frontpage.js @@ -1,12 +1,12 @@ import React, { Component } from 'react'; -import Items from '../components/Items'; +import Login from '../components/Login'; class Frontpage extends Component { render() { return (
- +
); } diff --git a/frontend/src/store/store.js b/frontend/src/store/store.js index cfc06ae..eb56b92 100644 --- a/frontend/src/store/store.js +++ b/frontend/src/store/store.js @@ -32,6 +32,13 @@ const initialState = { } }, 'loaded': false + }, + 'user': { + 'user': { + 'data': { + 'user': null + }, + } } }; @@ -41,7 +48,7 @@ const store = createStore( rootReducer, initialState, compose( - applyMiddleware(...middleware), + applyMiddleware( ...middleware ), window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() ) );