Add Login to new frontend (#585)

This commit is contained in:
Alejandra
2024-01-23 11:48:56 -05:00
committed by GitHub
parent bd54967db8
commit 52150b3d10
7 changed files with 111 additions and 14 deletions

View File

@@ -1,13 +1,14 @@
<!doctype html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title> <title>Full Stack Project Generator</title>
<link rel="icon" type="image/x-icon" href="./src/assets/images/favicon.png" />
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
<script type="module" src="/src/main.tsx"></script> <script type="module" src="./src/main.tsx"></script>
</body> </body>
</html> </html>

View File

@@ -11,10 +11,18 @@
"generate-client": "openapi --input ./openapi.json --useOptions --useUnionTypes --output ./src/client --client axios --exportSchemas true" "generate-client": "openapi --input ./openapi.json --useOptions --useUnionTypes --output ./src/client --client axios --exportSchemas true"
}, },
"dependencies": { "dependencies": {
"@chakra-ui/icons": "2.1.1",
"@chakra-ui/react": "2.8.2",
"@emotion/react": "11.11.3",
"@emotion/styled": "11.11.0",
"@types/react-router-dom": "5.3.3",
"axios": "1.6.2", "axios": "1.6.2",
"form-data": "4.0.0", "form-data": "4.0.0",
"framer-motion": "10.16.16",
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0" "react-dom": "^18.2.0",
"react-hook-form": "7.49.3",
"react-router-dom": "6.21.1"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "20.10.5", "@types/node": "20.10.5",

View File

@@ -1,11 +1,16 @@
import './App.css' import { BrowserRouter, Route, Routes } from 'react-router-dom';
import Login from './pages/auth/Login';
import RecoverPassword from './pages/auth/RecoverPassword';
function App() { function App() {
return ( return (
<> <BrowserRouter>
</> <Routes>
<Route path="/login" element={<Login />} />
<Route path="/recover-password" element={<RecoverPassword />} />
</Routes>
</BrowserRouter>
) )
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 B

View File

@@ -1,10 +1,21 @@
import React from 'react' import React from 'react';
import ReactDOM from 'react-dom/client' import ReactDOM from 'react-dom/client';
import App from './App.tsx'
import './index.css' import { ChakraProvider } from '@chakra-ui/react';
import App from './App';
import { OpenAPI } from './client';
OpenAPI.BASE = import.meta.env.VITE_API_URL;
OpenAPI.TOKEN = async () => {
return localStorage.getItem('access_token') || '';
}
ReactDOM.createRoot(document.getElementById('root')!).render( ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode> <React.StrictMode>
<App /> <ChakraProvider>
<App />
</ChakraProvider>
</React.StrictMode>, </React.StrictMode>,
) )

View File

@@ -0,0 +1,72 @@
import React from "react";
import { ViewIcon, ViewOffIcon } from "@chakra-ui/icons";
import { Button, Center, Container, FormControl, Icon, Image, Input, InputGroup, InputRightElement, Link, useBoolean } from "@chakra-ui/react";
import { SubmitHandler, useForm } from "react-hook-form";
import { Link as ReactRouterLink, useNavigate } from "react-router-dom";
import Logo from "../../assets/images/fastapi-logo.png";
import { LoginService } from "../../client";
import { Body_login_login_access_token as AccessToken } from "../../client/models/Body_login_login_access_token";
const Login: React.FC = () => {
const [show, setShow] = useBoolean();
const navigate = useNavigate();
const { register, handleSubmit } = useForm<AccessToken>();
const onSubmit: SubmitHandler<AccessToken> = async (data) => {
const response = await LoginService.loginAccessToken({
formData: data,
});
localStorage.setItem("access_token", response.access_token);
navigate("/");
};
return (
<Container
as="form"
onSubmit={handleSubmit(onSubmit)}
h="100vh"
maxW="sm"
alignItems="stretch"
justifyContent="center"
gap={4}
centerContent
>
<Image src={Logo} alt="FastAPI logo" height="auto" maxW="2xs" alignSelf="center" />
<FormControl id="email">
<Input {...register("username")} focusBorderColor="blue.200" placeholder="Email" type="text" />
</FormControl>
<FormControl id="password">
<InputGroup>
<Input
{...register("password")}
type={show ? "text" : "password"}
focusBorderColor="blue.200"
placeholder="Password"
/>
<InputRightElement
color="gray.500"
_hover={{
cursor: "pointer",
}}
>
<Icon onClick={setShow.toggle} aria-label={show ? "Hide password" : "Show password"}>
{show ? <ViewOffIcon /> : <ViewIcon />}
</Icon>
</InputRightElement>
</InputGroup>
<Center>
<Link as={ReactRouterLink} to="/recover-password" color="blue.500" mt={2}>
Forgot password?
</Link>
</Center>
</FormControl>
<Button colorScheme="teal" type="submit">
Log In
</Button>
</Container>
);
};
export default Login;