Implement frontend user login
This commit is contained in:
@@ -1,11 +1,17 @@
|
||||
import React from 'react';
|
||||
import { useState } from 'react';
|
||||
import Login from './Login';
|
||||
import MainView from './MainView';
|
||||
|
||||
|
||||
export const App: React.FC = () => {
|
||||
return (
|
||||
<div className="App">
|
||||
hallo i bims 1 frontend
|
||||
</div>
|
||||
);
|
||||
|
||||
const [loginToken, setLoginToken] = useState<string | null>(null);
|
||||
|
||||
if (loginToken === null) {
|
||||
return <Login setLoginToken={setLoginToken} />
|
||||
} else {
|
||||
return <MainView loginToken={loginToken} logout={() => { setLoginToken(null); }} />
|
||||
}
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
68
frontend/src/Login.tsx
Normal file
68
frontend/src/Login.tsx
Normal file
@@ -0,0 +1,68 @@
|
||||
import React, { useState } from "react";
|
||||
|
||||
type LoginResponse = {
|
||||
access_token: string,
|
||||
token_type: "bearer",
|
||||
};
|
||||
|
||||
type LoginError = {
|
||||
detail: string
|
||||
}
|
||||
|
||||
const LOGIN_ENDPOINT = "auth/login"
|
||||
|
||||
export const Login: React.FC<{
|
||||
setLoginToken: (token: string) => void
|
||||
}> = ({ setLoginToken }) => {
|
||||
|
||||
const [username, setUsername] = useState<string>("");
|
||||
const [password, setPassword] = useState<string>("");
|
||||
|
||||
const handleSubmit = async (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
e.preventDefault();
|
||||
|
||||
let formData = new FormData();
|
||||
formData.append("grant_type", "password");
|
||||
formData.append("username", username);
|
||||
formData.append("password", password);
|
||||
|
||||
const response = await fetch(LOGIN_ENDPOINT, {
|
||||
method: "POST",
|
||||
cache: "no-cache",
|
||||
body: formData,
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json() as LoginResponse;
|
||||
setLoginToken(data.access_token);
|
||||
} else {
|
||||
const data = await response.json() as LoginError;
|
||||
alert(data.detail);
|
||||
}
|
||||
}
|
||||
|
||||
return <>
|
||||
<h1>login pls</h1>
|
||||
<form>
|
||||
<label htmlFor="username">Username</label>
|
||||
<input
|
||||
type="text"
|
||||
id="username"
|
||||
placeholder="joe"
|
||||
value={username}
|
||||
onChange={(e) => { setUsername(e.target.value) }}>
|
||||
</input>
|
||||
<label htmlFor="password">Password</label>
|
||||
<input
|
||||
type="password"
|
||||
id="password"
|
||||
placeholder="mama"
|
||||
value={password}
|
||||
onChange={(e) => { setPassword(e.target.value) }}>
|
||||
</input>
|
||||
<button type="submit" onClick={handleSubmit}>Ok</button>
|
||||
</form>
|
||||
</>
|
||||
}
|
||||
|
||||
export default Login;
|
||||
46
frontend/src/MainView.tsx
Normal file
46
frontend/src/MainView.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
const ENDPOINT = "test"
|
||||
|
||||
export const MainView: React.FC<{
|
||||
loginToken: string,
|
||||
logout: () => void,
|
||||
}> = ({ loginToken, logout }) => {
|
||||
|
||||
const [data, setData] = useState<{ name: string, foo: string } | undefined>();
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
const response = await fetch(ENDPOINT, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${loginToken}`,
|
||||
}
|
||||
});
|
||||
|
||||
if (response.status !== 200) {
|
||||
alert("big oof");
|
||||
}
|
||||
|
||||
setData(await response.json());
|
||||
}
|
||||
|
||||
fetchData();
|
||||
}, [loginToken]);
|
||||
|
||||
if (!data) {
|
||||
return <>
|
||||
fetching data...
|
||||
</>
|
||||
} else {
|
||||
return <>
|
||||
<p>
|
||||
Token: {data.name}
|
||||
</p>
|
||||
<p>
|
||||
Foo: {data.foo}
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
}
|
||||
|
||||
export default MainView;
|
||||
Reference in New Issue
Block a user