diff --git a/client/package-lock.json b/client/package-lock.json
index f7bb226f..ab169765 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -24,7 +24,9 @@
"react-dom": "^18.2.0",
"react-router-dom": "^6.17.0",
"react-scripts": "5.0.1",
- "typescript": "^5.2.2",
+ "react-toastify": "^9.1.3",
+ "toastify-js": "^1.12.0",
+ "typescript": "^4.9.5",
"web-vitals": "^2.1.4"
}
},
@@ -15338,6 +15340,26 @@
}
}
},
+ "node_modules/react-toastify": {
+ "version": "9.1.3",
+ "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz",
+ "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==",
+ "dependencies": {
+ "clsx": "^1.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16",
+ "react-dom": ">=16"
+ }
+ },
+ "node_modules/react-toastify/node_modules/clsx": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
+ "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
@@ -17041,6 +17063,11 @@
"node": ">=8.0"
}
},
+ "node_modules/toastify-js": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.12.0.tgz",
+ "integrity": "sha512-HeMHCO9yLPvP9k0apGSdPUWrUbLnxUKNFzgUoZp1PHCLploIX/4DSQ7V8H25ef+h4iO9n0he7ImfcndnN6nDrQ=="
+ },
"node_modules/toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@@ -17258,15 +17285,15 @@
}
},
"node_modules/typescript": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
- "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
+ "version": "4.9.5",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
- "node": ">=14.17"
+ "node": ">=4.2.0"
}
},
"node_modules/unbox-primitive": {
@@ -29187,6 +29214,21 @@
"workbox-webpack-plugin": "^6.4.1"
}
},
+ "react-toastify": {
+ "version": "9.1.3",
+ "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.1.3.tgz",
+ "integrity": "sha512-fPfb8ghtn/XMxw3LkxQBk3IyagNpF/LIKjOBflbexr2AWxAH1MJgvnESwEwBn9liLFXgTKWgBSdZpw9m4OTHTg==",
+ "requires": {
+ "clsx": "^1.1.1"
+ },
+ "dependencies": {
+ "clsx": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
+ "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg=="
+ }
+ }
+ },
"react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
@@ -30440,6 +30482,11 @@
"is-number": "^7.0.0"
}
},
+ "toastify-js": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.12.0.tgz",
+ "integrity": "sha512-HeMHCO9yLPvP9k0apGSdPUWrUbLnxUKNFzgUoZp1PHCLploIX/4DSQ7V8H25ef+h4iO9n0he7ImfcndnN6nDrQ=="
+ },
"toidentifier": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@@ -30606,9 +30653,9 @@
}
},
"typescript": {
- "version": "5.2.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
- "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w=="
+ "version": "4.9.5",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+ "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g=="
},
"unbox-primitive": {
"version": "1.0.2",
diff --git a/client/package.json b/client/package.json
index de12ca33..0dba8c8b 100644
--- a/client/package.json
+++ b/client/package.json
@@ -19,7 +19,9 @@
"react-dom": "^18.2.0",
"react-router-dom": "^6.17.0",
"react-scripts": "5.0.1",
- "typescript": "^5.2.2",
+ "react-toastify": "^9.1.3",
+ "toastify-js": "^1.12.0",
+ "typescript": "^4.9.5",
"web-vitals": "^2.1.4"
},
"scripts": {
diff --git a/client/src/App.tsx b/client/src/App.tsx
index 06874267..dc00a55b 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -7,14 +7,34 @@ import Login from "./components/authentication/Login";
import SignUp from "./components/authentication/SignUp";
import "./App.css";
+import { ToastContainer } from "react-toastify";
+import { getToken } from "./utils/localStorageUtils";
const App = () => {
+ // TODO: Find a way to validate token
+ // TODO: use userToken to restrict access for not logged in status
+ const userToken = getToken();
+
return (
-
- } />
- } />
- } />
-
+ <>
+
+
+ } />
+ } />
+ } />
+
+ >
);
};
diff --git a/client/src/components/authentication/Login.tsx b/client/src/components/authentication/Login.tsx
index 51119fa6..147f3ac0 100644
--- a/client/src/components/authentication/Login.tsx
+++ b/client/src/components/authentication/Login.tsx
@@ -1,4 +1,4 @@
-import React, { FormEvent } from "react";
+import React, { FormEvent, useState } from "react";
import Button from "@mui/material/Button";
import CssBaseline from "@mui/material/CssBaseline";
@@ -8,8 +8,42 @@ import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import Container from "@mui/material/Container";
+import { toast } from "react-toastify";
+import { useNavigate } from "react-router-dom";
+import axios from "axios";
+
+import { storeToken } from "../../utils/localStorageUtils";
+
const Login = () => {
+ const navigate = useNavigate();
+ const [formData, setFormData] = useState({
+ username: "",
+ password: "",
+ });
+
const handleSubmit = (e: FormEvent) => {
+ e.preventDefault();
+
+ const requestUrl = "http://127.0.0.1:8000/socialdistribution/login/";
+
+ const form = new FormData();
+ form.append("username", formData.username);
+ form.append("password", formData.password);
+
+ axios
+ .post(requestUrl, form, {
+ headers: { "Content-Type": "multipart/form-data" },
+ })
+ .then((response: any) => {
+ storeToken(response.data.token);
+
+ toast.success("You are now logged in");
+
+ navigate("/home-page");
+ })
+ .catch((error) => {
+ toast.error("Wrong password or user does not exist");
+ });
return;
};
@@ -18,7 +52,6 @@ const Login = () => {
{
margin="normal"
required
fullWidth
- id="email"
- label="Email"
- name="email"
- autoComplete="email"
+ id="username"
+ label="Username"
+ name="username"
+ autoComplete="username"
autoFocus
+ onChange={(e) => {
+ setFormData({ ...formData, username: e.target.value });
+ }}
/>
{
label="Password"
type="password"
id="password"
+ onChange={(e) => {
+ setFormData({ ...formData, password: e.target.value });
+ }}
/>