From 4c1459d890b1802f95721eaf5f690cd467110ac8 Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Thu, 3 Oct 2019 09:47:07 -0400 Subject: [PATCH 1/8] Renamed edit.js to editProfile.js because it makes more sense --- twistter-frontend/src/App.js | 2 +- twistter-frontend/src/pages/{edit.js => editProfile.js} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename twistter-frontend/src/pages/{edit.js => editProfile.js} (100%) diff --git a/twistter-frontend/src/App.js b/twistter-frontend/src/App.js index f7c6c32..d541be6 100644 --- a/twistter-frontend/src/App.js +++ b/twistter-frontend/src/App.js @@ -16,7 +16,7 @@ import login from './pages/Login'; import user from './pages/user'; import writeMicroblog from './Writing_Microblogs.js'; -import edit from './pages/edit.js'; +import edit from './pages/editProfile'; import userLine from './Userline.js'; const theme = createMuiTheme(themeObject); diff --git a/twistter-frontend/src/pages/edit.js b/twistter-frontend/src/pages/editProfile.js similarity index 100% rename from twistter-frontend/src/pages/edit.js rename to twistter-frontend/src/pages/editProfile.js From 8179b51844bcbdcba6ec7d8fe203fa65dec1fb1e Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Mon, 7 Oct 2019 20:24:23 -0400 Subject: [PATCH 2/8] Before finishing authentication --- twistter-frontend/src/App.js | 48 ++++++++----- twistter-frontend/src/Writing_Microblogs.js | 34 +++++---- twistter-frontend/src/pages/Register.js | 71 ++++++++++++++----- .../src/redux/actions/userActions.js | 38 ++++++++-- twistter-frontend/src/util/AuthRoute.js | 21 +++--- 5 files changed, 147 insertions(+), 65 deletions(-) diff --git a/twistter-frontend/src/App.js b/twistter-frontend/src/App.js index 8e18621..8656ef0 100644 --- a/twistter-frontend/src/App.js +++ b/twistter-frontend/src/App.js @@ -2,8 +2,7 @@ import React, { Component } from "react"; import "./App.css"; -import { BrowserRouter as Router } from "react-router-dom"; -import Route from "react-router-dom/Route"; +import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; import Navbar from "./components/layout/NavBar"; import jwtDecode from "jwt-decode"; @@ -27,6 +26,7 @@ import userLine from "./Userline.js"; import AuthRoute from "./util/AuthRoute"; let authenticated; + const token = localStorage.FBIdToken; if (token) { const decodedToken = jwtDecode(token); @@ -43,25 +43,37 @@ const theme = createMuiTheme(themeObject); class App extends Component { render() { return ( - - -
- -
-
- - - - - - - -
+ + +
+ +
-
+
+ + {/* */} + + + + + + + + + + {/* + + + + + */} + +
+ +
+
- ); } } diff --git a/twistter-frontend/src/Writing_Microblogs.js b/twistter-frontend/src/Writing_Microblogs.js index 3bda6cc..b1570d8 100644 --- a/twistter-frontend/src/Writing_Microblogs.js +++ b/twistter-frontend/src/Writing_Microblogs.js @@ -34,21 +34,27 @@ class Writing_Microblogs extends Component { handleSubmit(event) { // alert('A title for the microblog was inputted: ' + this.state.title + '\nA microblog was posted: ' + this.state.value); + const postData = { + body: this.state.value, + userHandle: "new user", + userImage: "bing-url", + microBlogTitle: this.state.title, + microBlogTopics: this.state.topics.split(', ') + } + const headers = { + headers: { 'Content-Type': 'application/json'} + } - const response = axios.post( - 'http://localhost:5001/twistter-e4649/us-central1/api/putPost', - { body: this.state.value, - userHandle: "new user", - userImage: "bing-url", - microBlogTitle: this.state.title, - microBlogTopics: this.state.topics.split(', ') - - }, - { headers: { 'Content-Type': 'application/json'} } - - ) - console.log(response.data); - alert('Post was shared successfully!'); + axios + .post('/putPost', postData, headers) + .then((res) =>{ + alert('Post was shared successfully!') + console.log(res.data); + }) + .catch((err) => { + alert('An error occured.'); + console.error(err); + }) event.preventDefault(); this.setState({value: '', title: '',characterCount: 250, topics: ''}) } diff --git a/twistter-frontend/src/pages/Register.js b/twistter-frontend/src/pages/Register.js index d168315..3ae9047 100644 --- a/twistter-frontend/src/pages/Register.js +++ b/twistter-frontend/src/pages/Register.js @@ -6,6 +6,30 @@ import axios from 'axios'; import TextField from '@material-ui/core/TextField'; import PropTypes from 'prop-types'; +// Redux Stuff +import {connect} from 'react-redux'; +import {signupUser, logoutUser} from '../redux/actions/userActions'; +import withStyles from '@material-ui/core/styles/withStyles'; + +const styles = { + form: { + textAlign: "center" + }, + textField: { + marginBottom: 30 + }, + pageTitle: { + // marginTop: 20, + marginBottom: 40 + }, + button: { + positon: "relative", + marginBottom: 30 + }, + progress: { + position: "absolute" + } +}; class Register extends Component { @@ -21,30 +45,28 @@ class Register extends Component { this.handleSubmit = this.handleSubmit.bind(this); this.handleChange = this.handleChange.bind(this); -}; + }; + componentWillReceiveProps(nextProps) { + if (nextProps.UI.errors) { + this.setState({ errors: nextProps.UI.errors }); + } + } + + handleSubmit = (event) => { + event.preventDefault(); + this.setState({ + loading: true + }); -handleSubmit = (event) => { const newUserData = { email: this.state.email, handle: this.state.handle, password: this.state.password, confirmPassword: this.state.confirmPassword }; - axios.post('http://localhost:5001/twistter-e4649/us-central1/api/signup', newUserData) - .then(res => { - console.log(res.data); - localStorage.setItem('firebaseIdToken', `Bearer ${res.data.token}`); - this.props.history.push('/'); - }) - .catch(err => { - this.setState({ - errors: err.response.data - }); - }); - alert("You successfully registered"); - event.preventDefault(); - this.setState({email: '', handle: '', password: '', confirmPassword: ''}); + + this.props.signupUser(newUserData, this.props.history); }; @@ -55,7 +77,7 @@ handleChange = (event) => { }; render() { - const { classes } = this.props; + const { classes, UI: { loading } } = this.props; const { errors } = this.state; return (
@@ -83,6 +105,9 @@ handleChange = (event) => { {errors.general}
) } + {/* { + loading && Loading... + } */} @@ -91,7 +116,15 @@ handleChange = (event) => { } Register.propTypes = { - classes: PropTypes.object.isRequired + classes: PropTypes.object.isRequired, + user: PropTypes.object.isRequired, + UI: PropTypes.object.isRequired, + signupUser: PropTypes.func.isRequired }; -export default Register; \ No newline at end of file +const mapStateToProps = (state) => ({ + user: state.user, + UI: state.UI +}); + +export default connect(mapStateToProps, {signupUser})(withStyles(styles)(Register)); \ No newline at end of file diff --git a/twistter-frontend/src/redux/actions/userActions.js b/twistter-frontend/src/redux/actions/userActions.js index cc6eb56..ddb159e 100644 --- a/twistter-frontend/src/redux/actions/userActions.js +++ b/twistter-frontend/src/redux/actions/userActions.js @@ -1,4 +1,4 @@ -import {SET_USER, SET_ERRORS, CLEAR_ERRORS, LOADING_UI} from '../types'; +import {SET_USER, SET_ERRORS, CLEAR_ERRORS, LOADING_UI, SET_AUTHENTICATED, SET_UNAUTHENTICATED} from '../types'; import axios from 'axios'; @@ -19,9 +19,7 @@ export const loginUser = (loginData, history) => (dispatch) => { .post("/login", loginData) .then((res) => { // Save the login token - const FBIdToken = `Bearer ${res.data.token}`; - localStorage.setItem('FBIdToken', FBIdToken); - axios.defaults.headers.common['Authorization'] = FBIdToken; + setAuthorizationHeader(res.data.token); dispatch(getUserData()); dispatch({ type: CLEAR_ERRORS }) // Redirects to home page @@ -33,4 +31,36 @@ export const loginUser = (loginData, history) => (dispatch) => { payload: err.response.data, }) }); +}; + +export const signupUser = (newUserData, history) => (dispatch) => { + dispatch({ type: LOADING_UI }); + axios + .post("/signup", newUserData) + .then((res) => { + // Save the signup token + setAuthorizationHeader(res.data.token); + dispatch(getUserData()); + dispatch({ type: CLEAR_ERRORS }) + // Redirects to home page + history.push('/home'); + }) + .catch((err) => { + dispatch ({ + type: SET_ERRORS, + payload: err.response.data, + }) + }); +}; + +export const logoutUser = () => (dispatch) => { + localStorage.removeItem('FBIdToken'); + delete axios.defaults.headers.common['Authorization']; + dispatch({ type: SET_UNAUTHENTICATED }); +} + +const setAuthorizationHeader = (token) => { + const FBIdToken = `Bearer ${token}`; + localStorage.setItem('FBIdToken', FBIdToken); + axios.defaults.headers.common['Authorization'] = FBIdToken; } \ No newline at end of file diff --git a/twistter-frontend/src/util/AuthRoute.js b/twistter-frontend/src/util/AuthRoute.js index 309ccf0..f2d9bc2 100644 --- a/twistter-frontend/src/util/AuthRoute.js +++ b/twistter-frontend/src/util/AuthRoute.js @@ -1,22 +1,23 @@ -import React from 'react' -import { Route, Redirect} from 'react-router-dom'; +import React from 'react'; +import { Route, Redirect } from 'react-router-dom'; import { connect } from 'react-redux'; import PropTypes from 'prop-types'; const AuthRoute = ({ component: Component, authenticated, ...rest }) => ( - - authenticated === true ? : } - /> + render={(props) => + authenticated === true ? : + } + /> ); const mapStateToProps = (state) => ({ - authenticated: state.user.authenticated + authenticated: state.user.authenticated }); AuthRoute.propTypes = { - user: PropTypes.object -} + user: PropTypes.object +}; -export default connect(mapStateToProps)(AuthRoute); +export default connect(mapStateToProps)(AuthRoute); \ No newline at end of file From 9eb4f603dfe630476ebdeea8375e7b88ec2583a3 Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Mon, 7 Oct 2019 20:46:28 -0400 Subject: [PATCH 3/8] Logout is working ^_^ --- twistter-frontend/src/App.js | 38 ++++++++++++------------- twistter-frontend/src/pages/Login.js | 5 +++- twistter-frontend/src/util/AuthRoute.js | 2 +- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/twistter-frontend/src/App.js b/twistter-frontend/src/App.js index 8656ef0..b917566 100644 --- a/twistter-frontend/src/App.js +++ b/twistter-frontend/src/App.js @@ -12,6 +12,11 @@ import store from "./redux/store"; import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider'; import createMuiTheme from '@material-ui/core/styles/createMuiTheme'; import themeObject from './util/theme'; +import { SET_AUTHENTICATED } from './redux/types'; +import { logoutUser, getUserData } from './redux/actions/userActions'; + +// Components +import AuthRoute from "./util/AuthRoute"; // Pages import home from './pages/Home'; @@ -21,24 +26,23 @@ import user from './pages/user'; import writeMicroblog from "./Writing_Microblogs.js"; import edit from "./pages/edit.js"; import userLine from "./Userline.js"; +import axios from "axios"; -// Components -import AuthRoute from "./util/AuthRoute"; - -let authenticated; +const theme = createMuiTheme(themeObject); const token = localStorage.FBIdToken; if (token) { const decodedToken = jwtDecode(token); if (decodedToken.exp * 1000 < Date.now()) { + store.dispatch(logoutUser); window.location.href = "/login"; - authenticated = false; } else { - authenticated = true; + store.dispatch({ type: SET_AUTHENTICATED }); + axios.defaults.headers.common['Authorization'] = token; + store.dispatch(getUserData()); } } -const theme = createMuiTheme(themeObject); class App extends Component { render() { @@ -52,22 +56,16 @@ class App extends Component {
- {/* */} - - + {/* AuthRoute checks if the user is logged in and if they are it redirects them to /home */} + + - - - - + + + + - {/* - - - - - */}
diff --git a/twistter-frontend/src/pages/Login.js b/twistter-frontend/src/pages/Login.js index 9492372..5453b11 100644 --- a/twistter-frontend/src/pages/Login.js +++ b/twistter-frontend/src/pages/Login.js @@ -1,7 +1,6 @@ /* eslint-disable */ import React, { Component } from 'react'; import '../App.css'; -import axios from 'axios'; import PropTypes from 'prop-types'; import logo from '../images/twistter-logo.png'; @@ -157,6 +156,8 @@ export class Login extends Component { } } +// Proptypes just confirms that all data in it exists and is of the type that it +// is declared to be Login.propTypes = { classes: PropTypes.object.isRequired, loginUser: PropTypes.func.isRequired, @@ -176,5 +177,7 @@ Login.propTypes = { classes: PropTypes.object.isRequired }; +// This mapStateToProps is just synchronizing the 'state' to 'this.props' so we can access it +// The state contains info about the current logged in user export default connect(mapStateToProps, mapActionsToProps)(withStyles(styles)(Login)); diff --git a/twistter-frontend/src/util/AuthRoute.js b/twistter-frontend/src/util/AuthRoute.js index f2d9bc2..db4eb36 100644 --- a/twistter-frontend/src/util/AuthRoute.js +++ b/twistter-frontend/src/util/AuthRoute.js @@ -7,7 +7,7 @@ const AuthRoute = ({ component: Component, authenticated, ...rest }) => ( - authenticated === true ? : + authenticated === true ? : } /> ); From bb6c7a07fc876be14cb8af8d5a806a754c8f924a Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Mon, 7 Oct 2019 21:00:52 -0400 Subject: [PATCH 4/8] Register.js renamed to Signup.js --- twistter-frontend/src/App.css | 2 +- twistter-frontend/src/App.js | 6 +- twistter-frontend/src/Logout.js | 2 +- .../src/components/layout/NavBar.js | 4 +- twistter-frontend/src/pages/Home.js | 4 +- twistter-frontend/src/pages/Register.js | 130 -------------- twistter-frontend/src/pages/Signup.js | 166 ++++++++++++++++++ 7 files changed, 175 insertions(+), 139 deletions(-) delete mode 100644 twistter-frontend/src/pages/Register.js create mode 100644 twistter-frontend/src/pages/Signup.js diff --git a/twistter-frontend/src/App.css b/twistter-frontend/src/App.css index 8189649..0bfca90 100644 --- a/twistter-frontend/src/App.css +++ b/twistter-frontend/src/App.css @@ -22,7 +22,7 @@ white-space: nowrap; } -.register { +.signup { background-color: #1da1f2; border: 1px solid #fff; color: #fff; diff --git a/twistter-frontend/src/App.js b/twistter-frontend/src/App.js index b917566..8145864 100644 --- a/twistter-frontend/src/App.js +++ b/twistter-frontend/src/App.js @@ -20,7 +20,7 @@ import AuthRoute from "./util/AuthRoute"; // Pages import home from './pages/Home'; -import register from './pages/Register'; +import signup from './pages/Signup'; import login from './pages/Login'; import user from './pages/user'; import writeMicroblog from "./Writing_Microblogs.js"; @@ -57,7 +57,7 @@ class App extends Component {
{/* AuthRoute checks if the user is logged in and if they are it redirects them to /home */} - + @@ -65,7 +65,7 @@ class App extends Component { - +
diff --git a/twistter-frontend/src/Logout.js b/twistter-frontend/src/Logout.js index df36575..5944f2d 100644 --- a/twistter-frontend/src/Logout.js +++ b/twistter-frontend/src/Logout.js @@ -13,7 +13,7 @@ class Logout extends Component { Logout of your Twistter Account



- + ); }; diff --git a/twistter-frontend/src/components/layout/NavBar.js b/twistter-frontend/src/components/layout/NavBar.js index 0b6ba22..f79fe79 100644 --- a/twistter-frontend/src/components/layout/NavBar.js +++ b/twistter-frontend/src/components/layout/NavBar.js @@ -16,8 +16,8 @@ export class Navbar extends Component { - + +
diff --git a/twistter-frontend/src/pages/Register.js b/twistter-frontend/src/pages/Register.js deleted file mode 100644 index 3ae9047..0000000 --- a/twistter-frontend/src/pages/Register.js +++ /dev/null @@ -1,130 +0,0 @@ -import React, { Component } from 'react'; -import '../App.css'; - -import logo from '../images/twistter-logo.png'; -import axios from 'axios'; -import TextField from '@material-ui/core/TextField'; -import PropTypes from 'prop-types'; - -// Redux Stuff -import {connect} from 'react-redux'; -import {signupUser, logoutUser} from '../redux/actions/userActions'; -import withStyles from '@material-ui/core/styles/withStyles'; - -const styles = { - form: { - textAlign: "center" - }, - textField: { - marginBottom: 30 - }, - pageTitle: { - // marginTop: 20, - marginBottom: 40 - }, - button: { - positon: "relative", - marginBottom: 30 - }, - progress: { - position: "absolute" - } -}; - -class Register extends Component { - - constructor() { - super(); - this.state = { - email: '', - handle: '', - password: '', - confirmPassword: '', - errors: {} - }; - - this.handleSubmit = this.handleSubmit.bind(this); - this.handleChange = this.handleChange.bind(this); - }; - - componentWillReceiveProps(nextProps) { - if (nextProps.UI.errors) { - this.setState({ errors: nextProps.UI.errors }); - } - } - - handleSubmit = (event) => { - event.preventDefault(); - this.setState({ - loading: true - }); - - const newUserData = { - email: this.state.email, - handle: this.state.handle, - password: this.state.password, - confirmPassword: this.state.confirmPassword - }; - - this.props.signupUser(newUserData, this.props.history); -}; - - -handleChange = (event) => { - this.setState({ - [event.target.name]: event.target.value - }); -}; - - render() { - const { classes, UI: { loading } } = this.props; - const { errors } = this.state; - return ( -
- logo -

- Create your account -

- - - -

- -

- -

- -

- { - errors.general && - (
- {errors.general} -
) - } - {/* { - loading && Loading... - } */} - - -
- ); - } - -} -Register.propTypes = { - classes: PropTypes.object.isRequired, - user: PropTypes.object.isRequired, - UI: PropTypes.object.isRequired, - signupUser: PropTypes.func.isRequired -}; - -const mapStateToProps = (state) => ({ - user: state.user, - UI: state.UI -}); - -export default connect(mapStateToProps, {signupUser})(withStyles(styles)(Register)); \ No newline at end of file diff --git a/twistter-frontend/src/pages/Signup.js b/twistter-frontend/src/pages/Signup.js new file mode 100644 index 0000000..d97ff17 --- /dev/null +++ b/twistter-frontend/src/pages/Signup.js @@ -0,0 +1,166 @@ +/* eslint-disable */ +import React, { Component } from 'react'; +import '../App.css'; +import PropTypes from 'prop-types'; + +import logo from '../images/twistter-logo.png'; + +// Material-UI stuff +import Button from "@material-ui/core/Button"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import Grid from "@material-ui/core/Grid"; +import TextField from "@material-ui/core/TextField"; +import Typography from "@material-ui/core/Typography"; +import withStyles from "@material-ui/core/styles/withStyles"; + +// Redux stuff +import { connect } from 'react-redux'; +import { signupUser } from '../redux/actions/userActions'; + +const styles = { + form: { + textAlign: "center" + }, + textField: { + marginBottom: 30 + }, + pageTitle: { + marginBottom: 40 + }, + button: { + positon: "relative", + marginBottom: 30 + }, + progress: { + position: "absolute" + } +}; + +export class Signup extends Component { + + // Constructor for the state + constructor() { + super(); + this.state = { + email: "", + password:"", + errors: {} + }; + } + + componentWillReceiveProps(nextProps) { + if (nextProps.UI.errors) { + this.setState({ errors: nextProps.UI.errors }); + } + } + + // Runs whenever the submit button is clicked. + // Updates the database entry of the signed in user with the + // data stored in the state. + handleSubmit = (event) => { + event.preventDefault(); + const signupData = { + email: this.state.email, + password: this.state.password, + }; + this.props.signupUser(signupData, this.props.history); + }; + + // Updates the state whenever one of the textboxes changes. + // The key is the name of the textbox and the value is the + // value in the text box. + handleChange = (event) => { + this.setState({ + [event.target.name]: event.target.value, + errors: { + [event.target.name]: null + } + }); + }; + + render() { + const { classes, UI: { loading } } = this.props; + const { errors } = this.state; + + return ( + + + + logo + + Log in to Twistter + +
+ + + + {errors.general && ( + Wrong Email or Password + )} + +
+ + + ); + } +} + +// Proptypes just confirms that all data in it exists and is of the type that it +// is declared to be +Signup.propTypes = { + classes: PropTypes.object.isRequired, + signupUser: PropTypes.func.isRequired, + user: PropTypes.object.isRequired, + UI: PropTypes.object.isRequired +}; + +const mapStateToProps = (state) => ({ + user: state.user, + UI: state.UI, +}); + +const mapActionsToProps = { + signupUser +} +Signup.propTypes = { + classes: PropTypes.object.isRequired +}; + +// This mapStateToProps is just synchronizing the 'state' to 'this.props' so we can access it +// The state contains info about the current logged in user + +export default connect(mapStateToProps, mapActionsToProps)(withStyles(styles)(Signup)); \ No newline at end of file From d1233e77ed809c43ac0c50acf063207910752ebd Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Wed, 9 Oct 2019 12:03:57 -0400 Subject: [PATCH 5/8] Logout is working now : ) --- twistter-frontend/src/App.js | 4 +- twistter-frontend/src/Logout.js | 22 -------- .../src/components/layout/NavBar.js | 49 +++++++++++++++- twistter-frontend/src/pages/Login.js | 3 +- twistter-frontend/src/pages/Logout.js | 56 +++++++++++++++++++ twistter-frontend/src/pages/Signup.js | 9 ++- 6 files changed, 115 insertions(+), 28 deletions(-) delete mode 100644 twistter-frontend/src/Logout.js create mode 100644 twistter-frontend/src/pages/Logout.js diff --git a/twistter-frontend/src/App.js b/twistter-frontend/src/App.js index 8145864..4a1a6d4 100644 --- a/twistter-frontend/src/App.js +++ b/twistter-frontend/src/App.js @@ -1,6 +1,7 @@ /* eslint-disable */ import React, { Component } from "react"; import "./App.css"; +import axios from "axios"; import { BrowserRouter as Router, Route, Switch } from "react-router-dom"; import Navbar from "./components/layout/NavBar"; @@ -26,7 +27,7 @@ import user from './pages/user'; import writeMicroblog from "./Writing_Microblogs.js"; import edit from "./pages/edit.js"; import userLine from "./Userline.js"; -import axios from "axios"; +import logout from './pages/Logout'; const theme = createMuiTheme(themeObject); @@ -59,6 +60,7 @@ class App extends Component { {/* AuthRoute checks if the user is logged in and if they are it redirects them to /home */} + diff --git a/twistter-frontend/src/Logout.js b/twistter-frontend/src/Logout.js deleted file mode 100644 index 5944f2d..0000000 --- a/twistter-frontend/src/Logout.js +++ /dev/null @@ -1,22 +0,0 @@ -/* eslint-disable */ -import React, { Component} from 'react'; -import './App.css'; -import logo from './images/twistter-logo.png'; -import TextField from '@material-ui/core/TextField'; - -class Logout extends Component { - render() { - return( -
- logo -

