Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions client/src/components/ErrorMessage.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import React from "react";
import { Alert } from "react-bootstrap";

const ErrorMessage = ({ variant = "info", children }) => {
const ErrorMessage = ({ errors, variant }) => {
if (!errors) {
return null;
}
return (
<Alert variant={variant} style={{ fontSize: 20 }}>
<strong>{children}</strong>
</Alert>
<div className={`alert alert-${variant}`}>
{Object.values(errors).map((error) => (
<p key={error}>{error}</p>
))}
</div>
);
};

export default ErrorMessage;
export default ErrorMessage;
97 changes: 97 additions & 0 deletions client/src/hooks/useAuth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { useEffect, useReducer } from "react";
import axios from "axios";

const useAuth = () => {
const [state, dispatch] = useReducer(
(state, action) => {
switch (action.type) {
case "reset":
return {
loading: false,
error: null,
user: null,
};
case "error":
return {
...state,
loading: false,
error: action.error,
};
case "login":
case "register":
return {
...state,
loading: true,
};
case "success":
return {
loading: false,
error: null,
user: action.user,
};
default:
return state;
}
},
{
loading: false,
error: null,
user: null,
}
);

const register = async (values) => {
dispatch({ type: "register" });
try {
const response = await axios.post("/api/users/register", values, {
baseURL: "http://localhost:5000",
headers: {
"Content-Type": "application/json",
},
});
const { data } = response;
localStorage.setItem("userInfo", JSON.stringify(data));
dispatch({ type: "success", user: data });
} catch (error) {
dispatch({ type: "error", error: error.message });
}
};

const login = async (values) => {
dispatch({ type: "login" });
try {
const response = await axios.post("/api/users/login", values, {
baseURL: "http://localhost:5000",
headers: {
"Content-Type": "application/json",
},
});
const { data } = response;
localStorage.setItem("userInfo", JSON.stringify(data));
dispatch({ type: "success", user: data });
} catch (error) {
dispatch({ type: "error", error: error.message });
}
};

const logout = () => {
localStorage.removeItem("userInfo");
dispatch({ type: "reset" });
};

useEffect(() => {
const user = JSON.parse(localStorage.getItem("userInfo"));
if (user) {
dispatch({ type: "success", user });
}
}, []);

return {
...state,
register,
login,
logout,
};
};

export default useAuth;
32 changes: 32 additions & 0 deletions client/src/hooks/useMakeRequest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useState } from "react";
import axios from "axios";

const useMakeRequest = ({
requestMethod,
requestUrl,
requestData,
requestConfig,
}) => {
const [response, setResponse] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(false);

const makeRequest = async () => {
setLoading(true);
try {
const res = await axios[requestMethod](
requestUrl,
requestData,
requestConfig
);
setResponse(res);
} catch (err) {
setError(err);
}
setLoading(false);
};

return { makeRequest, response, error, loading };
};

export default useMakeRequest;
9 changes: 5 additions & 4 deletions client/src/screens/LoginPage/LoginPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const LoginPage = () => {
});
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);

const submitHandler = async (event) => {
event.preventDefault();
setLoading(true);
Expand All @@ -29,11 +29,12 @@ const LoginPage = () => {
});

