diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 419a1f1..9e9afa8 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,6 +14,7 @@ "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", + "react-icons": "^4.12.0", "react-markdown": "^8.0.7", "react-redux": "^8.0.5", "react-router-dom": "^6.8.1", @@ -21,8 +22,8 @@ "remark-gfm": "^3.0.0" }, "devDependencies": { - "@types/react": "^18.0.27", - "@types/react-dom": "^18.0.10", + "@types/react": "^18.2.38", + "@types/react-dom": "^18.2.17", "@types/react-syntax-highlighter": "^15.5.6", "@typescript-eslint/eslint-plugin": "^5.51.0", "@typescript-eslint/parser": "^5.51.0", @@ -1255,9 +1256,9 @@ "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/react": { - "version": "18.0.27", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", - "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", + "version": "18.2.38", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.38.tgz", + "integrity": "sha512-cBBXHzuPtQK6wNthuVMV6IjHAFkdl/FOPFIlkd81/Cd1+IqkHu/A+w4g43kaQQoYHik/ruaQBDL72HyCy1vuMw==", "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -1265,9 +1266,9 @@ } }, "node_modules/@types/react-dom": { - "version": "18.0.10", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz", - "integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==", + "version": "18.2.17", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz", + "integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==", "devOptional": true, "dependencies": { "@types/react": "*" @@ -6411,6 +6412,14 @@ "react": ">= 16.8 || 18.0.0" } }, + "node_modules/react-icons": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", + "integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", + "peerDependencies": { + "react": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index bb7b6db..c43abf6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -25,6 +25,7 @@ "react-copy-to-clipboard": "^5.1.0", "react-dom": "^18.2.0", "react-dropzone": "^14.2.3", + "react-icons": "^4.12.0", "react-markdown": "^8.0.7", "react-redux": "^8.0.5", "react-router-dom": "^6.8.1", @@ -32,8 +33,8 @@ "remark-gfm": "^3.0.0" }, "devDependencies": { - "@types/react": "^18.0.27", - "@types/react-dom": "^18.0.10", + "@types/react": "^18.2.38", + "@types/react-dom": "^18.2.17", "@types/react-syntax-highlighter": "^15.5.6", "@typescript-eslint/eslint-plugin": "^5.51.0", "@typescript-eslint/parser": "^5.51.0", diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index fdf86dd..05362c6 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,7 +1,12 @@ -import { Routes, Route } from 'react-router-dom'; +import { Routes, Route, useLocation } from 'react-router-dom'; import Navigation from './Navigation'; import Conversation from './conversation/Conversation'; import About from './About'; +import Login from './Login/Login'; +import Signup from './Login/Signup'; +import ResetCode from './Login/ResetCode'; +import ForgotPass from './Login/ForgotPass'; + import PageNotFound from './PageNotFound'; import { inject } from '@vercel/analytics'; import { useMediaQuery } from './hooks'; @@ -13,20 +18,32 @@ inject(); export default function App() { const { isMobile } = useMediaQuery(); const [navOpen, setNavOpen] = useState(!isMobile); + const location = useLocation(); + + // Checking for the login page + const isLogin = + location.pathname === '/login' || + location.pathname === '/register' || + location.pathname === '/Forgot' || + location.pathname === '/ResetPassword'; return (
- + {!isLogin && }
} /> } /> + } /> + } /> + } /> + } /> } /> } /> diff --git a/frontend/src/Hero.tsx b/frontend/src/Hero.tsx index cb55ca1..97ee5c3 100644 --- a/frontend/src/Hero.tsx +++ b/frontend/src/Hero.tsx @@ -1,8 +1,10 @@ import { useMediaQuery } from './hooks'; import DocsGPT3 from './assets/cute_docsgpt3.svg'; +import { useNavigate } from 'react-router-dom'; export default function Hero({ className = '' }: { className?: string }) { // const isMobile = window.innerWidth <= 768; + const navigate = useNavigate(); const { isMobile } = useMediaQuery(); return (
diff --git a/frontend/src/Login/ForgotPass.tsx b/frontend/src/Login/ForgotPass.tsx new file mode 100644 index 0000000..486a550 --- /dev/null +++ b/frontend/src/Login/ForgotPass.tsx @@ -0,0 +1,66 @@ +import React from 'react'; +import DocsGPT3 from '../assets/cute_docsgpt3.svg'; +import { useNavigate } from 'react-router-dom'; +export default function ForgotPass() { + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + console.log('login'); + }; + + const navigate = useNavigate(); + + return ( +
+
+
navigate('/')}> + Logo +
+
+

Log in to

+

+ DocsGPT +

+
+
+
+

Password reset

+

+ Enter the email address associated with your account and we will + send you a link to reset your password. +

+
+ + + +
+
+

+ Don't have an account? +

navigate('/register')} + > + Sign up +

