refactor password change form

This commit is contained in:
f0x 2023-01-04 21:12:57 +00:00
parent f6369ccae1
commit ceba7bc3bc
7 changed files with 55 additions and 57 deletions

View file

@ -93,14 +93,14 @@ function Checkbox({label, field, ...inputProps}) {
}
function Select({label, field, options, ...inputProps}) {
const {onChange, value} = field;
const {onChange, value, ref} = field;
return (
<div className="form-field select">
<label>
{label}
<select
{...{onChange, value}}
{...{onChange, value, ref}}
{...inputProps}
>
{options}

View file

@ -23,8 +23,6 @@ const React = require("react");
module.exports = function useBoolInput({name, Name}, {defaultValue=false} = {}) {
const [value, setValue] = React.useState(defaultValue);
console.log("bool", name, value, defaultValue);
function onChange(e) {
setValue(e.target.checked);
}

View file

@ -39,7 +39,6 @@ module.exports = function useTextInput({name, Name}, {validator, defaultValue=""
let res = validator(text);
setValid(res == "");
textRef.current.setCustomValidity(res);
textRef.current.reportValidity();
}
}, [text, textRef, validator]);

View file

@ -18,6 +18,8 @@
"use strict";
const base = require("./base");
module.exports = {
unwrapRes(res) {
if (res.error != undefined) {
@ -25,5 +27,17 @@ module.exports = {
} else {
return res.data;
}
},
updateCacheOnMutation(queryName, arg = undefined) {
// https://redux-toolkit.js.org/rtk-query/usage/manual-cache-updates#pessimistic-updates
return {
onQueryStarted: (_, { dispatch, queryFulfilled}) => {
queryFulfilled.then(({data: newData}) => {
dispatch(base.util.updateQueryData(queryName, arg, (draft) => {
Object.assign(draft, newData);
}));
});
}
};
}
};

View file

@ -18,17 +18,14 @@
"use strict";
// const Promise = require("bluebird");
// const { unwrapRes } = require("./lib");
const { updateCacheOnMutation } = require("./lib");
const base = require("./base");
const endpoints = (build) => ({
verifyCredentials: build.query({
query: () => ({
url: `/api/v1/accounts/verify_credentials`
}),
providesTags: [{type: "User", id: "SELF"}]
})
}),
updateCredentials: build.mutation({
query: (formData) => ({
@ -37,7 +34,14 @@ const endpoints = (build) => ({
asForm: true,
body: formData
}),
invalidatesTags: [{type: "User", id: "SELF"}]
...updateCacheOnMutation("verifyCredentials")
}),
passwordChange: build.mutation({
query: (data) => ({
method: "POST",
url: `/api/v1/user/password_change`,
body: data
})
})
});

View file

@ -337,6 +337,12 @@ section.with-sidebar > div, section.with-sidebar > form {
}
}
form {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.form-field label {
font-weight: bold;
}
@ -346,7 +352,6 @@ section.with-sidebar > div, section.with-sidebar > form {
display: flex;
}
span.form-info {
flex: 1 1 auto;
overflow: hidden;

View file

@ -112,56 +112,34 @@ function UserSettingsForm({source}) {
}
function PasswordChange() {
const dispatch = Redux.useDispatch();
const form = {
oldPassword: useTextInput("old_password"),
newPassword: useTextInput("old_password", {validator(val) {
if (val != "" && val == form.oldPassword.value) {
return "New password same as old password";
}
return "";
}})
};
const [errorMsg, setError] = React.useState("");
const [statusMsg, setStatus] = React.useState("");
const [oldPassword, setOldPassword] = React.useState("");
const [newPassword, setNewPassword] = React.useState("");
const [newPasswordConfirm, setNewPasswordConfirm] = React.useState("");
function changePassword() {
if (newPassword !== newPasswordConfirm) {
setError("New password and confirm new password did not match!");
return;
const verifyNewPassword = useTextInput("verifyNewPassword", {
validator(val) {
if (val != "" && val != form.newPassword.value) {
return "Passwords do not match";
}
return "";
}
});
setStatus("PATCHing");
setError("");
return Promise.try(() => {
let data = {
old_password: oldPassword,
new_password: newPassword
};
return dispatch(api.apiCall("POST", "/api/v1/user/password_change", data, "form"));
}).then(() => {
setStatus("Saved!");
setOldPassword("");
setNewPassword("");
setNewPasswordConfirm("");
}).catch((e) => {
setError(e.message);
setStatus("");
});
}
const [result, submitForm] = useFormSubmit(form, query.usePasswordChangeMutation());
return (
<>
<form className="change-password" onSubmit={submitForm}>
<h1>Change password</h1>
<div className="labelinput">
<label htmlFor="password">Current password</label>
<input name="password" id="password" type="password" autoComplete="current-password" value={oldPassword} onChange={(e) => setOldPassword(e.target.value)} />
</div>
<div className="labelinput">
<label htmlFor="new-password">New password</label>
<input name="new-password" id="new-password" type="password" autoComplete="new-password" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} />
</div>
<div className="labelinput">
<label htmlFor="confirm-new-password">Confirm new password</label>
<input name="confirm-new-password" id="confirm-new-password" type="password" autoComplete="new-password" value={newPasswordConfirm} onChange={(e) => setNewPasswordConfirm(e.target.value)} />
</div>
<Submit onClick={changePassword} label="Save new password" errorMsg={errorMsg} statusMsg={statusMsg}/>
</>
<TextInput type="password" field={form.oldPassword} label="Current password"/>
<TextInput type="password" field={form.newPassword} label="New password"/>
<TextInput type="password" field={verifyNewPassword} label="Confirm new password"/>
<MutationButton text="Change password" result={result}/>
</form>
);
}