feat: use password input (#163)
* feat: use password input * chore: address pull request feedback * fix: typo in function name * fix: deepsource issues --------- Co-authored-by: Meier Lukas <meierschlumpf@gmail.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { useCallback, useMemo, useState } from "react";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useForm, zodResolver } from "@homarr/form";
|
||||
@@ -25,10 +25,15 @@ export const UserCreateStepperComponent = () => {
|
||||
|
||||
const stepperMax = 4;
|
||||
const [active, setActive] = useState(0);
|
||||
const nextStep = () =>
|
||||
setActive((current) => (current < stepperMax ? current + 1 : current));
|
||||
const prevStep = () =>
|
||||
setActive((current) => (current > 0 ? current - 1 : current));
|
||||
const nextStep = useCallback(
|
||||
() =>
|
||||
setActive((current) => (current < stepperMax ? current + 1 : current)),
|
||||
[setActive],
|
||||
);
|
||||
const prevStep = useCallback(
|
||||
() => setActive((current) => (current > 0 ? current - 1 : current)),
|
||||
[setActive],
|
||||
);
|
||||
const hasNext = active < stepperMax;
|
||||
const hasPrevious = active > 0;
|
||||
|
||||
@@ -52,39 +57,51 @@ export const UserCreateStepperComponent = () => {
|
||||
const securityForm = useForm({
|
||||
initialValues: {
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
},
|
||||
validate: zodResolver(
|
||||
z.object({
|
||||
password: validation.user.password,
|
||||
}),
|
||||
z
|
||||
.object({
|
||||
password: validation.user.password,
|
||||
confirmPassword: z.string(),
|
||||
})
|
||||
.refine((data) => data.password === data.confirmPassword, {
|
||||
path: ["confirmPassword"],
|
||||
message: "Passwords do not match",
|
||||
}),
|
||||
),
|
||||
validateInputOnBlur: true,
|
||||
validateInputOnChange: true,
|
||||
});
|
||||
|
||||
const allForms = [generalForm, securityForm];
|
||||
const allForms = useMemo(
|
||||
() => [generalForm, securityForm],
|
||||
[generalForm, securityForm],
|
||||
);
|
||||
|
||||
const isCurrentFormValid = allForms[active]
|
||||
? (allForms[active]!.isValid satisfies () => boolean)
|
||||
: () => true;
|
||||
const canNavigateToNextStep = isCurrentFormValid();
|
||||
|
||||
const controlledGoToNextStep = async () => {
|
||||
const controlledGoToNextStep = useCallback(async () => {
|
||||
if (active + 1 === stepperMax) {
|
||||
await mutateAsync({
|
||||
name: generalForm.values.username,
|
||||
username: generalForm.values.username,
|
||||
email: generalForm.values.email,
|
||||
password: securityForm.values.password,
|
||||
confirmPassword: securityForm.values.confirmPassword,
|
||||
});
|
||||
}
|
||||
nextStep();
|
||||
};
|
||||
}, [active, generalForm, mutateAsync, securityForm, nextStep]);
|
||||
|
||||
const reset = () => {
|
||||
const reset = useCallback(() => {
|
||||
setActive(0);
|
||||
allForms.forEach((form) => {
|
||||
form.reset();
|
||||
});
|
||||
};
|
||||
}, [allForms]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -134,6 +151,12 @@ export const UserCreateStepperComponent = () => {
|
||||
withAsterisk
|
||||
{...securityForm.getInputProps("password")}
|
||||
/>
|
||||
<PasswordInput
|
||||
label={t("step.security.field.confirmPassword.label")}
|
||||
variant="filled"
|
||||
withAsterisk
|
||||
{...securityForm.getInputProps("confirmPassword")}
|
||||
/>
|
||||
</Stack>
|
||||
</Card>
|
||||
</form>
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getScopedI18n } from "@homarr/translation/server";
|
||||
|
||||
import { UserCreateStepperComponent } from "./_components/stepper.component";
|
||||
import { UserCreateStepperComponent } from "./_components/create-user-stepper";
|
||||
|
||||
export async function generateMetadata() {
|
||||
const t = await getScopedI18n("management.page.user.create");
|
||||
|
||||
Reference in New Issue
Block a user