diff --git a/client/package-lock.json b/client/package-lock.json index de9ab9f..6725543 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -30,6 +30,7 @@ "lucide-react": "^0.447.0", "match-sorter": "^6.3.4", "mdb-react-ui-kit": "^7.2.0", + "open-source": "file:", "otp-input-react": "^0.3.0", "prop-types": "^15.8.1", "react": "^18.2.0", @@ -45,7 +46,8 @@ "react-top-loading-bar": "^2.3.1", "socket.io": "^4.7.5", "socket.io-client": "^4.7.5", - "sort-by": "^1.2.0" + "sort-by": "^1.2.0", + "yup": "^1.4.0" }, "devDependencies": { "@types/react": "^18.2.55", @@ -6083,6 +6085,10 @@ "wrappy": "1" } }, + "node_modules/open-source": { + "resolved": "", + "link": true + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -6521,6 +6527,12 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "license": "MIT" }, + "node_modules/property-expr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz", + "integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==", + "license": "MIT" + }, "node_modules/protobufjs": { "version": "7.4.0", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", @@ -7650,6 +7662,12 @@ "node": ">=0.8" } }, + "node_modules/tiny-case": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz", + "integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==", + "license": "MIT" + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -7672,6 +7690,12 @@ "node": ">=8.0" } }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "license": "MIT" + }, "node_modules/ts-interface-checker": { "version": "0.1.13", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", @@ -8301,6 +8325,30 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/yup": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/yup/-/yup-1.4.0.tgz", + "integrity": "sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==", + "license": "MIT", + "dependencies": { + "property-expr": "^2.0.5", + "tiny-case": "^1.0.3", + "toposort": "^2.0.2", + "type-fest": "^2.19.0" + } + }, + "node_modules/yup/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/client/package.json b/client/package.json index 2682ea4..5a86c71 100644 --- a/client/package.json +++ b/client/package.json @@ -32,6 +32,7 @@ "lucide-react": "^0.447.0", "match-sorter": "^6.3.4", "mdb-react-ui-kit": "^7.2.0", + "open-source": "file:", "otp-input-react": "^0.3.0", "prop-types": "^15.8.1", "react": "^18.2.0", @@ -47,7 +48,8 @@ "react-top-loading-bar": "^2.3.1", "socket.io": "^4.7.5", "socket.io-client": "^4.7.5", - "sort-by": "^1.2.0" + "sort-by": "^1.2.0", + "yup": "^1.4.0" }, "devDependencies": { "@types/react": "^18.2.55", diff --git a/client/src/component/Login.jsx b/client/src/component/Login.jsx index 7efca1f..569a7c1 100644 --- a/client/src/component/Login.jsx +++ b/client/src/component/Login.jsx @@ -1,40 +1,61 @@ -import PropTypes from 'prop-types'; -import { useState } from 'react'; -import { useNavigate } from 'react-router-dom'; -import { Link } from 'react-router-dom'; +import PropTypes from "prop-types"; +import { useState } from "react"; +import { useNavigate } from "react-router-dom"; +import { Link } from "react-router-dom"; // import './css/Auth.css'; -import './css/Login.css' +import "./css/Login.css"; +import { loginValidation } from "../validations/validation"; const host = "http://localhost:5000"; const Login = (props) => { - const [credentials, setCredentials] = useState({ email: "", password: "" }); + // const [credentials, setCredentials] = useState({ email: "", password: "" }); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [errors, setErrors] = useState({}); let navigate = useNavigate(); const handleSubmit = async (e) => { - // To not Reload after click submit + // To not Reload after click submit e.preventDefault(); + + try { + await loginValidation.validate( + { email, password }, + { abortEarly: false } + ); + setErrors({}); + } catch (error) { + const newErrors = {}; + error.inner.forEach((err) => { + newErrors[err.path] = err.message; + // newErrors[err.path] = err.errors[0]; + }); + + setErrors(newErrors); + return; + } + const response = await fetch(`${host}/api/auth/login`, { method: "POST", headers: { "Content-Type": "application/json", }, - body: JSON.stringify({ email: credentials.email, password: credentials.password }), + body: JSON.stringify({ email: email, password: password }), }); const json = await response.json(); console.log(json); if (json.success) { // Save the auth token and redirect - localStorage.setItem('token', json.authtoken); - props.showAlert("Logged in Successfully", "success") + localStorage.setItem("token", json.authtoken); + props.showAlert("Logged in Successfully", "success"); navigate("/"); + } else { + props.showAlert("Invalid Credentials", "danger"); } - else { - props.showAlert("Invalid Credentials", "danger") - } - } + }; const onChange = (e) => { - setCredentials({ ...credentials, [e.target.name]: e.target.value }) - } + setCredentials({ ...credentials, [e.target.name]: e.target.value }); + }; // return ( //
+ Please Sign In here
+
+ with your some
+
+ -- real info
+
diff --git a/client/src/component/css/Login.css b/client/src/component/css/Login.css index aa75a19..2fc7699 100644 --- a/client/src/component/css/Login.css +++ b/client/src/component/css/Login.css @@ -6,7 +6,7 @@ } body{ width: 100vw; - height: 100vh; + /* height: 100vh; */ background:white; display: grid; justify-content: center; @@ -20,7 +20,7 @@ body{ .wrapper{ position: relative; width: 100vw; - height: 100vh; + /* height: 100vh; */ display: grid; grid-template-columns: 1fr 1fr; } @@ -31,6 +31,7 @@ body{ align-items: center; } .title{ + margin-top: 50px; font-size: 4rem; color:#6366F1 ; font-weight:bolder; diff --git a/client/src/validations/validation.js b/client/src/validations/validation.js new file mode 100644 index 0000000..8c0b6a7 --- /dev/null +++ b/client/src/validations/validation.js @@ -0,0 +1,25 @@ +import * as yup from "yup"; + +export const loginValidation = yup.object().shape({ + email: yup + .string() + .email("Email format invalid") + .required("Email is required"), + password: yup.string().required("Password is required"), +}); + +export const registerValidation = yup.object().shape({ + name: yup.string().required("Name is required"), + email: yup + .string() + .email("Invalid email format") + .required("Email is required"), + password: yup + .string() + .min(6, "Password should be at least 6 characters") + .required("Password is required"), + cpassword: yup + .string() + .oneOf([yup.ref('password'), null], "Passwords must match") + .required("Confirm password is required"), + }); diff --git a/server/package-lock.json b/server/package-lock.json index 51a3571..88ea952 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -22,6 +22,7 @@ "mongoose": "^8.7.0", "multer": "^1.4.5-lts.1", "nodemailer": "^6.9.15", + "opensource-backend": "file:", "socket.io": "^4.7.5" }, "devDependencies": { @@ -2830,6 +2831,10 @@ "wrappy": "1" } }, + "node_modules/opensource-backend": { + "resolved": "", + "link": true + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", diff --git a/server/package.json b/server/package.json index 3bda82e..8155ba3 100644 --- a/server/package.json +++ b/server/package.json @@ -27,6 +27,7 @@ "mongoose": "^8.7.0", "multer": "^1.4.5-lts.1", "nodemailer": "^6.9.15", + "opensource-backend": "file:", "socket.io": "^4.7.5" }, "devDependencies": {