|
|
@ -1,4 +1,4 @@
|
|
|
|
import { FormEvent, useCallback, useRef, useState } from "react"
|
|
|
|
import { FormEvent, useCallback, useEffect, useRef, useState } from "react"
|
|
|
|
import "../style/settings.css"
|
|
|
|
import "../style/settings.css"
|
|
|
|
import { useAppFetcher, useUser } from "../App.tsx"
|
|
|
|
import { useAppFetcher, useUser } from "../App.tsx"
|
|
|
|
import { Fetcher } from "../app/Fetcher.ts"
|
|
|
|
import { Fetcher } from "../app/Fetcher.ts"
|
|
|
@ -10,18 +10,19 @@ export default function ProfileSettings() {
|
|
|
|
const [errorMessages, setErrorMessages] = useState<string[]>([])
|
|
|
|
const [errorMessages, setErrorMessages] = useState<string[]>([])
|
|
|
|
const [success, setSuccess] = useState(false)
|
|
|
|
const [success, setSuccess] = useState(false)
|
|
|
|
|
|
|
|
|
|
|
|
const formRef = useRef<HTMLFormElement | null>(null)
|
|
|
|
const [name, setName] = useState(user!.name)
|
|
|
|
|
|
|
|
const [email, setEmail] = useState(user!.email)
|
|
|
|
|
|
|
|
const [password, setPassword] = useState<string>()
|
|
|
|
|
|
|
|
const [confirmPassword, setConfirmPassword] = useState<string>()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const passwordConfirmRef = useRef<HTMLInputElement>(null)
|
|
|
|
|
|
|
|
const formRef = useRef<HTMLFormElement>(null)
|
|
|
|
|
|
|
|
|
|
|
|
const submitForm = useCallback(
|
|
|
|
const submitForm = useCallback(
|
|
|
|
async (e: FormEvent) => {
|
|
|
|
async (e: FormEvent) => {
|
|
|
|
e.preventDefault()
|
|
|
|
e.preventDefault()
|
|
|
|
const { name, email, password, confirmPassword } =
|
|
|
|
|
|
|
|
Object.fromEntries<string>(
|
|
|
|
|
|
|
|
new FormData(formRef.current!) as Iterable<
|
|
|
|
|
|
|
|
[PropertyKey, string]
|
|
|
|
|
|
|
|
>,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
passwordConfirmRef.current!.checkValidity()
|
|
|
|
if (password !== confirmPassword) {
|
|
|
|
if (password !== confirmPassword) {
|
|
|
|
setErrorMessages(["Les mots de passe ne correspondent pas !"])
|
|
|
|
setErrorMessages(["Les mots de passe ne correspondent pas !"])
|
|
|
|
return
|
|
|
|
return
|
|
|
@ -46,8 +47,14 @@ export default function ProfileSettings() {
|
|
|
|
formRef.current!.reset()
|
|
|
|
formRef.current!.reset()
|
|
|
|
setErrorMessages([])
|
|
|
|
setErrorMessages([])
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[fetcher, setUser, user],
|
|
|
|
[confirmPassword, email, fetcher, name, password, setUser, user],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
passwordConfirmRef.current!.setCustomValidity(
|
|
|
|
|
|
|
|
password === confirmPassword ? "" : "Les mots de passe ne correspondent pas !"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
}, [confirmPassword, password])
|
|
|
|
|
|
|
|
|
|
|
|
const [modalShow, setModalShow] = useState(false)
|
|
|
|
const [modalShow, setModalShow] = useState(false)
|
|
|
|
const width = 150
|
|
|
|
const width = 150
|
|
|
@ -94,44 +101,64 @@ export default function ProfileSettings() {
|
|
|
|
ref={formRef}
|
|
|
|
ref={formRef}
|
|
|
|
id="credentials-form"
|
|
|
|
id="credentials-form"
|
|
|
|
onSubmit={submitForm}>
|
|
|
|
onSubmit={submitForm}>
|
|
|
|
<p>Nom d'utilisateur</p>
|
|
|
|
<label htmlFor="name">Nom d'utilisateur</label>
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
className="settings-input"
|
|
|
|
className="settings-input"
|
|
|
|
|
|
|
|
id="name"
|
|
|
|
name="name"
|
|
|
|
name="name"
|
|
|
|
type="text"
|
|
|
|
type="text"
|
|
|
|
placeholder={"Nom d'utilisateur"}
|
|
|
|
autoComplete="username"
|
|
|
|
defaultValue={user!.name}
|
|
|
|
required
|
|
|
|
|
|
|
|
placeholder="Nom d'utilisateur"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
value={name}
|
|
|
|
|
|
|
|
onChange={e => setName(e.target.value)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<p>Addresse email</p>
|
|
|
|
<label htmlFor="email">Adresse email</label>
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
className="settings-input"
|
|
|
|
className="settings-input"
|
|
|
|
name="email"
|
|
|
|
name="email"
|
|
|
|
|
|
|
|
id="email"
|
|
|
|
type="email"
|
|
|
|
type="email"
|
|
|
|
placeholder={"Addresse email"}
|
|
|
|
placeholder={"Addresse email"}
|
|
|
|
defaultValue={user!.email}
|
|
|
|
autoComplete="email"
|
|
|
|
|
|
|
|
required
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
value={email}
|
|
|
|
|
|
|
|
onChange={e => setEmail(e.target.value)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<p>Mot de passe</p>
|
|
|
|
<label htmlFor="password">Mot de passe</label>
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
className="settings-input"
|
|
|
|
className="settings-input"
|
|
|
|
name="password"
|
|
|
|
name="password"
|
|
|
|
|
|
|
|
id={"password"}
|
|
|
|
type="password"
|
|
|
|
type="password"
|
|
|
|
placeholder={"Mot de passe"}
|
|
|
|
placeholder={"Mot de passe"}
|
|
|
|
|
|
|
|
autoComplete="new-password"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
value={password}
|
|
|
|
|
|
|
|
onChange={e => setPassword(e.target.value)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<p>Confirmez le mot de passe</p>
|
|
|
|
<label htmlFor="confirmPassword">Confirmez le mot de passe</label>
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
|
|
|
|
ref={passwordConfirmRef}
|
|
|
|
className="settings-input"
|
|
|
|
className="settings-input"
|
|
|
|
name="confirmPassword"
|
|
|
|
name="confirmPassword"
|
|
|
|
|
|
|
|
id="confirmPassword"
|
|
|
|
type="password"
|
|
|
|
type="password"
|
|
|
|
|
|
|
|
autoComplete="new-password"
|
|
|
|
placeholder={"Confirmation du mot de passe"}
|
|
|
|
placeholder={"Confirmation du mot de passe"}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
value={confirmPassword}
|
|
|
|
|
|
|
|
onChange={e => setConfirmPassword(e.target.value)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<button
|
|
|
|
<button
|
|
|
|
className="settings-button"
|
|
|
|
className="settings-button"
|
|
|
|
type="submit"
|
|
|
|
type="submit">
|
|
|
|
onClick={submitForm}>
|
|
|
|
|
|
|
|
Mettre à jour
|
|
|
|
Mettre à jour
|
|
|
|
</button>
|
|
|
|
</button>
|
|
|
|
</form>
|
|
|
|
</form>
|
|
|
@ -173,11 +200,38 @@ function ProfileImageInputPopup({ show, onHide }: ProfileImageInputPopupProps) {
|
|
|
|
const fetcher = useAppFetcher()
|
|
|
|
const fetcher = useAppFetcher()
|
|
|
|
const [user, setUser] = useUser()
|
|
|
|
const [user, setUser] = useUser()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const [link, setLink] = useState("")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
function onKeyUp(e: KeyboardEvent) {
|
|
|
|
|
|
|
|
if (e.key === "Escape") onHide()
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
window.addEventListener('keyup', onKeyUp)
|
|
|
|
|
|
|
|
return () => window.removeEventListener('keyup', onKeyUp)
|
|
|
|
|
|
|
|
}, [onHide])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const handleForm = useCallback(async (e: FormEvent) => {
|
|
|
|
|
|
|
|
e.preventDefault()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const url = urlRef.current!.value
|
|
|
|
|
|
|
|
const errors = await updateAccount(fetcher, {
|
|
|
|
|
|
|
|
profilePicture: url,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
if (errors.length !== 0) {
|
|
|
|
|
|
|
|
setErrorMessages(errors)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setUser({ ...user!, profilePicture: url })
|
|
|
|
|
|
|
|
setErrorMessages([])
|
|
|
|
|
|
|
|
onHide()
|
|
|
|
|
|
|
|
}, [fetcher, onHide, setUser, user])
|
|
|
|
|
|
|
|
|
|
|
|
if (!show) return <></>
|
|
|
|
if (!show) return <></>
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<div id="profile-picture-popup">
|
|
|
|
<dialog id="profile-picture-popup">
|
|
|
|
<div id="profile-picture-popup-content">
|
|
|
|
<form id="profile-picture-popup-form" onSubmit={handleForm}>
|
|
|
|
<div id="profile-picture-popup-header">
|
|
|
|
<div id="profile-picture-popup-header">
|
|
|
|
<p id="profile-picture-popup-title">
|
|
|
|
<p id="profile-picture-popup-title">
|
|
|
|
Nouvelle photo de profil
|
|
|
|
Nouvelle photo de profil
|
|
|
@ -189,9 +243,9 @@ function ProfileImageInputPopup({ show, onHide }: ProfileImageInputPopupProps) {
|
|
|
|
{msg}
|
|
|
|
{msg}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
))}
|
|
|
|
))}
|
|
|
|
<p id="profile-picture-popup-subtitle">
|
|
|
|
<label id="profile-picture-popup-subtitle" htmlFor="profile-picture">
|
|
|
|
Saisissez le lien vers votre nouvelle photo de profil
|
|
|
|
Saisissez le lien vers votre nouvelle photo de profil
|
|
|
|
</p>
|
|
|
|
</label>
|
|
|
|
<input
|
|
|
|
<input
|
|
|
|
className={
|
|
|
|
className={
|
|
|
|
`settings-input ` +
|
|
|
|
`settings-input ` +
|
|
|
@ -199,33 +253,26 @@ function ProfileImageInputPopup({ show, onHide }: ProfileImageInputPopupProps) {
|
|
|
|
? ""
|
|
|
|
? ""
|
|
|
|
: "invalid-input")
|
|
|
|
: "invalid-input")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
id="profile-picture"
|
|
|
|
ref={urlRef}
|
|
|
|
ref={urlRef}
|
|
|
|
type="input"
|
|
|
|
type="url"
|
|
|
|
|
|
|
|
autoComplete="url"
|
|
|
|
|
|
|
|
required
|
|
|
|
placeholder={"lien vers une image"}
|
|
|
|
placeholder={"lien vers une image"}
|
|
|
|
|
|
|
|
value={link}
|
|
|
|
|
|
|
|
onChange={e => setLink(e.target.value)}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<div id="profile-picture-popup-footer">
|
|
|
|
<div id="profile-picture-popup-footer">
|
|
|
|
<button className={"settings-button"} onClick={onHide}>
|
|
|
|
<button className={"settings-button"} onClick={onHide}>
|
|
|
|
Annuler
|
|
|
|
Annuler
|
|
|
|
</button>
|
|
|
|
</button>
|
|
|
|
<button
|
|
|
|
<input
|
|
|
|
|
|
|
|
type="submit"
|
|
|
|
className={"settings-button"}
|
|
|
|
className={"settings-button"}
|
|
|
|
onClick={async () => {
|
|
|
|
value="Valider"
|
|
|
|
const url = urlRef.current!.value
|
|
|
|
/>
|
|
|
|
const errors = await updateAccount(fetcher, {
|
|
|
|
|
|
|
|
profilePicture: url,
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
if (errors.length !== 0) {
|
|
|
|
|
|
|
|
setErrorMessages(errors)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
setUser({ ...user!, profilePicture: url })
|
|
|
|
|
|
|
|
setErrorMessages([])
|
|
|
|
|
|
|
|
onHide()
|
|
|
|
|
|
|
|
}}>
|
|
|
|
|
|
|
|
Valider
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</form>
|
|
|
|
|
|
|
|
</dialog>
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|