localStorage.setItem("userInfo", JSON.stringify(response.data));
console.log(values);
console.log(response.data);
setLoading(false);
resetForm();
} catch (err) {
setError(err.message);
console.log(err);
setError(err.error);
setLoading(false);
}
};
Expand All @@ -42,7 +43,7 @@ const LoginPage = () => {
<MainScreen title="LOGIN">
<div className="loginContainer">
{loading && <Loading />}
{error && <div variant="danger">{error}</div>}
{error && <div>{error}</div>}
<Form onSubmit={submitHandler}>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
Expand Down
176 changes: 93 additions & 83 deletions client/src/screens/RegisterPage/RegisterPage.jsx
Original file line number Diff line number Diff line change
@@ -1,94 +1,104 @@
import React,{useState,useEffect} from 'react'
import './register.css'
import MainScreen from './../../components/MainScreen';
import { Form ,Button} from 'react-bootstrap';
import axios from 'axios'
import ErrorMessage from './../../components/ErrorMessage';
import Loading from './../../components/Loading';
import React, { useState } from "react";
import "./register.css";
import MainScreen from "./../../components/MainScreen";
import { Form, Button } from "react-bootstrap";
import ErrorMessage from "./../../components/ErrorMessage";
import Loading from "./../../components/Loading";
import useForm from "../../hooks/useForm";
import axios from "axios";

const RegisterPage = () => {
const [email, setEmail] = useState("");
const [name, setName] = useState("");
const [pic, setPic] = useState(
"https://icon-library.com/images/anonymous-avatar-icon/anonymous-avatar-icon-25.jpg"
);
const [password, setPassword] = useState("");
const [confirmpassword, setConfirmPassword] = useState("");
const [message, setMessage] = useState(null);
const [picMessage, setPicMessage] = useState(null);
const[error,setError] =useState(false)
const[loading,setLoading] =useState(false)
const submitHandler = async(e)=>{
e.preventDefault()
if(password !== confirmpassword){
setMessage("passwords do not match")
}else{
setMessage(null)
try{
setLoading(true)
const {data}= await axios.post("/api/users/",{name,pic,email,password}, {
baseURL: "http://localhost:5000",
headers: {
"Content-Type": "application/json",
}
});
setLoading(false)
const [values, handleChange, resetForm] = useForm({
email: "",
name: "",
pic: "https://icon-library.com/images/anonymous-avatar-icon/anonymous-avatar-icon-25.jpg",
password: "",
confirmpassword: "",
});
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);

const submitHandler = async (event) => {
event.preventDefault();
setLoading(true);
try {
const response = await axios.post("/api/users/register", values, {
baseURL: "http://localhost:5000",
headers: {
"Content-Type": "application/json",
},
});

localStorage.setItem("userInfo", JSON.stringify(data))
}
catch(err){
setError(error.response.data.message)
}
}
console.log(email);
localStorage.setItem("userInfo", JSON.stringify(response.data));
console.log(values);
setLoading(false);
resetForm();
} catch (err) {
setError(err.message);
setLoading(false);
}
};

return (
<MainScreen title="Register">
<div className="loginContainer">
{error && <ErrorMessage variant="danger" >{error}</ErrorMessage>}
{message && <ErrorMessage variant="danger" >{message}</ErrorMessage>}
{loading && <Loading/>}
<div className="loginContainer">
<ErrorMessage variant="danger" errors={error} />
{loading && <Loading />}
<Form onSubmit={submitHandler}>
<Form.Group className="mb-3" controlId="formBasicName">
<Form.Label>Enter name</Form.Label>
<Form.Control value={name}
placeholder="Enter name"
onChange={(e) => setName(e.target.value)} />
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicName">
<Form.Label>Enter name</Form.Label>
<Form.Control
type="text"
placeholder="Enter name"
name="name"
value={values.name}
onChange={handleChange}
/>
</Form.Group>

<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control type="email"
value={email}
placeholder="Enter email"
onChange={(e) => setEmail(e.target.value)} />
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicEmail">
<Form.Label>Email address</Form.Label>
<Form.Control
type="email"
placeholder="Enter email"
name="email"
value={values.email}
onChange={handleChange}
/>
</Form.Group>

<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control type="password"
value={password}
placeholder="Password"
onChange={(e) => setPassword(e.target.value)}/>
</Form.Group>
<Form.Group className="mb-3" controlId="confirmPassword">
<Form.Label>confirm Password</Form.Label>
<Form.Control type="password"
value={confirmpassword}
placeholder="Confirm Password"
onChange={(e) => setConfirmPassword(e.target.value)} />
</Form.Group>
<Form.Group controlId="formFile" className="mb-3">
<Form.Label>upload profile picture</Form.Label>
<Form.Control type="file" />
</Form.Group>
<Form.Group className="mb-3" controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
placeholder="Password"
name="password"
value={values.password}
onChange={handleChange}
/>
</Form.Group>
<Form.Group className="mb-3" controlId="confirmPassword">
<Form.Label>confirm Password</Form.Label>
<Form.Control
type="password"
placeholder="confirm password"
name="confirmpassword"
value={values.confirmpassword}
onChange={handleChange}
/>
</Form.Group>
<Form.Group controlId="formFile" className="mb-3">
<Form.Label>upload profile picture</Form.Label>
<Form.Control type="file" />
</Form.Group>

<Button variant="primary" type="submit">
Register
</Button>
</Form>
</div>
<Button variant="primary" type="submit" disabled={loading}>
Register
</Button>
</Form>
</div>
</MainScreen>
)
}
);
};

export default RegisterPage
export default RegisterPage;
Loading