Add settings page, refactor session management #118
Merged
maxime.batista
merged 6 commits from settings-reborn
into master
1 year ago
Loading…
Reference in new issue
There is no content yet.
Delete Branch 'settings-reborn'
Deleting a branch is permanent. It CANNOT be undone. Continue?
<script>
var Alert = ReactBootstrap.Alert
</script>
A build tool is used to avoid that.
}
const storedAuth = useMemo(() => getStoredAuthentication(), [])
const fetcher = useMemo(() => new Fetcher(storedAuth), [storedAuth])
The stored token is internal to the object, no need to expose it in the rest of the function.
fetcher.updateAuthentication(auth)
const user = await fetchUser(fetcher)
setUser(user)
storeAuthentication(auth)
It is the job of the
setUser
function to persist in any storage. Don't try to make the storage separated from the state, create a hook that is always synced:interface UserContext {
user: User | null
setUser: (user: User) => void
The user may want to log out.
}
const SignedInUserContext = createContext<UserContext | null>(null)
const FetcherContext = createContext(new Fetcher())
This context is derived from the signed in user. Put them in the same context.
response.headers.get("Next-Authorization-Expiration-Date")!,
)
if (nextToken && expirationDate) {
this.auth = { token: nextToken, expirationDate }
If you check the nullability later, using a non-null assertion doesn't make sense.
const [errorMessages, setErrorMessages] = useState<string[]>([])
const [success, setSuccess] = useState(false)
const formRef = useRef<HTMLFormElement | null>(null)
A reference can always be null.
new FormData(formRef.current!) as Iterable<
[PropertyKey, string]
>,
)
Use the target of the event directly.
)
if (password !== confirmPassword) {
setErrorMessages(["Les mots de passe ne correspondent pas !"])
React offers a way to easily run code as each key stroke, and the browser has a custom validity API. Offer a quick feedback to the user.
When submitting the form, check its validity with
checkValidity
:src={profilePicture}
width={width}
height={width}
alt="profile-picture"
An ALT text is visible to the end user.
name="name"
type="text"
placeholder={"Nom d'utilisateur"}
defaultValue={user!.name}
Labels should be used to bind a legend text with the appropriate input via its ID. The autocomplete attribute allows the browser to sort its suggestions. A required field should have a required attribute. At last, React controlled inputs are great to skip the
FormData
browser API, and allow custom actions (like checking if the two passwords match easily).name="email"
type="email"
placeholder={"Addresse email"}
defaultValue={user!.email}
Address takes only one d in French. You may also want to take into account that two users may not share the same email. Your backend currently throws an exception when it is the case.
className="settings-input"
name="password"
type="password"
placeholder={"Mot de passe"}
Help password manager by indicating that the website wants a new password.
<button
className="settings-button"
type="submit"
onClick={submitForm}>
const fetcher = useAppFetcher()
const [user, setUser] = useUser()
The escape key may be used to close a modal as per ARIA patterns.
if (!show) return <></>
return (
<div id="profile-picture-popup">
: "invalid-input")
}
ref={urlRef}
type="input"
Use the
url
input type and alabel
element.</button>
<button
className={"settings-button"}
onClick={async () => {
It is a form, just use a form element and the appropriate event.
text-align: center;
vertical-align: center;
margin: 0;
}
No need to change the sign up form.
name="email"
id="email"
type="email"
placeholder={"Addresse email"}
Address in English, Adresse in French
381853b40c
to7b4a06a932
1 year ago7b4a06a932
tof9c42862e0
1 year ago9e8606184c
into master 1 year agoReviewers
9e8606184c
.