From 5064ff71e6cc65a5afdb710130d3c42a7157d0ce Mon Sep 17 00:00:00 2001 From: Terri Archer Date: Sat, 31 Dec 2022 14:09:37 -0500 Subject: [PATCH 1/2] completed MVP --- src/App.js | 25 ++++++++++--- src/components/AddFriend.js | 59 +++++++++++++++++++++++++++++++ src/components/Friend.js | 13 +++++++ src/components/FriendList.js | 36 +++++++++++++++++++ src/components/Header.js | 20 +++++++++++ src/components/Login.js | 62 +++++++++++++++++++++++++++++++++ src/components/Logout.js | 24 +++++++++++++ src/components/PrivateRoutes.js | 12 +++++++ src/mocks/api.js | 4 +-- 9 files changed, 248 insertions(+), 7 deletions(-) create mode 100644 src/components/AddFriend.js create mode 100644 src/components/Friend.js create mode 100644 src/components/FriendList.js create mode 100644 src/components/Header.js create mode 100644 src/components/Login.js create mode 100644 src/components/Logout.js create mode 100644 src/components/PrivateRoutes.js diff --git a/src/App.js b/src/App.js index 1b971d1f6..b12f99546 100644 --- a/src/App.js +++ b/src/App.js @@ -1,12 +1,27 @@ -import React from 'react'; +import React, { useState } from 'react'; import './App.css'; -import { BrowserRouter as Router, Route} from 'react-router-dom'; +import { BrowserRouter as Router,Route,Routes} from 'react-router-dom'; +import Header from './components/Header'; +import FriendList from './components/FriendList'; +import Login from './components/Login'; +import AddFriend from './components/AddFriend'; +import Logout from './components/Logout'; +import PrivateRoutes from "./components/PrivateRoutes" function App() { + const [friends,setFriends] = useState([]) + return ( -
-

Client Auth Project

-
+ <> +
+ + + }/> + }/> + }/> + }/> + + ); } diff --git a/src/components/AddFriend.js b/src/components/AddFriend.js new file mode 100644 index 000000000..94e5e70a7 --- /dev/null +++ b/src/components/AddFriend.js @@ -0,0 +1,59 @@ +import axios from "axios"; +import React, {useState} from "react"; + +const initialFormValues = { + name: '', + email: '', + age: '' +} + +const AddFriend = () => { + const token = localStorage.getItem('token') + const[formValues,setFormValues] = useState(initialFormValues) + + function handleChange(e){ + setFormValues(() => { + return{ + ...formValues, + [e.target.name]: e.target.value + } + }) + } + + function handleSubmit(e){ + e.preventDefault(); + axios.create({ headers: { Authorization: token}}) + .post(`http://localhost:9000/api/friends`, formValues) + .then(res => console.log(res)) + .catch(err => console.error(err)) + } + + return( + <> +
handleSubmit(e)}> + handleChange(e)} + /> + handleChange(e)} + /> + handleChange(e)} + /> + +
+ + ) + +} + +export default AddFriend; \ No newline at end of file diff --git a/src/components/Friend.js b/src/components/Friend.js new file mode 100644 index 000000000..ad9641899 --- /dev/null +++ b/src/components/Friend.js @@ -0,0 +1,13 @@ +import React from "react"; + +const Friend = ({friend}) => { + return( + <> +
  • +

    {friend.name} - {friend.age ? `age: ${friend.age} -` : ""} {friend.email}

    +
  • + + ) +} + +export default Friend \ No newline at end of file diff --git a/src/components/FriendList.js b/src/components/FriendList.js new file mode 100644 index 000000000..2f24043c1 --- /dev/null +++ b/src/components/FriendList.js @@ -0,0 +1,36 @@ +import React, {useEffect} from "react"; +import axios from "axios"; +import Friend from "./Friend"; +import { useNavigate } from "react-router-dom"; + + +const FriendList = (props) => { + const token = localStorage.getItem('token') + let navigate = useNavigate(); + + useEffect(()=> { + axios.create({ headers: { Authorization: token}}) + .get('http://localhost:9000/api/friends') + .then(res => props.setFriends(res.data)) + .catch(err => { + navigate('/') + }) + }, []) + + return( + <> +

    FriendList

    + {props.friends.length != 0 ? + + : +

    No friends to display

    + } + + ) +} + +export default FriendList; \ No newline at end of file diff --git a/src/components/Header.js b/src/components/Header.js new file mode 100644 index 000000000..f601bb929 --- /dev/null +++ b/src/components/Header.js @@ -0,0 +1,20 @@ +import React from "react"; +import { Link } from "react-router-dom"; + +const Header = (props) => { + return( +
    +
    +

    FRIENDS DATABASE

    +
    + +
    + ) +} + +export default Header; \ No newline at end of file diff --git a/src/components/Login.js b/src/components/Login.js new file mode 100644 index 000000000..3910edc47 --- /dev/null +++ b/src/components/Login.js @@ -0,0 +1,62 @@ +import axios from "axios"; +import React, {useState} from "react"; +import { useNavigate } from "react-router-dom"; + +const initialFormValues = { + username: '', + password: '', +} + +const Login = () => { + let navigate = useNavigate(); + + const[formValues,setFormValues] = useState(initialFormValues) + const[error,setError] = useState('') + + function handleChange(e){ + setFormValues(() => { + return{ + ...formValues, + [e.target.name]: e.target.value + } + }) + } + + function handleSubmit(e){ + e.preventDefault(); + axios.post('http://localhost:9000/api/login', formValues) + .then(({data}) => { + localStorage.setItem('token', data.token) + navigate('/friendlist') + }) + .catch(err => setError('Invalid login!')) + setFormValues(initialFormValues) + } + return( + <> + {error &&

    {error}

    } + + + ) + +} + +export default Login; \ No newline at end of file diff --git a/src/components/Logout.js b/src/components/Logout.js new file mode 100644 index 000000000..cf8924b62 --- /dev/null +++ b/src/components/Logout.js @@ -0,0 +1,24 @@ +import React from "react"; +import axios from "axios"; +import { useNavigate } from "react-router-dom"; + +const Logout = () => { + const navigate = useNavigate() + const token = localStorage.getItem('token') + function confirm(){ + axios.create({ headers: { Authorization: token}}) + .post(`http://localhost:9000/api/logout`) + .then(({data}) => + { + localStorage.setItem('token', '' ) + navigate('/') + }) + } + + return( + + ) + +} + +export default Logout; \ No newline at end of file diff --git a/src/components/PrivateRoutes.js b/src/components/PrivateRoutes.js new file mode 100644 index 000000000..d2fd288bc --- /dev/null +++ b/src/components/PrivateRoutes.js @@ -0,0 +1,12 @@ +import React, { Component } from "react"; +import { Route, Navigate, Routes } from "react-router-dom"; + +const PrivateRoutes = ({ children }) => { + if(localStorage.getItem('token').length < 5){ + return + } + + return children; +} + +export default PrivateRoutes \ No newline at end of file diff --git a/src/mocks/api.js b/src/mocks/api.js index 57493e8a1..245597842 100644 --- a/src/mocks/api.js +++ b/src/mocks/api.js @@ -36,7 +36,7 @@ api.post('/api/login', (req, res) => { }) -api.post('/api/logout', authenticator, (req, res) => { +api.post('/api/logout',authenticator, (req, res) => { const {username, role, token} = credentials; res.json({ username, @@ -45,7 +45,7 @@ api.post('/api/logout', authenticator, (req, res) => { }) }) -api.get('/api/friends', authenticator, (req, res) => { +api.get('/api/friends', authenticator,(req, res) => { res.json(Data.getAll()) }) From 1acbd3eadec49af396393dc2a4f8b49535321c29 Mon Sep 17 00:00:00 2001 From: Terri Archer Date: Sat, 31 Dec 2022 14:10:53 -0500 Subject: [PATCH 2/2] fixed login link --- src/components/Header.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Header.js b/src/components/Header.js index f601bb929..562245f15 100644 --- a/src/components/Header.js +++ b/src/components/Header.js @@ -8,7 +8,7 @@ const Header = (props) => {

    FRIENDS DATABASE