You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Application-Web/src/pages/LoginPage.tsx

117 lines
3.5 KiB

import { FormEvent, useRef, useState } from "react"
import { BASE } from "../Constants.ts"
import { fetchAPI, redirect } from "../Fetcher.ts"
import { Failure } from "../api/failure.ts"
import { getSession, saveSession } from "../api/session.ts"
import "../style/form.css"
export default function LoginApp() {
const [errors, setErrors] = useState<Failure[]>([])
const emailRef = useRef<HTMLInputElement>(null)
const passwordRef = useRef<HTMLInputElement>(null)
async function handleSubmit(e: FormEvent) {
e.preventDefault()
const email = emailRef.current!.value
const password = passwordRef.current!.value
const response = await fetchAPI(
"auth/token",
{ email, password },
"POST",
false,
)
if (response.ok) {
const session = getSession()
const { token, expirationDate } = await response.json()
saveSession({ ...session, auth: { token, expirationDate }, urlTarget: undefined })
redirect(session.urlTarget ?? "/")
return
}
// if unauthorized :
if (response.status === 401) {
setErrors([
{
type: "Non autorisé",
messages: [
"L'adresse email ou le mot de passe sont invalide.",
],
},
])
return
}
try {
const failures = await response.json()
setErrors(
Object.entries<string[]>(failures).map(([type, messages]) => ({
type,
messages,
})),
)
} catch (e) {
setErrors([
{
type: "internal error",
messages: ["an internal error occurred."],
},
])
}
}
return (
<div className="container">
<center>
<h2>Se connecter</h2>
</center>
{errors.map(({ type, messages }) =>
messages.map((message) => (
<p key={type} style={{ color: "red" }}>
{type} : {message}
</p>
)),
)}
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="email">Email :</label>
<input
ref={emailRef}
type="text"
id="email"
name="email"
required
/>
<label htmlFor="password">Mot de passe :</label>
<input
ref={passwordRef}
type="password"
id="password"
name="password"
required
/>
<a href={BASE + "/register"} className="inscr">
Vous n'avez pas de compte ?
</a>
<br />
<br />
<div id="buttons">
<input
className="button"
type="submit"
value="Se connecter"
/>
</div>
</div>
</form>
</div>
)
}