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.
117 lines
3.5 KiB
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>
|
|
)
|
|
}
|