diff --git a/package-lock.json b/package-lock.json
index 26e3ebf..82c4f4b 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
"@testing-library/user-event": "^13.5.0",
"axios": "^1.3.5",
"formik": "^2.2.9",
+ "jsonwebtoken": "^9.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.0",
@@ -5562,6 +5563,11 @@
"node-int64": "^0.4.0"
}
},
+ "node_modules/buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
+ },
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -6792,6 +6798,14 @@
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz",
"integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg=="
},
+ "node_modules/ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -11726,6 +11740,21 @@
"node": ">=0.10.0"
}
},
+ "node_modules/jsonwebtoken": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
+ "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
+ "dependencies": {
+ "jws": "^3.2.2",
+ "lodash": "^4.17.21",
+ "ms": "^2.1.1",
+ "semver": "^7.3.8"
+ },
+ "engines": {
+ "node": ">=12",
+ "npm": ">=6"
+ }
+ },
"node_modules/jsx-ast-utils": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz",
@@ -11738,6 +11767,25 @@
"node": ">=4.0"
}
},
+ "node_modules/jwa": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+ "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+ "dependencies": {
+ "buffer-equal-constant-time": "1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "node_modules/jws": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+ "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+ "dependencies": {
+ "jwa": "^1.4.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
"node_modules/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
diff --git a/package.json b/package.json
index ee9ac18..0fdb170 100644
--- a/package.json
+++ b/package.json
@@ -8,6 +8,7 @@
"@testing-library/user-event": "^13.5.0",
"axios": "^1.3.5",
"formik": "^2.2.9",
+ "jsonwebtoken": "^9.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hot-toast": "^2.4.0",
diff --git a/src/App.js b/src/App.js
index 6b7386c..a7afb32 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,18 +1,26 @@
import { HomePage, PostForm, NotFoundPage } from "./pages/index";
-import { Routes, Route } from "react-router-dom";
+import { Routes, Route, Navigate } from "react-router-dom";
import { PostProvider } from "./context/postContext";
import { Toaster } from "react-hot-toast";
+import Signup from './components/signup';
+import Login from './components/Login';
+
function App() {
+
+ const user = localStorage.getItem("token")
return (
- } />
+ {user && }/>}
+ }/>
+ }/>
} />
} />
} />
+ }/>
diff --git a/src/components/Login/index.jsx b/src/components/Login/index.jsx
new file mode 100644
index 0000000..ae02cbc
--- /dev/null
+++ b/src/components/Login/index.jsx
@@ -0,0 +1,85 @@
+import { useState } from "react";
+import styles from "./styles.module.css";
+import { Link } from "react-router-dom";
+import axios from 'axios'
+
+const Signup = () => {
+ const [data, setData] = useState({
+ email: "",
+ password: "",
+ });
+
+
+ const [error, setError] = useState("")
+
+ const handleChange = ({ currentTarget: input }) => {
+ setData({ ...data, [input.name]: input.value });
+ };
+
+ const handleSubmit =async (e) => {
+ e.preventDefault();
+ try {
+ const url = "http://localhost:4000/api/auth/signin";
+ const {data:res} = await axios.post(url,data);
+ localStorage.setItem("token", res.data);
+ window.location= "/"
+ } catch (error) {
+ if(error.response &&
+ error.response.status >=400 &&
+ error.response.status <=500
+ ){
+ setError(error.response.data.message)
+ }
+
+ }
+
+ }
+
+ return (
+
+
+
+
+
+
New Here?
+
+
+
+
+
+
+
+
+
+ );
+};
+
+export default Signup;
\ No newline at end of file
diff --git a/src/components/Login/styles.module.css b/src/components/Login/styles.module.css
new file mode 100644
index 0000000..c1a1ff1
--- /dev/null
+++ b/src/components/Login/styles.module.css
@@ -0,0 +1,98 @@
+.login_container {
+ width: 100%;
+ min-height: 100vh;
+ background-color: #f5f5f5;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.login_form_container {
+ width: 900px;
+ height: 500px;
+ display: flex;
+ border-radius: 10px;
+ box-shadow: 0px 3px 3px -2px rgb(0 0 0 / 20%),
+ 0px 3px 4px 0px rgb(0 0 0 / 14%), 0px 1px 8px 0px rgb(0 0 0 / 12%);
+}
+
+.left {
+ flex: 2;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background-color: white;
+ border-top-left-radius: 10px;
+ border-bottom-left-radius: 10px;
+}
+
+.form_container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.form_container h1 {
+ font-size: 40px;
+ margin-top: 0;
+}
+
+.input {
+ outline: none;
+ border: none;
+ width: 370px;
+ padding: 15px;
+ border-radius: 10px;
+ background-color: #edf5f3;
+ margin: 5px 0;
+ font-size: 14px;
+}
+
+.error_msg {
+ width: 370px;
+ padding: 15px;
+ margin: 5px 0;
+ font-size: 14px;
+ background-color: #f34646;
+ color: white;
+ border-radius: 5px;
+ text-align: center;
+}
+
+.right {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background-color: #3bb19b;
+ border-top-right-radius: 10px;
+ border-bottom-right-radius: 10px;
+}
+
+.right h1 {
+ margin-top: 0;
+ color: white;
+ font-size: 40px;
+ align-self: center;
+}
+
+.white_btn,
+.green_btn {
+ border: none;
+ outline: none;
+ padding: 12px 0;
+ background-color: white;
+ border-radius: 20px;
+ width: 180px;
+ font-weight: bold;
+ font-size: 14px;
+ cursor: pointer;
+}
+
+.green_btn {
+ background-color: #3bb19b;
+ color: white;
+ margin: 10px;
+}
\ No newline at end of file
diff --git a/src/components/Main/index.jsx b/src/components/Main/index.jsx
new file mode 100644
index 0000000..113a2a4
--- /dev/null
+++ b/src/components/Main/index.jsx
@@ -0,0 +1,24 @@
+import styles from './style.module.css';
+
+
+const Main = () =>{
+
+ const handleLogout = ()=> {
+ localStorage.removeItem("token");
+ window.location.reload();
+}
+
+return(
+
+
+
+);
+
+
+};
+export default Main;
\ No newline at end of file
diff --git a/src/components/Main/style.module.css b/src/components/Main/style.module.css
new file mode 100644
index 0000000..3cb8dac
--- /dev/null
+++ b/src/components/Main/style.module.css
@@ -0,0 +1,27 @@
+.navbar {
+ width: 100%;
+ height: 70px;
+ background-color: #3bb19b;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+
+.navbar h1 {
+ color: white;
+ font-size: 25px;
+ margin-left: 20px;
+}
+
+.white_btn {
+ border: none;
+ outline: none;
+ padding: 12px 0;
+ background-color: white;
+ border-radius: 20px;
+ width: 120px;
+ font-weight: bold;
+ font-size: 14px;
+ cursor: pointer;
+ margin-right: 20px;
+}
\ No newline at end of file
diff --git a/src/components/signup/index.jsx b/src/components/signup/index.jsx
new file mode 100644
index 0000000..e2924b8
--- /dev/null
+++ b/src/components/signup/index.jsx
@@ -0,0 +1,93 @@
+import { useState } from "react";
+import styles from "./styles.module.css";
+import { Link, useNavigate } from "react-router-dom";
+import axios from 'axios'
+
+const Signup = () => {
+ const [data, setData] = useState({
+ username: "",
+ email: "",
+ password: "",
+ });
+ const [error, setError] = useState("")
+ const navigate= useNavigate();
+
+ const handleChange = ({ currentTarget: input }) => {
+ setData({ ...data, [input.name]: input.value });
+ };
+
+ const handleSubmit =async (e) => {
+ e.preventDefault();
+ try {
+ const url = "http://localhost:4000/api/auth/signup";
+ const {data:res} = await axios.post(url,data);
+ navigate("/login")
+ console.log(res.message)
+ } catch (error) {
+ if(error.response &&
+ error.response.status >=400 &&
+ error.response.status <=500
+ ){
+ setError(error.response.data.message)
+ }
+
+ }
+
+ }
+
+ return (
+
+
+
+
Welcome Back
+
+
+
+
+
+
+
+ );
+};
+
+export default Signup;
diff --git a/src/components/signup/styles.module.css b/src/components/signup/styles.module.css
new file mode 100644
index 0000000..15c6aa7
--- /dev/null
+++ b/src/components/signup/styles.module.css
@@ -0,0 +1,98 @@
+.signup_container {
+ width: 100%;
+ min-height: 100vh;
+ background-color: #f5f5f5;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+.signup_form_container {
+ width: 900px;
+ height: 500px;
+ display: flex;
+ border-radius: 10px;
+ box-shadow: 0px 3px 3px -2px rgb(0 0 0 / 20%),
+ 0px 3px 4px 0px rgb(0 0 0 / 14%), 0px 1px 8px 0px rgb(0 0 0 / 12%);
+}
+
+.left {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background-color: #3bb19b;
+ border-top-left-radius: 10px;
+ border-bottom-left-radius: 10px;
+}
+
+.left h1 {
+ margin-top: 0;
+ color: white;
+ font-size: 35px;
+ align-self: center;
+}
+
+.right {
+ flex: 2;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background-color: white;
+ border-top-right-radius: 10px;
+ border-bottom-right-radius: 10px;
+}
+
+.form_container {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.form_container h1 {
+ font-size: 40px;
+ margin-top: 0;
+}
+
+.input {
+ outline: none;
+ border: none;
+ width: 370px;
+ padding: 15px;
+ border-radius: 10px;
+ background-color: #edf5f3;
+ margin: 5px 0;
+ font-size: 14px;
+}
+
+.error_msg {
+ width: 370px;
+ padding: 15px;
+ margin: 5px 0;
+ font-size: 14px;
+ background-color: #f34646;
+ color: white;
+ border-radius: 5px;
+ text-align: center;
+}
+
+.white_btn,
+.green_btn {
+ border: none;
+ outline: none;
+ padding: 12px 0;
+ background-color: rgb(102, 115, 212);
+ border-radius: 20px;
+ width: 180px;
+ font-weight: bold;
+ font-size: 14px;
+ cursor: pointer;
+}
+
+.green_btn {
+ background-color: #3bb19b;
+ color: white;
+ margin: 10px;
+}
\ No newline at end of file
diff --git a/src/pages/HomePage.js b/src/pages/HomePage.js
index c343023..0ed75f4 100644
--- a/src/pages/HomePage.js
+++ b/src/pages/HomePage.js
@@ -2,7 +2,12 @@ import { usePosts } from "../context/postContext";
import {VscEmptyWindow} from 'react-icons/vsc'
import { Link } from "react-router-dom";
import { PostCard } from "../components/PostCard";
+
export function HomePage() {
+ const handleLogout = ()=> {
+ localStorage.removeItem("token");
+ window.location.reload();
+}
const { posts } = usePosts()
@@ -15,13 +20,19 @@ export function HomePage() {
return (
-
+
+
Post ({posts.length})
Create new Post
-