- Logout of your Twistter Account -

-

- -
- ); - }; -} - -export default Logout; diff --git a/twistter-frontend/src/components/layout/NavBar.js b/twistter-frontend/src/components/layout/NavBar.js index f79fe79..92ad833 100644 --- a/twistter-frontend/src/components/layout/NavBar.js +++ b/twistter-frontend/src/components/layout/NavBar.js @@ -1,12 +1,43 @@ /* eslint-disable */ import React, { Component } from 'react'; import { Link } from 'react-router-dom'; +// import PropTypes from 'prop-types'; + +// Material UI stuff import AppBar from '@material-ui/core/AppBar'; import ToolBar from '@material-ui/core/Toolbar'; import Button from '@material-ui/core/Button'; +import withStyles from "@material-ui/core/styles/withStyles"; -export class Navbar extends Component { - render() { +// Redux stuff +// import { logoutUser } from '../../redux/actions/userActions'; +// import { connect } from 'react-redux'; + +// const styles = { +// form: { +// textAlign: "center" +// }, +// textField: { +// marginBottom: 30 +// }, +// pageTitle: { +// marginBottom: 40 +// }, +// button: { +// positon: "relative", +// marginBottom: 30 +// }, +// progress: { +// position: "absolute" +// } +// }; + + + + + + export class Navbar extends Component { + render() { return ( @@ -28,4 +59,18 @@ export class Navbar extends Component { } } +// const mapStateToProps = (state) => ({ +// user: state.user +// }) + +// const mapActionsToProps = { logoutUser }; + +// Navbar.propTypes = { +// logoutUser: PropTypes.func.isRequired, +// user: PropTypes.object.isRequired, +// classes: PropTypes.object.isRequired +// } + +// export default connect(mapStateToProps, mapActionsToProps)(withStyles(styles)(Navbar)); + export default Navbar; diff --git a/twistter-frontend/src/pages/Login.js b/twistter-frontend/src/pages/Login.js index 5453b11..affff6e 100644 --- a/twistter-frontend/src/pages/Login.js +++ b/twistter-frontend/src/pages/Login.js @@ -1,6 +1,6 @@ /* eslint-disable */ import React, { Component } from 'react'; -import '../App.css'; +// import '../App.css'; import PropTypes from 'prop-types'; import logo from '../images/twistter-logo.png'; @@ -173,6 +173,7 @@ const mapStateToProps = (state) => ({ const mapActionsToProps = { loginUser } + Login.propTypes = { classes: PropTypes.object.isRequired }; diff --git a/twistter-frontend/src/pages/Logout.js b/twistter-frontend/src/pages/Logout.js new file mode 100644 index 0000000..cd31c79 --- /dev/null +++ b/twistter-frontend/src/pages/Logout.js @@ -0,0 +1,56 @@ +/* eslint-disable */ +import React, { Component } from "react"; +import PropTypes from "prop-types"; + +// Material UI stuff +import Button from "@material-ui/core/Button"; +import withStyles from "@material-ui/core/styles/withStyles"; + +// Redux stuff +import { logoutUser } from "../redux/actions/userActions"; +import { connect } from "react-redux"; + +const styles = { + form: { + textAlign: "center" + }, + textField: { + marginBottom: 30 + }, + pageTitle: { + marginBottom: 40 + }, + button: { + positon: "relative", + marginBottom: 30 + }, + progress: { + position: "absolute" + } +}; + +export class Logout extends Component { + + componentDidMount() { + this.props.logoutUser(); + this.props.history.push('/'); + } + + render() { + return null; + } +} + +const mapStateToProps = (state) => ({ + user: state.user +}); + +const mapActionsToProps = { logoutUser }; + +Logout.propTypes = { + logoutUser: PropTypes.func.isRequired, + user: PropTypes.object.isRequired, + classes: PropTypes.object.isRequired +}; + +export default connect(mapStateToProps, mapActionsToProps)(withStyles(styles)(Logout)); diff --git a/twistter-frontend/src/pages/Signup.js b/twistter-frontend/src/pages/Signup.js index d97ff17..398997f 100644 --- a/twistter-frontend/src/pages/Signup.js +++ b/twistter-frontend/src/pages/Signup.js @@ -1,6 +1,6 @@ /* eslint-disable */ import React, { Component } from 'react'; -import '../App.css'; +// import '../App.css'; import PropTypes from 'prop-types'; import logo from '../images/twistter-logo.png'; @@ -42,8 +42,10 @@ export class Signup extends Component { constructor() { super(); this.state = { + handle: "", email: "", password:"", + confirmPassword: "", errors: {} }; } @@ -60,8 +62,10 @@ export class Signup extends Component { handleSubmit = (event) => { event.preventDefault(); const signupData = { + handle: this.state.handle, email: this.state.email, password: this.state.password, + confirmPassword: this.state.confirmPassword }; this.props.signupUser(signupData, this.props.history); }; @@ -88,7 +92,7 @@ export class Signup extends Component { logo - Log in to Twistter + Create a new account
({ const mapActionsToProps = { signupUser } + Signup.propTypes = { classes: PropTypes.object.isRequired }; From 00ed9d64c59226845b7c3ca40fe01de143df5915 Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Thu, 10 Oct 2019 14:13:04 -0400 Subject: [PATCH 6/8] store.js --- twistter-frontend/src/redux/store.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/twistter-frontend/src/redux/store.js b/twistter-frontend/src/redux/store.js index b79ebe6..93e0b8a 100644 --- a/twistter-frontend/src/redux/store.js +++ b/twistter-frontend/src/redux/store.js @@ -15,12 +15,13 @@ const reducers = combineReducers({ UI: uiReducer }); + const store = createStore( reducers, initialState, compose( applyMiddleware(...middleWare), - window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() + window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() // Can be removed after debugging is finished ) ); From 27efa858d5dddc668fe9d44591ffd93b3a01796e Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Fri, 11 Oct 2019 17:34:35 -0400 Subject: [PATCH 7/8] Signup is working --- functions/handlers/users.js | 8 +++--- twistter-frontend/src/Userline.js | 2 +- twistter-frontend/src/pages/Login.js | 2 +- twistter-frontend/src/pages/Signup.js | 28 ++++++++++++++++++- twistter-frontend/src/pages/edit.js | 7 +++++ .../src/redux/actions/userActions.js | 2 ++ 6 files changed, 42 insertions(+), 7 deletions(-) diff --git a/functions/handlers/users.js b/functions/handlers/users.js index 21f9b96..00d8f1c 100644 --- a/functions/handlers/users.js +++ b/functions/handlers/users.js @@ -50,7 +50,7 @@ exports.signup = (req, res) => { return res.status(400).json(errors); } - let idToken, userId; + let token, userId; db.doc(`/users/${newUser.handle}`) .get() @@ -68,8 +68,8 @@ exports.signup = (req, res) => { userId = data.user.uid; return data.user.getIdToken(); }) - .then((token) => { - idToken = token; + .then((idToken) => { + token = idToken; const userCred = { email: req.body.email, handle: newUser.handle, @@ -79,7 +79,7 @@ exports.signup = (req, res) => { return db.doc(`/users/${newUser.handle}`).set(userCred); }) .then(() => { - return res.status(201).json({ idToken }); + return res.status(201).json({ token }); }) .catch((err) => { console.error(err); diff --git a/twistter-frontend/src/Userline.js b/twistter-frontend/src/Userline.js index aa75716..8c95620 100644 --- a/twistter-frontend/src/Userline.js +++ b/twistter-frontend/src/Userline.js @@ -23,7 +23,7 @@ class Userline extends Component { componentDidMount() { - axios.get('http://localhost:5001/twistter-e4649/us-central1/api/getallPostsforUser') + axios.get('/getallPostsforUser') .then(res => { const post = res.data; this.setState({microBlogs : post}) diff --git a/twistter-frontend/src/pages/Login.js b/twistter-frontend/src/pages/Login.js index affff6e..7e3be76 100644 --- a/twistter-frontend/src/pages/Login.js +++ b/twistter-frontend/src/pages/Login.js @@ -123,7 +123,7 @@ export class Login extends Component { + +