+ +
+
+
+ ); +} diff --git a/frontend/src/Login/Login.tsx b/frontend/src/Login/Login.tsx new file mode 100644 index 0000000..5d036f6 --- /dev/null +++ b/frontend/src/Login/Login.tsx @@ -0,0 +1,173 @@ +import React, { useState, useEffect } from 'react'; +import DocsGPT3 from '../assets/cute_docsgpt3.svg'; +import { useNavigate } from 'react-router-dom'; +import { IoEye } from 'react-icons/io5'; +import { IoMdEyeOff } from 'react-icons/io'; +export default function Login() { + const [showalert, setshowalert] = useState(''); + const [email, setemail] = useState(''); + const [password, setpassword] = useState(''); + const [isVisible, setisVisible] = useState(false); + const [ispasswordVisible, setispasswordVisible] = useState(false); + + const handleSubmit = () => { + //email validation + if (email.length === 0 || password.length === 0) { + if (password.length === 0) { + setshowalert('Password is required'); + return; + } else { + setshowalert('Email is required'); + } + return; + } else { + setshowalert(''); + } + if (password.length === 0) { + setshowalert('Password is required'); + return; + } + + // const response = await fetch(`http://localhost:5000/api/auth/login`, { + // method: "POST", + // headers: { + // "Content-Type": "application/json", + // }, + // body: JSON.stringify({ + // Email: user.Email, + // Password: user.Password, + // }), + // }); + // const json = await response.json(); + // console.log(json); + // if (json.Check) { + // localStorage.setItem("token", json.authtoken); + // if (json?.status) + // { + // localStorage.setItem("isadmin" , true); + // } + // navigate("/"); + // } + // else if (!json.Check) + // { + // alert("Invalid Login Credentials") + // console.log("Invalid Login Cred") + // } + + alert('Login Successful '); + + navigate('/'); + }; + + const navigate = useNavigate(); + + // Toogle Password + + const togglePassword = () => { + setispasswordVisible(!ispasswordVisible); + + const el = document.getElementById('password') as HTMLInputElement; + if (el.type === 'password') { + el.type = 'text'; + } else { + el.type = 'password'; + } + }; + + useEffect(() => { + if (password) { + setisVisible(true); + } else { + setisVisible(false); + } + }, [password]); + + return ( +
+
+
navigate('/')}> + Logo +
+
+

+ Log in to +

+

+ DocsGPT +

+
+
+ { + setemail(e.target.value); + }} + className="w-[90vw] cursor-pointer rounded-lg border-red-400 bg-[#2B2B2B] p-4 text-sm font-medium text-white hover:bg-[#383838] focus:border-2 focus:border-[#715c9d] focus:outline-none md:w-full md:min-w-[25vw]" + // onChange={onchange} + /> +
+ { + setpassword(e.target.value); + }} + className="w-[90vw] cursor-pointer rounded-lg border-red-400 bg-[#2B2B2B] p-4 text-sm font-medium text-white hover:bg-[#383838] focus:border-2 focus:border-[#715c9d] focus:outline-none md:w-full md:min-w-[25vw]" + // onChange={onchange} + /> + {isVisible && + (!ispasswordVisible ? ( + + ) : ( + + ))} +
+ +

navigate('/Forgot')} + > + Forgot your password? +

+ + {showalert.length > 0 && ( +
{showalert}
+ )} +
+

+ Don't have an account? +

navigate('/register')} + > + Sign up +

+ +
+
+
+
+ ); +} diff --git a/frontend/src/Login/ResetCode.tsx b/frontend/src/Login/ResetCode.tsx new file mode 100644 index 0000000..f69f5a8 --- /dev/null +++ b/frontend/src/Login/ResetCode.tsx @@ -0,0 +1,63 @@ +import React from 'react'; +import DocsGPT3 from '../assets/cute_docsgpt3.svg'; +import { useNavigate } from 'react-router-dom'; +export default function ResetCode() { + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + console.log('login'); + }; + + const navigate = useNavigate(); + return ( +
+
+
navigate('/')}> + Logo +
+
+

