user auth frontend
Sun Jul 23 2023 09:23:18 GMT+0000 (Coordinated Universal Time)
Saved by @nelson22
components > workoutdetails.js import React from 'react' import {useWorkoutContext} from '../hooks/useWorkoutContext'; import { useAuthContext } from '../hooks/useAuthContext'; const WorkoutDetails = ({workout}) => { const {user} = useAuthContext(); const {dispatch} = useWorkoutContext(); const handleClick = async () => { console.log("workout id =", workout._id); const response = await fetch(`/api/workouts/${workout._id}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${user.token}` } }) const json = await response.json(); if(response.ok){ dispatch({type: 'DELETE_WORKOUT', payload: json}); } } return ( <div className='workout-wrap'> <p className='workout-title'>{workout.title}</p> <p className='workout-details'><strong>Reps: </strong>{workout.reps}</p> <p className='workout-details'><strong>Load: </strong>{workout.load}</p> <p className='workout-details'><strong>Created at: </strong>{workout.createdAt}</p> <button className='delete' onClick={handleClick}>Delete Workout</button> </div> ) } export default WorkoutDetails ---------------------------------------------------------------- Pages > Home.js import React from 'react'; import { useEffect } from 'react'; import WorkoutDetails from '../components/WorkoutDetails'; import WorkoutForm from '../components/WorkoutForm'; import {useWorkoutContext} from '../hooks/useWorkoutContext'; import { useAuthContext } from '../hooks/useAuthContext'; const Home = () => { //const [workout, setWorkout] = useState(null) const {workouts, dispatch} = useWorkoutContext(); const {user} = useAuthContext(); useEffect(() => { const fetchWorkout = async () => { const response = await fetch('/api/workouts/', { headers: { 'Authorization': `Bearer ${user.token}` } }) const json = await response.json() if(response.ok){ //setWorkout(json) dispatch({type: 'SETWORKOUTS', payload: json}) } } if(user){ fetchWorkout() } }, [user]) return ( <div className='container'> <div className='workout-main'> <h2 className='workout-hd'>Fill the form below to add your workout.</h2> <WorkoutForm></WorkoutForm> <h2 className='workout-hd'>Below are the lists of workouts to be done every week.</h2> {workouts && workouts.map((data) => ( <WorkoutDetails key={data._id} workout={data}></WorkoutDetails> ))} </div> </div> ) } export default Home ---------------------------------------------------------- CONTEXT > AuthContext.js import { createContext, useEffect, useReducer } from "react"; export const AuthContext = createContext(); const initState = { user: null } const authReducer = (state, action) => { switch(action.type){ case 'LOGIN': return { user: action.payload} case 'LOGOUT': return {user: null} default: return state } } export const AuthContextProvider = ({children}) => { const [state, dispatch] = useReducer(authReducer, initState); console.log("auth context = ", state); useEffect(() => { let user = JSON.parse(localStorage.getItem('user')); if(user){ dispatch({type: 'LOGIN', payload: user}); } }, []); return( <AuthContext.Provider value={{...state, dispatch}}> {children} </AuthContext.Provider> ) } ----------------------------------------------------------- HOOKS > useAuthContext.js import { AuthContext } from "../context/AuthContext"; import { useContext } from "react"; export const useAuthContext = () => { const context = useContext(AuthContext); if(!context){ throw Error("useAuthContext context must be used inside AuthContextProvider"); } return context } ----------------------------------------------------------- INDEX.JS import { AuthContextProvider } from './context/AuthContext'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <AuthContextProvider> <App /> </AuthContextProvider> </React.StrictMode> ); ----------------------------------------------------------- HOOKS > useSignup.js import { useState } from "react"; import {useAuthContext} from './useAuthContext'; export const useSignup = () => { const [error, setError] = useState(null); const [isLoading, setIsLoading] = useState(false); const {dispatch} = useAuthContext(); const signup = async (email, password) => { setError(null); setIsLoading(true); const response = await fetch('/api/user/signup', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({email, password}) }); const json = await response.json() if(!response.ok){ setIsLoading(false); setError(json.error); } if(response.ok){ localStorage.setItem('user', JSON.stringify(json)); dispatch({type: 'LOGIN', payload: json}); setIsLoading(false); setError(null); } } return {signup, isLoading, error} } ----------------------------------------------------------- PAGES > Signup.js import React, {useState} from 'react' import { useSignup } from '../hooks/useSignup'; const Signup = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const {signup, isLoading, error} = useSignup(); const handleSubmit = async (e) => { e.preventDefault(); await signup(email, password); console.log(email, password); } return ( <div className='flex-wrap'> <form className='signup-form'> <h2>Sign up</h2> <input type="text" placeholder="Enter your email" value={email} onChange={(e) => setEmail(e.target.value)} /> <input type="password" placeholder="Enter your password" value={password} onChange={(e) => setPassword(e.target.value)} /> <input type="submit" className="submit" value="Submit" onClick={(e) => handleSubmit(e)} /> <p className='error'>{error && error}</p> </form> </div> ) } export default Signup ----------------------------------------------------------- HOOKS > useLogin.js import { useState } from "react"; import {useAuthContext} from './useAuthContext'; export const useLogin = () => { const [error, setError] = useState(null); const [isLoading, setIsLoading] = useState(false); const {dispatch} = useAuthContext(); const login = async (email, password) => { setError(null); setIsLoading(true); const response = await fetch('/api/user/login', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({email, password}) }); const json = await response.json() if(!response.ok){ setIsLoading(false); setError(json.error); } if(response.ok){ localStorage.setItem('user', JSON.stringify(json)); dispatch({type: 'LOGIN', payload: json}); setIsLoading(false); setError(null); } } return {login, isLoading, error} } ----------------------------------------------------------- PAGES > Login.js import React, {useState} from 'react'; import { useLogin } from '../hooks/useLogin'; const Login = () => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const {login, isLoading, error} = useLogin(); const handleSubmit = async (e) => { e.preventDefault(); await login(email, password); console.log(email, password); } return ( <div className='flex-wrap'> <form className='login-form'> <h2>Login</h2> <input type="text" placeholder="Enter your email" value={email} onChange={(e) => setEmail(e.target.value)} /> <input type="password" placeholder="Enter your password" value={password} onChange={(e) => setPassword(e.target.value)} /> <input type="submit" disabled={isLoading} className="submit" value="Submit" onClick={(e) => handleSubmit(e)} /> <p className='error'>{error && error}</p> </form> </div> ) } export default Login ----------------------------------------------------------- HOOKS > useLogout.js import { useAuthContext } from "./useAuthContext"; export const useLogout = () => { const {dispatch} = useAuthContext(); const logout = () => { localStorage.removeItem('user'); dispatch({type: 'LOGOUT'}); } return {logout} } ----------------------------------------------------------- COMPONENTS > Navbar.js import React from 'react'; import { Link } from 'react-router-dom'; import { useLogout } from '../hooks/useLogout'; import { useAuthContext } from '../hooks/useAuthContext'; const Navbar = () => { const {user} = useAuthContext(); const {logout} = useLogout(); const handleClick = () => { logout(); } return ( <header className='header'> <Link to="/"> Workout Buddy </Link> {user ? <div> {console.log(user.email)} <span className='loggedin'>{user.email}</span> <Link onClick={handleClick} className='nav-items'> Logout </Link> </div> : <div> <Link to="/login" className='nav-items'> Login </Link> <Link to="/Signup" className='nav-items'> Signup </Link> </div> } </header> ) } export default Navbar ------------------------------------------------------------ components > workoutforms.js import { useState } from 'react' import {useWorkoutContext} from '../hooks/useWorkoutContext'; import {useAuthContext} from '../hooks/useAuthContext'; const WorkoutForm = () => { const {dispatch} = useWorkoutContext(); const [title, setTitle] = useState(''); const [reps, setReps] = useState(''); const [load, setLoad] = useState(''); const [error, setError] = useState(''); const {user} = useAuthContext(); const handleSubmit = async (e) => { e.preventDefault(); if(!user){ setError('You must be logged in'); return } const formData = {title, reps, load}; const response = await fetch('/api/workouts/', { method: 'POST', body: JSON.stringify(formData), headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${user.token}` } }) const json = await response.json(); if(!response.ok){ setError(json.error); } if(response.ok){ dispatch({type: 'CREATE_WORKOUT', payload: json}) setError(''); setTitle(''); setReps(''); setLoad(''); console.log("Workout added succcessfully!!!", json); } } return ( <form onSubmit={handleSubmit} className="workout-form"> <input type="text" className="form-input" placeholder="Enter Workout Title" onChange={e => setTitle(e.target.value)} value={title} /> <br /> <input type="text" className="form-input" placeholder="Enter Workout Reps" onChange={e => setReps(e.target.value)} value={reps} /> <br /> <input type="text" className="form-input" placeholder="Enter Workout Load" onChange={e => setLoad(e.target.value)} value={load} /> <br /> <input type="submit" value="Submit" className='form-submit' /> {error && <p>{error}</p>} </form> ) } export default WorkoutForm --------------------------------------------- app.js import './App.css'; import {BrowserRouter, Routes, Route, Navigate} from 'react-router-dom'; import Home from './pages/Home'; import Navbar from './components/Navbar'; import Login from './pages/Login'; import Signup from './pages/Signup'; import { useAuthContext } from './hooks/useAuthContext'; function App() { const {user} = useAuthContext(); return ( <div className="App"> <BrowserRouter> <Navbar /> <Routes> <Route path="/" element={user ? <Home /> : <Navigate to="/login" />} /> <Route path="/login" element={!user ? <Login /> : <Navigate to="/" />} /> <Route path="/signup" element={!user ? <Signup /> : <Navigate to="/" />} /> </Routes> </BrowserRouter> </div> ); } export default App;
Comments