mirror of
https://github.com/arc53/DocsGPT.git
synced 2025-11-29 00:23:17 +00:00
Merge pull request #799 from Hemant2335/Demo
Creating a Seprate Page for Signup and Signin
This commit is contained in:
25
frontend/package-lock.json
generated
25
frontend/package-lock.json
generated
@@ -14,6 +14,7 @@
|
|||||||
"react-copy-to-clipboard": "^5.1.0",
|
"react-copy-to-clipboard": "^5.1.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-dropzone": "^14.2.3",
|
"react-dropzone": "^14.2.3",
|
||||||
|
"react-icons": "^4.12.0",
|
||||||
"react-markdown": "^8.0.7",
|
"react-markdown": "^8.0.7",
|
||||||
"react-redux": "^8.0.5",
|
"react-redux": "^8.0.5",
|
||||||
"react-router-dom": "^6.8.1",
|
"react-router-dom": "^6.8.1",
|
||||||
@@ -21,8 +22,8 @@
|
|||||||
"remark-gfm": "^3.0.0"
|
"remark-gfm": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.0.27",
|
"@types/react": "^18.2.38",
|
||||||
"@types/react-dom": "^18.0.10",
|
"@types/react-dom": "^18.2.17",
|
||||||
"@types/react-syntax-highlighter": "^15.5.6",
|
"@types/react-syntax-highlighter": "^15.5.6",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.51.0",
|
"@typescript-eslint/eslint-plugin": "^5.51.0",
|
||||||
"@typescript-eslint/parser": "^5.51.0",
|
"@typescript-eslint/parser": "^5.51.0",
|
||||||
@@ -1255,9 +1256,9 @@
|
|||||||
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
|
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "18.0.27",
|
"version": "18.2.38",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.38.tgz",
|
||||||
"integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==",
|
"integrity": "sha512-cBBXHzuPtQK6wNthuVMV6IjHAFkdl/FOPFIlkd81/Cd1+IqkHu/A+w4g43kaQQoYHik/ruaQBDL72HyCy1vuMw==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
"@types/scheduler": "*",
|
"@types/scheduler": "*",
|
||||||
@@ -1265,9 +1266,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/react-dom": {
|
"node_modules/@types/react-dom": {
|
||||||
"version": "18.0.10",
|
"version": "18.2.17",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.17.tgz",
|
||||||
"integrity": "sha512-E42GW/JA4Qv15wQdqJq8DL4JhNpB3prJgjgapN3qJT9K2zO5IIAQh4VXvCEDupoqAwnz0cY4RlXeC/ajX5SFHg==",
|
"integrity": "sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg==",
|
||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
@@ -6411,6 +6412,14 @@
|
|||||||
"react": ">= 16.8 || 18.0.0"
|
"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": {
|
"node_modules/react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
"react-copy-to-clipboard": "^5.1.0",
|
"react-copy-to-clipboard": "^5.1.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-dropzone": "^14.2.3",
|
"react-dropzone": "^14.2.3",
|
||||||
|
"react-icons": "^4.12.0",
|
||||||
"react-markdown": "^8.0.7",
|
"react-markdown": "^8.0.7",
|
||||||
"react-redux": "^8.0.5",
|
"react-redux": "^8.0.5",
|
||||||
"react-router-dom": "^6.8.1",
|
"react-router-dom": "^6.8.1",
|
||||||
@@ -32,8 +33,8 @@
|
|||||||
"remark-gfm": "^3.0.0"
|
"remark-gfm": "^3.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.0.27",
|
"@types/react": "^18.2.38",
|
||||||
"@types/react-dom": "^18.0.10",
|
"@types/react-dom": "^18.2.17",
|
||||||
"@types/react-syntax-highlighter": "^15.5.6",
|
"@types/react-syntax-highlighter": "^15.5.6",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.51.0",
|
"@typescript-eslint/eslint-plugin": "^5.51.0",
|
||||||
"@typescript-eslint/parser": "^5.51.0",
|
"@typescript-eslint/parser": "^5.51.0",
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import { Routes, Route } from 'react-router-dom';
|
import { Routes, Route, useLocation } from 'react-router-dom';
|
||||||
import Navigation from './Navigation';
|
import Navigation from './Navigation';
|
||||||
import Conversation from './conversation/Conversation';
|
import Conversation from './conversation/Conversation';
|
||||||
import About from './About';
|
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 PageNotFound from './PageNotFound';
|
||||||
import { inject } from '@vercel/analytics';
|
import { inject } from '@vercel/analytics';
|
||||||
import { useMediaQuery } from './hooks';
|
import { useMediaQuery } from './hooks';
|
||||||
@@ -13,20 +18,32 @@ inject();
|
|||||||
export default function App() {
|
export default function App() {
|
||||||
const { isMobile } = useMediaQuery();
|
const { isMobile } = useMediaQuery();
|
||||||
const [navOpen, setNavOpen] = useState(!isMobile);
|
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 (
|
return (
|
||||||
<div className="min-h-full min-w-full">
|
<div className="min-h-full min-w-full">
|
||||||
<Navigation navOpen={navOpen} setNavOpen={setNavOpen} />
|
{!isLogin && <Navigation navOpen={navOpen} setNavOpen={setNavOpen} />}
|
||||||
<div
|
<div
|
||||||
className={`transition-all duration-200 ${
|
className={`transition-all duration-200 ${
|
||||||
!isMobile
|
!isMobile
|
||||||
? `ml-0 ${!navOpen ? '-mt-5 md:mx-auto lg:mx-auto' : 'md:ml-72'}`
|
? `ml-0 ${!navOpen ? '-mt-5 md:mx-auto lg:mx-auto' : 'md:ml-72'}`
|
||||||
: 'ml-0 md:ml-16'
|
: 'ml-0 md:ml-16'
|
||||||
}`}
|
}${isLogin && `ml-0`}`}
|
||||||
>
|
>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/" element={<Conversation />} />
|
<Route path="/" element={<Conversation />} />
|
||||||
<Route path="/about" element={<About />} />
|
<Route path="/about" element={<About />} />
|
||||||
|
<Route path="/login" element={<Login />} />
|
||||||
|
<Route path="/register" element={<Signup />} />
|
||||||
|
<Route path="/Forgot" element={<ForgotPass />} />
|
||||||
|
<Route path="/ResetPassword" element={<ResetCode />} />
|
||||||
<Route path="*" element={<PageNotFound />} />
|
<Route path="*" element={<PageNotFound />} />
|
||||||
<Route path="/settings" element={<Setting />} />
|
<Route path="/settings" element={<Setting />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { useMediaQuery } from './hooks';
|
import { useMediaQuery } from './hooks';
|
||||||
import DocsGPT3 from './assets/cute_docsgpt3.svg';
|
import DocsGPT3 from './assets/cute_docsgpt3.svg';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
export default function Hero({ className = '' }: { className?: string }) {
|
export default function Hero({ className = '' }: { className?: string }) {
|
||||||
// const isMobile = window.innerWidth <= 768;
|
// const isMobile = window.innerWidth <= 768;
|
||||||
|
const navigate = useNavigate();
|
||||||
const { isMobile } = useMediaQuery();
|
const { isMobile } = useMediaQuery();
|
||||||
return (
|
return (
|
||||||
<div className={`mt-14 ${isMobile ? 'mb-2' : 'mb-12'}flex flex-col `}>
|
<div className={`mt-14 ${isMobile ? 'mb-2' : 'mb-12'}flex flex-col `}>
|
||||||
|
|||||||
66
frontend/src/Login/ForgotPass.tsx
Normal file
66
frontend/src/Login/ForgotPass.tsx
Normal file
@@ -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<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log('login');
|
||||||
|
};
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="z-30 flex h-full min-h-screen w-full items-center justify-center bg-[#1D1D1D]">
|
||||||
|
<div className=" flex flex-col items-center px-[5vw] md:w-fit md:p-0">
|
||||||
|
<div className=" cursor-pointer" onClick={() => navigate('/')}>
|
||||||
|
<img src={DocsGPT3} alt="Logo" className="h-[10vh]" />
|
||||||
|
</div>
|
||||||
|
<div className="font-bold md:flex md:gap-2 ">
|
||||||
|
<h1 className="text-white">Log in to </h1>
|
||||||
|
<h1 className="bg-gradient-to-r from-[#56B3CB] via-[#CD2AA0] to-[#EA635C] bg-clip-text text-transparent">
|
||||||
|
DocsGPT
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
className="flex w-full flex-col gap-[3vh] rounded-2xl border-2 border-[#383838] bg-[#222222] py-[2vh] px-[5vh] text-white md:w-fit"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<h1 className=" text-xl font-semibold">Password reset</h1>
|
||||||
|
<p className="text-md font-semibold text-[#888888] md:max-w-[25vw]">
|
||||||
|
Enter the email address associated with your account and we will
|
||||||
|
send you a link to reset your password.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="Name"
|
||||||
|
placeholder="Email"
|
||||||
|
className="w-full rounded-lg border-none bg-[#2B2B2B] p-4 text-sm font-medium text-white focus:outline-none "
|
||||||
|
// onChange={onchange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
className="h-[7vh] rounded-lg bg-[#7D54D1] text-sm font-medium text-white hover:bg-[#8A62DC]"
|
||||||
|
onClick={() => {
|
||||||
|
navigate('/ResetPassword');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Request password reset
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<div className="mt-[2vh] flex w-full justify-center text-sm">
|
||||||
|
<h2 className="gap-1 text-right text-[#5F5F5F] md:flex">
|
||||||
|
Don't have an account?
|
||||||
|
<h2
|
||||||
|
className="text-center font-medium text-white hover:cursor-pointer hover:underline"
|
||||||
|
onClick={() => navigate('/register')}
|
||||||
|
>
|
||||||
|
Sign up
|
||||||
|
</h2>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
173
frontend/src/Login/Login.tsx
Normal file
173
frontend/src/Login/Login.tsx
Normal file
@@ -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<string>('');
|
||||||
|
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 (
|
||||||
|
<div className="z-30 flex h-full min-h-screen w-full items-center justify-center bg-[#1D1D1D]">
|
||||||
|
<div className="flex flex-col items-center md:w-fit">
|
||||||
|
<div className="text- cursor-pointer" onClick={() => navigate('/')}>
|
||||||
|
<img src={DocsGPT3} alt="Logo" className="h-[10vh]" />
|
||||||
|
</div>
|
||||||
|
<div className="mt-[2vh] flex w-full flex-wrap items-center justify-center gap-2 font-bold ">
|
||||||
|
<h1 className="mt-0 text-[3vh] text-white md:text-[3.5vh]">
|
||||||
|
Log in to
|
||||||
|
</h1>
|
||||||
|
<h1 className="mt-0 bg-gradient-to-r from-[#56B3CB] via-[#CD2AA0] to-[#EA635C] bg-clip-text text-[3vh] text-transparent md:text-[3.5vh]">
|
||||||
|
DocsGPT
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<form className="flex w-full flex-col gap-[3vh] md:w-fit">
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="Name"
|
||||||
|
placeholder="Email"
|
||||||
|
onChange={(e) => {
|
||||||
|
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}
|
||||||
|
/>
|
||||||
|
<div className="relative flex">
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
id="password"
|
||||||
|
name="Name"
|
||||||
|
placeholder="Password"
|
||||||
|
onChange={(e) => {
|
||||||
|
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 ? (
|
||||||
|
<button
|
||||||
|
onClick={() => togglePassword()}
|
||||||
|
type="button"
|
||||||
|
className="absolute top-[2.2vh] right-[2vh] text-[2vh] text-white md:text-[3vh]"
|
||||||
|
>
|
||||||
|
<IoEye />
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
onClick={() => togglePassword()}
|
||||||
|
type="button"
|
||||||
|
className="absolute top-[2.2vh] right-[2vh] text-[2vh] text-white md:text-[3vh]"
|
||||||
|
>
|
||||||
|
<IoMdEyeOff />
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2
|
||||||
|
className="text-right text-sm text-[#5F5F5F] hover:cursor-pointer hover:text-gray-400"
|
||||||
|
onClick={() => navigate('/Forgot')}
|
||||||
|
>
|
||||||
|
Forgot your password?
|
||||||
|
</h2>
|
||||||
|
<button
|
||||||
|
onClick={() => handleSubmit()}
|
||||||
|
type="button"
|
||||||
|
className="h-[7vh] rounded-lg bg-[#7D54D1] font-semibold text-white hover:bg-[#8A62DC]"
|
||||||
|
>
|
||||||
|
Log in
|
||||||
|
</button>
|
||||||
|
{showalert.length > 0 && (
|
||||||
|
<div className="text-red-500">{showalert}</div>
|
||||||
|
)}
|
||||||
|
<div className="flex w-full justify-center text-sm">
|
||||||
|
<h2 className="flex gap-1 text-right text-[#5F5F5F]">
|
||||||
|
Don't have an account?
|
||||||
|
<h2
|
||||||
|
className="text-center font-bold text-white hover:cursor-pointer hover:underline"
|
||||||
|
onClick={() => navigate('/register')}
|
||||||
|
>
|
||||||
|
Sign up
|
||||||
|
</h2>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
63
frontend/src/Login/ResetCode.tsx
Normal file
63
frontend/src/Login/ResetCode.tsx
Normal file
@@ -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<HTMLFormElement>) => {
|
||||||
|
e.preventDefault();
|
||||||
|
console.log('login');
|
||||||
|
};
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
return (
|
||||||
|
<div className="z-30 flex h-full min-h-screen w-full items-center justify-center bg-[#1D1D1D]">
|
||||||
|
<div className=" flex flex-col items-center px-[5vw] md:w-fit md:p-0">
|
||||||
|
<div className=" cursor-pointer" onClick={() => navigate('/')}>
|
||||||
|
<img src={DocsGPT3} alt="Logo" className="h-[10vh]" />
|
||||||
|
</div>
|
||||||
|
<div className="font-bold md:flex md:gap-2 ">
|
||||||
|
<h1 className="text-white">Log in to </h1>
|
||||||
|
<h1 className="bg-gradient-to-r from-[#56B3CB] via-[#CD2AA0] to-[#EA635C] bg-clip-text text-transparent">
|
||||||
|
DocsGPT
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
className="flex w-full flex-col gap-[3vh] rounded-2xl border-2 border-[#383838] bg-[#222222] py-[2vh] px-[5vh] text-white md:w-fit"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<h1 className=" text-xl font-semibold md:max-w-[25vw]">
|
||||||
|
We've sent you instructions to reset your password. Please
|
||||||
|
check your inbox.
|
||||||
|
</h1>
|
||||||
|
<p className="text-md text-[#888888] md:max-w-[25vw]">
|
||||||
|
If you haven't received an email in 5 minutes, check your
|
||||||
|
spam, resend, or try a different email.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="Name"
|
||||||
|
placeholder="Email"
|
||||||
|
className="w-full rounded-lg border-none bg-[#2B2B2B] p-4 text-sm font-medium text-white focus:outline-none "
|
||||||
|
// onChange={onchange}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button className="h-[7vh] rounded-lg bg-[#7D54D1] text-sm font-medium text-white hover:bg-[#8A62DC]">
|
||||||
|
Request password reset
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
<div className="mt-[2vh] flex w-full justify-center text-sm">
|
||||||
|
<h2 className="gap-1 text-right text-[#5F5F5F] md:flex">
|
||||||
|
Don't have an account?
|
||||||
|
<h2
|
||||||
|
className="text-center font-medium text-white hover:cursor-pointer hover:underline"
|
||||||
|
onClick={() => navigate('/register')}
|
||||||
|
>
|
||||||
|
Sign up
|
||||||
|
</h2>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
137
frontend/src/Login/Signup.tsx
Normal file
137
frontend/src/Login/Signup.tsx
Normal file
@@ -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<string>('');
|
||||||
|
const [email, setemail] = useState('');
|
||||||
|
const [password, setpassword] = useState('');
|
||||||
|
const [isVisible, setisVisible] = useState(false);
|
||||||
|
const [ispasswordVisible, setispasswordVisible] = useState(false);
|
||||||
|
|
||||||
|
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
|
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 (
|
||||||
|
<div className="z-30 flex h-full min-h-screen w-full items-center justify-center bg-[#1D1D1D]">
|
||||||
|
<div className=" flex flex-col items-center px-[5vh] md:w-fit md:px-0">
|
||||||
|
<div className=" cursor-pointer" onClick={() => navigate('/')}>
|
||||||
|
<img src={DocsGPT3} alt="Logo" className="h-[10vh]" />
|
||||||
|
</div>
|
||||||
|
<div className="mt-[2vh] flex flex-wrap items-center justify-center gap-2 font-bold ">
|
||||||
|
<h1 className="mt-0 text-[3vh] text-white md:text-[3.5vh]">Create</h1>
|
||||||
|
<h1 className="mt-0 bg-gradient-to-r from-[#56B3CB] via-[#CD2AA0] to-[#EA635C] bg-clip-text text-[3vh] text-transparent md:text-[3.5vh]">
|
||||||
|
DocsGPT
|
||||||
|
</h1>
|
||||||
|
<h1 className="mt-0 text-[3vh] text-white md:text-[3.5vh]">
|
||||||
|
Account
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<form
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
className="flex flex-col gap-[3vh] px-[2vh] md:w-fit"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
name="Name"
|
||||||
|
placeholder="Email"
|
||||||
|
onChange={(e) => {
|
||||||
|
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]"
|
||||||
|
/>
|
||||||
|
<div className="relative flex">
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
id="password"
|
||||||
|
name="Name"
|
||||||
|
placeholder="Password"
|
||||||
|
onChange={(e) => {
|
||||||
|
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 ? (
|
||||||
|
<button
|
||||||
|
onClick={() => togglePassword()}
|
||||||
|
type="button"
|
||||||
|
className="absolute top-[2.2vh] right-[2vh] text-[2vh] text-white md:text-[3vh]"
|
||||||
|
>
|
||||||
|
<IoEye />
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
onClick={() => togglePassword()}
|
||||||
|
type="button"
|
||||||
|
className="absolute top-[2.2vh] right-[2vh] text-[2vh] text-white md:text-[3vh]"
|
||||||
|
>
|
||||||
|
<IoMdEyeOff />
|
||||||
|
</button>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<button className="h-[7vh] rounded-lg bg-[#7D54D1] font-semibold text-white hover:bg-[#8A62DC]">
|
||||||
|
Create Account
|
||||||
|
</button>
|
||||||
|
{showalert.length > 0 && (
|
||||||
|
<div className="text-red-500">{showalert}</div>
|
||||||
|
)}
|
||||||
|
<div className="flex w-full justify-center text-sm">
|
||||||
|
<h2 className="flex gap-1 text-right text-[#5F5F5F]">
|
||||||
|
Already have an account?
|
||||||
|
<h2
|
||||||
|
className="text-center font-bold text-white hover:cursor-pointer hover:underline"
|
||||||
|
onClick={() => navigate('/login')}
|
||||||
|
>
|
||||||
|
Log in
|
||||||
|
</h2>
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Fragment, useEffect, useRef, useState } from 'react';
|
import { Fragment, useEffect, useRef, useState } from 'react';
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
import Hero from '../Hero';
|
import Hero from '../Hero';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { AppDispatch } from '../store';
|
import { AppDispatch } from '../store';
|
||||||
import ConversationBubble from './ConversationBubble';
|
import ConversationBubble from './ConversationBubble';
|
||||||
import {
|
import {
|
||||||
@@ -115,6 +116,8 @@ export default function Conversation() {
|
|||||||
document.execCommand('insertText', false, text);
|
document.execCommand('insertText', false, text);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col justify-center p-4 md:flex-row">
|
<div className="flex flex-col justify-center p-4 md:flex-row">
|
||||||
{queries.length > 0 && !hasScrolledToLast && (
|
{queries.length > 0 && !hasScrolledToLast && (
|
||||||
@@ -133,7 +136,7 @@ export default function Conversation() {
|
|||||||
|
|
||||||
{queries.length > 0 && (
|
{queries.length > 0 && (
|
||||||
<div className="mt-20 flex flex-col transition-all md:w-3/4">
|
<div className="mt-20 flex flex-col transition-all md:w-3/4">
|
||||||
{queries.map((query, index) => {
|
{queries.map((query: Query, index: number) => {
|
||||||
return (
|
return (
|
||||||
<Fragment key={index}>
|
<Fragment key={index}>
|
||||||
<ConversationBubble
|
<ConversationBubble
|
||||||
@@ -152,8 +155,23 @@ export default function Conversation() {
|
|||||||
{queries.length === 0 && (
|
{queries.length === 0 && (
|
||||||
<Hero className="mt-24 h-[100vh] md:mt-52"></Hero>
|
<Hero className="mt-24 h-[100vh] md:mt-52"></Hero>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="relative bottom-0 flex w-10/12 flex-col items-end self-center bg-white pt-3 md:fixed md:w-[65%]">
|
<div className="relative bottom-0 flex w-10/12 flex-col items-end self-center bg-white pt-3 md:fixed md:w-[65%]">
|
||||||
<div className="flex h-full w-full">
|
<div className="flex h-full w-full">
|
||||||
|
<div className="mt-[1vh] flex w-full items-center justify-center gap-[1vh]">
|
||||||
|
<button
|
||||||
|
className="mr-4 flex items-center justify-center rounded-full bg-blue-1000 py-2 px-4 text-white hover:bg-blue-3000"
|
||||||
|
onClick={() => navigate('/register')}
|
||||||
|
>
|
||||||
|
Sign Up
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className="mr-4 flex items-center justify-center rounded-full bg-blue-1000 py-2 px-4 text-white hover:bg-blue-3000"
|
||||||
|
onClick={() => navigate('/login')}
|
||||||
|
>
|
||||||
|
Sign in
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
id="inputbox"
|
id="inputbox"
|
||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
@@ -192,6 +210,7 @@ export default function Conversation() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p className="text-gray-595959 w-[100vw] self-center bg-white p-5 text-center text-xs md:w-full">
|
<p className="text-gray-595959 w-[100vw] self-center bg-white p-5 text-center text-xs md:w-full">
|
||||||
This is a chatbot that uses the GPT-3, Faiss and LangChain to answer
|
This is a chatbot that uses the GPT-3, Faiss and LangChain to answer
|
||||||
questions.
|
questions.
|
||||||
|
|||||||
Reference in New Issue
Block a user