Log in to

+

+ DocsGPT +

+
+
+
+

+ We've sent you instructions to reset your password. Please + check your inbox. +

+

+ If you haven't received an email in 5 minutes, check your + spam, resend, or try a different email. +

+
+ + + +
+
+

+ Don't have an account? +

navigate('/register')} + > + Sign up +

+ +
+
+
+ ); +} diff --git a/frontend/src/Login/Signup.tsx b/frontend/src/Login/Signup.tsx new file mode 100644 index 0000000..fde032b --- /dev/null +++ b/frontend/src/Login/Signup.tsx @@ -0,0 +1,137 @@ +import React, { useState, useEffect } from 'react'; +import DocsGPT3 from '../assets/cute_docsgpt3.svg'; +import { IoEye } from 'react-icons/io5'; +import { IoMdEyeOff } from 'react-icons/io'; +import { useNavigate } from 'react-router-dom'; + +export default function Signup() { + const [showalert, setshowalert] = useState(''); + const [email, setemail] = useState(''); + const [password, setpassword] = useState(''); + const [isVisible, setisVisible] = useState(false); + const [ispasswordVisible, setispasswordVisible] = useState(false); + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + + if (email.length === 0 || password.length === 0) { + setshowalert('Both fields are required'); + return; + } + + //email validation + if (!email.match(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/)) { + setshowalert('Please enter a valid email address'); + return; + } + + setshowalert(''); + alert('Signup Successful '); + + navigate('/login'); + }; + + const navigate = useNavigate(); + + // Toogle Password + + const togglePassword = () => { + setispasswordVisible(!ispasswordVisible); + + const el = document.getElementById('password') as HTMLInputElement; + if (el.type === 'password') { + el.type = 'text'; + } else { + el.type = 'password'; + } + }; + + useEffect(() => { + if (password) { + setisVisible(true); + } else { + setisVisible(false); + } + }, [password]); + + return ( +
+
+
navigate('/')}> + Logo +
+
+

Create

+

+ DocsGPT +

+

+ Account +

+
+
+ { + setemail(e.target.value); + }} + className="w-[90vw] cursor-pointer rounded-lg border-red-400 bg-[#2B2B2B] p-4 text-sm font-medium text-white hover:bg-[#383838] focus:border-2 focus:border-[#715c9d] focus:outline-none md:w-full md:min-w-[25vw]" + /> +
+ { + setpassword(e.target.value); + }} + className="w-[90vw] cursor-pointer rounded-lg border-red-400 bg-[#2B2B2B] p-4 text-sm font-medium text-white hover:bg-[#383838] focus:border-2 focus:border-[#715c9d] focus:outline-none md:w-full md:min-w-[25vw]" + // onChange={onchange} + /> + {isVisible && + (!ispasswordVisible ? ( + + ) : ( + + ))} +
+ + {showalert.length > 0 && ( +
{showalert}
+ )} +
+

+ Already have an account? +

navigate('/login')} + > + Log in +

+ +
+
+
+
+ ); +} diff --git a/frontend/src/conversation/Conversation.tsx b/frontend/src/conversation/Conversation.tsx index fcef240..c797d65 100644 --- a/frontend/src/conversation/Conversation.tsx +++ b/frontend/src/conversation/Conversation.tsx @@ -1,6 +1,7 @@ import { Fragment, useEffect, useRef, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import Hero from '../Hero'; +import { useNavigate } from 'react-router-dom'; import { AppDispatch } from '../store'; import ConversationBubble from './ConversationBubble'; import { @@ -115,6 +116,8 @@ export default function Conversation() { document.execCommand('insertText', false, text); }; + const navigate = useNavigate(); + return (
{queries.length > 0 && !hasScrolledToLast && ( @@ -133,7 +136,7 @@ export default function Conversation() { {queries.length > 0 && (
- {queries.map((query, index) => { + {queries.map((query: Query, index: number) => { return ( )} +
+
+ + +
)}
+

This is a chatbot that uses the GPT-3, Faiss and LangChain to answer questions.