committed by
GitHub
7 changed files with 111 additions and 14 deletions
@ -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> |
||||
|
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 412 B |
@ -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>, |
||||
) |
) |
||||
|
|
||||
|
@ -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; |
Loading…
Reference in new issue