Skip to content

Commit

Permalink
✨ Add Login to new frontend (fastapi#585)
Browse files Browse the repository at this point in the history
  • Loading branch information
alejsdev authored Jan 23, 2024
1 parent 4a4efec commit 167f059
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 14 deletions.
7 changes: 4 additions & 3 deletions src/new-frontend/index.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<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>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
<script type="module" src="./src/main.tsx"></script>
</body>
</html>
10 changes: 9 additions & 1 deletion src/new-frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,18 @@
"generate-client": "openapi --input ./openapi.json --useOptions --useUnionTypes --output ./src/client --client axios --exportSchemas true"
},
"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",
"form-data": "4.0.0",
"framer-motion": "10.16.16",
"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": {
"@types/node": "20.10.5",
Expand Down
15 changes: 10 additions & 5 deletions src/new-frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import './App.css'

function App() {
import { BrowserRouter, Route, Routes } from 'react-router-dom';

import Login from './pages/auth/Login';
import RecoverPassword from './pages/auth/RecoverPassword';

function App() {
return (
<>
</>
<BrowserRouter>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/recover-password" element={<RecoverPassword />} />
</Routes>
</BrowserRouter>
)
}

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/new-frontend/src/assets/images/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
21 changes: 16 additions & 5 deletions src/new-frontend/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import React from 'react';
import ReactDOM from 'react-dom/client';

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(
<React.StrictMode>
<App />
<ChakraProvider>
<App />
</ChakraProvider>
</React.StrictMode>,
)

72 changes: 72 additions & 0 deletions src/new-frontend/src/pages/auth/Login.tsx
Original file line number Diff line number Diff line change
@@ -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;

0 comments on commit 167f059

Please sign in to comment.