From bba05c51c99bc7841c9c692b0bae974cefe46c3e Mon Sep 17 00:00:00 2001 From: Angelique Abacajan Date: Tue, 9 Nov 2021 15:35:39 -0500 Subject: [PATCH 1/6] Added similar files from the GP and added a route login page --- README.md | 12 +++++------ friends/src/components/Friends.js | 0 friends/src/components/Login.js | 28 ++++++++++++++++++++++++++ friends/src/components/Logout.js | 0 friends/src/components/PrivateRoute.js | 0 package-lock.json | 13 ++++++++++++ package.json | 2 +- 7 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 friends/src/components/Friends.js create mode 100644 friends/src/components/Login.js create mode 100644 friends/src/components/Logout.js create mode 100644 friends/src/components/PrivateRoute.js diff --git a/README.md b/README.md index 00ff367ae..0c3032245 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Auth Friends +# Auth Friends (Checklist) Topics: @@ -15,10 +15,10 @@ Topics: #### Initialize Project -* Run `npm install` inside the root directory of this project to install dependencies for the API server. -* Run `npm start` to start the API server. -* `cd` into the _friends_ folder. -* Run `npm start` to start the client code. + Run `npm install` inside the root directory of this project to install dependencies for the API server. +[x] Run `npm start` to start the API server. +[x] `cd` into the _friends_ folder. +[x] Run `npm start` to start the client code. ### Task 2: MVP @@ -37,7 +37,7 @@ Topics: * **[POST]** * to `/api/friends`: Adds in a new friend. #### Build the App! -* Add a route for a login page and build out a simple login form with username and password inputs and a submit button (design this however you would like). +[x] Add a route for a login page and build out a simple login form with username and password inputs and a submit button (design this however you would like). * The login function should save the returned token to localStorage. You can setup `isLoading` state in your Login component, and show a spinner on your form or in your button while the login request is happening. * When the request returns, save the token to `localStorage`, then use the history object in your Login component to navigate your user to your FriendsList route * Create a `` component to protect your other routes. It should check localStorage for a token, and redirect the user to your login route if there is not a token. diff --git a/friends/src/components/Friends.js b/friends/src/components/Friends.js new file mode 100644 index 000000000..e69de29bb diff --git a/friends/src/components/Login.js b/friends/src/components/Login.js new file mode 100644 index 000000000..b32a902ed --- /dev/null +++ b/friends/src/components/Login.js @@ -0,0 +1,28 @@ +import React from 'react'; +import axois from 'axios'; + +class Login extends React.Component { + + // Initial state (values) + state = { + credentials: { + username: "", + password: "" + } + }; + + // handling change when clicking a button + handleChange = event => { + this.setState({ + credentials: { + ...this.state.credentials, + [event.target.name]: event.target.value + } + }) + }; + + // Login axios call using Post + axios.post("http://localhost:5000/api/login") + + +} \ No newline at end of file diff --git a/friends/src/components/Logout.js b/friends/src/components/Logout.js new file mode 100644 index 000000000..e69de29bb diff --git a/friends/src/components/PrivateRoute.js b/friends/src/components/PrivateRoute.js new file mode 100644 index 000000000..e69de29bb diff --git a/package-lock.json b/package-lock.json index 5ba234cb8..a44756b19 100644 --- a/package-lock.json +++ b/package-lock.json @@ -86,6 +86,14 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "axios": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.24.0.tgz", + "integrity": "sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==", + "requires": { + "follow-redirects": "^1.14.4" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -485,6 +493,11 @@ "unpipe": "~1.0.0" } }, + "follow-redirects": { + "version": "1.14.5", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz", + "integrity": "sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==" + }, "forwarded": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", diff --git a/package.json b/package.json index 954bad52e..54d55755f 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "", "main": "server.js", "dependencies": { + "axios": "^0.24.0", "body-parser": "^1.19.0", "cors": "^2.8.5", "express": "^4.17.1" @@ -18,4 +19,3 @@ "author": "Lambda School", "license": "ISC" } - From 924eebd7abf01af447a6dd3d60d47415154f544a Mon Sep 17 00:00:00 2001 From: Angelique Abacajan Date: Tue, 9 Nov 2021 16:02:13 -0500 Subject: [PATCH 2/6] Implemented Login.js by adding localStorage in the axios call --- friends/src/components/Login.js | 46 ++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/friends/src/components/Login.js b/friends/src/components/Login.js index b32a902ed..3e84493cc 100644 --- a/friends/src/components/Login.js +++ b/friends/src/components/Login.js @@ -1,5 +1,6 @@ import React from 'react'; import axois from 'axios'; +import axios from 'axios'; class Login extends React.Component { @@ -22,7 +23,50 @@ class Login extends React.Component { }; // Login axios call using Post - axios.post("http://localhost:5000/api/login") + login = () => { + axios.post("http://localhost:5000/api/login", this.state.credentials) + .then(response => { + localStorage.setItem("token", response.data.payload); + localStorage.setItem("username", this.state.credentials.username); + this.props.history.push("/protected"); + + }).catch(error => { + console.error(error); + }) + }; + + + // render props + render() { + return( +
+
+ {/* Input fields for username and password */} + + + + + {/* Submit button */} + +
+
+ + ) + } } \ No newline at end of file From 68e9c02841d407a9e909d248d4f4cb2132c34943 Mon Sep 17 00:00:00 2001 From: Angelique Abacajan Date: Tue, 9 Nov 2021 16:05:05 -0500 Subject: [PATCH 3/6] Checked off tasks in the ReadMe file --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0c3032245..7914e3537 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Topics: #### Initialize Project - Run `npm install` inside the root directory of this project to install dependencies for the API server. +[x] Run `npm install` inside the root directory of this project to install dependencies for the API server. [x] Run `npm start` to start the API server. [x] `cd` into the _friends_ folder. [x] Run `npm start` to start the client code. @@ -38,8 +38,8 @@ Topics: #### Build the App! [x] Add a route for a login page and build out a simple login form with username and password inputs and a submit button (design this however you would like). -* The login function should save the returned token to localStorage. You can setup `isLoading` state in your Login component, and show a spinner on your form or in your button while the login request is happening. -* When the request returns, save the token to `localStorage`, then use the history object in your Login component to navigate your user to your FriendsList route +[x] The login function should save the returned token to localStorage. You can setup `isLoading` state in your Login component, and show a spinner on your form or in your button while the login request is happening. +[x] When the request returns, save the token to `localStorage`, then use the history object in your Login component to navigate your user to your FriendsList route * Create a `` component to protect your other routes. It should check localStorage for a token, and redirect the user to your login route if there is not a token. * Create a protected route for your friends list. Remember, if the user isn't logged in, navigating to this protected route will redirect them to the login page. * In your FriendsList component, rendered with ``, you will create a list of your friends that you get from the API. From fde0c614f615db2e576fc6cdeeb4ec98ef298931 Mon Sep 17 00:00:00 2001 From: Angelique Abacajan Date: Tue, 9 Nov 2021 16:24:38 -0500 Subject: [PATCH 4/6] Implemented PrivateRoute and export Login --- README.md | 7 ++++++- friends/src/components/Login.js | 4 +++- friends/src/components/PrivateRoute.js | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7914e3537..a0b32c320 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,15 @@ Topics: #### Build the App! [x] Add a route for a login page and build out a simple login form with username and password inputs and a submit button (design this however you would like). + [x] The login function should save the returned token to localStorage. You can setup `isLoading` state in your Login component, and show a spinner on your form or in your button while the login request is happening. + [x] When the request returns, save the token to `localStorage`, then use the history object in your Login component to navigate your user to your FriendsList route -* Create a `` component to protect your other routes. It should check localStorage for a token, and redirect the user to your login route if there is not a token. + +[x] Create a `` component to protect your other routes. It should check localStorage for a token, and redirect the user to your login route if there is not a token. + * Create a protected route for your friends list. Remember, if the user isn't logged in, navigating to this protected route will redirect them to the login page. + * In your FriendsList component, rendered with ``, you will create a list of your friends that you get from the API. **Adding New Friends** diff --git a/friends/src/components/Login.js b/friends/src/components/Login.js index 3e84493cc..1a2ba4cf3 100644 --- a/friends/src/components/Login.js +++ b/friends/src/components/Login.js @@ -69,4 +69,6 @@ class Login extends React.Component { } -} \ No newline at end of file +} + +export default Login; \ No newline at end of file diff --git a/friends/src/components/PrivateRoute.js b/friends/src/components/PrivateRoute.js index e69de29bb..175f7bc8b 100644 --- a/friends/src/components/PrivateRoute.js +++ b/friends/src/components/PrivateRoute.js @@ -0,0 +1,14 @@ +import React from 'react'; +import { Route, Redirect } from 'react-router-dom'; + +const PrivateRoute = ({ component: Component, ...rest }) => { + return { + if(localStorage.getItem("token")){ + + } else { + return + } + }}/> +} + +export default PrivateRoute; \ No newline at end of file From 1a392c1c8311e7d7517e217d909a33b02fb9835c Mon Sep 17 00:00:00 2001 From: Angelique Abacajan Date: Tue, 9 Nov 2021 16:46:52 -0500 Subject: [PATCH 5/6] Implemented and added axiosWithAuth to render PrivateRoute to Friends.js component --- README.md | 2 +- friends/src/components/Friends.js | 44 ++++++++++++++++++++++++++++++ friends/src/utils/axiosWithAuth.js | 15 ++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 friends/src/utils/axiosWithAuth.js diff --git a/README.md b/README.md index a0b32c320..e8e91e45d 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ Topics: [x] Create a `` component to protect your other routes. It should check localStorage for a token, and redirect the user to your login route if there is not a token. -* Create a protected route for your friends list. Remember, if the user isn't logged in, navigating to this protected route will redirect them to the login page. +[x] Create a protected route for your friends list. Remember, if the user isn't logged in, navigating to this protected route will redirect them to the login page. * In your FriendsList component, rendered with ``, you will create a list of your friends that you get from the API. diff --git a/friends/src/components/Friends.js b/friends/src/components/Friends.js index e69de29bb..1b638d580 100644 --- a/friends/src/components/Friends.js +++ b/friends/src/components/Friends.js @@ -0,0 +1,44 @@ +import axios from 'axios'; +import React from 'react'; +import { BrowserRouter as Router, Switch, Link } from 'react-router-dom'; +import PrivateRoute from './PrivateRoute'; +import axiosWithAuth from '../utils/axiosWithAuth'; + +class Friends extends React.Component { + state = { + friends: [] + }; + + componentDidMount() { + axiosWithAuth().get('/api/friends', { + + }).then(response => { + this.setState({ + ...this.state, + friends: response.data + }) + }).catch(error => { + console.error(error); + }) + } + + render() { + + const { friends } = this.state; + return( +
+ {friends.map(friend => { + return( +
+

Name: {friend.name}

+

Age: {friend.age}

+

Email: {friend.email}

+
+ ) + })} +
+ ) + } +} + +export default Friends; \ No newline at end of file diff --git a/friends/src/utils/axiosWithAuth.js b/friends/src/utils/axiosWithAuth.js new file mode 100644 index 000000000..2a6df1b22 --- /dev/null +++ b/friends/src/utils/axiosWithAuth.js @@ -0,0 +1,15 @@ +import axios from 'axios'; + +const axiosWithAuth = () => { + const token = localStorage.getItem("token"); + + return axios.create({ + headers: { + authorization: token + }, + + baseURL: "http://localhost:5000" + }) +} + +export default axiosWithAuth; \ No newline at end of file From b7c03b784f892c143c112320ac0830cb3a1be656 Mon Sep 17 00:00:00 2001 From: Angelique Abacajan Date: Tue, 9 Nov 2021 19:55:59 -0500 Subject: [PATCH 6/6] MVP with added components --- README.md | 5 +++-- friends/src/components/Logout.js | 24 ++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e8e91e45d..359f61ecd 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ Topics: [x] Create a protected route for your friends list. Remember, if the user isn't logged in, navigating to this protected route will redirect them to the login page. -* In your FriendsList component, rendered with ``, you will create a list of your friends that you get from the API. +[x] In your FriendsList component, rendered with ``, you will create a list of your friends that you get from the API. **Adding New Friends** * Create a form to collects data for a new friend. @@ -63,7 +63,8 @@ Topics: } ``` -* If you'd like, you can create multiple "view" components for your routes. You could have a component who's sole purpose is to render the login form; one for a form for updating a user; another component who's sole purpose is for creating users; and then another component who's sole purpose is to delete a user. +[x] If you'd like, you can create multiple "view" components for your routes. You could have a component who's sole purpose is to render the login form; one for a form for updating a user; another component who's sole purpose is for creating users; and then another component who's sole purpose is to delete a user. + Added Logout component and axiosWithAuth * It really is up to you how you build this project. I suggest writing down the flow you want to follow, and then writing down each individual piece you need for each step in the flow so that this process doesn't feel as overwhelming. ### Task 3: Stretch Problems diff --git a/friends/src/components/Logout.js b/friends/src/components/Logout.js index e69de29bb..faf37df75 100644 --- a/friends/src/components/Logout.js +++ b/friends/src/components/Logout.js @@ -0,0 +1,24 @@ +import React, { useEffect } from 'react'; +import axiosWithAuth from '../utils/axiosWithAuth'; + +const Logout = (props) => { + useEffect(() => { + axiosWithAuth().post("/api/logout", { + + }).then(response => { + localStorage.removeItem("token"); + localStorage.removeItem("username"); + props.history.push("/login") + + }).catch(error => { + console.error(error) + }) + }, []) + + + return( +
+ {/* empty? */} +
+ ) +} \ No newline at end of file