feat: add change password form (#199)
This commit is contained in:
@@ -1,15 +1,13 @@
|
||||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import { useRouter } from "next/router";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
import type { RouterOutputs } from "@homarr/api";
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { Button, Divider, Group, Stack, Text } from "@homarr/ui";
|
||||
|
||||
import { revalidatePathAction } from "~/app/revalidatePathAction";
|
||||
|
||||
interface DangerZoneAccordionProps {
|
||||
user: NonNullable<RouterOutputs["user"]["getById"]>;
|
||||
}
|
||||
@@ -19,9 +17,8 @@ export const DangerZoneAccordion = ({ user }: DangerZoneAccordionProps) => {
|
||||
const router = useRouter();
|
||||
const { mutateAsync: mutateUserDeletionAsync } =
|
||||
clientApi.user.delete.useMutation({
|
||||
onSettled: async () => {
|
||||
await router.push("/manage/users");
|
||||
await revalidatePathAction("/manage/users");
|
||||
onSettled: () => {
|
||||
router.push("/manage/users");
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
"use client";
|
||||
|
||||
import type { RouterOutputs } from "@homarr/api";
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { useForm, zodResolver } from "@homarr/form";
|
||||
import { showSuccessNotification } from "@homarr/notifications";
|
||||
import { useI18n } from "@homarr/translation/client";
|
||||
import { Button, PasswordInput, Stack, Title } from "@homarr/ui";
|
||||
import { validation } from "@homarr/validation";
|
||||
|
||||
import { revalidatePathAction } from "~/app/revalidatePathAction";
|
||||
|
||||
interface SecurityAccordionComponentProps {
|
||||
user: NonNullable<RouterOutputs["user"]["getById"]>;
|
||||
}
|
||||
|
||||
export const SecurityAccordionComponent = ({
|
||||
user,
|
||||
}: SecurityAccordionComponentProps) => {
|
||||
return (
|
||||
<Stack>
|
||||
<ChangePasswordForm user={user} />
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
const ChangePasswordForm = ({
|
||||
user,
|
||||
}: {
|
||||
user: NonNullable<RouterOutputs["user"]["getById"]>;
|
||||
}) => {
|
||||
const t = useI18n();
|
||||
const { mutate, isPending } = clientApi.user.changePassword.useMutation({
|
||||
onSettled: async () => {
|
||||
await revalidatePathAction(`/manage/users/${user.id}`);
|
||||
showSuccessNotification({
|
||||
title: t(
|
||||
"management.page.user.edit.section.security.changePassword.message.passwordUpdated",
|
||||
),
|
||||
message: "",
|
||||
});
|
||||
},
|
||||
});
|
||||
const form = useForm({
|
||||
initialValues: {
|
||||
userId: user.id,
|
||||
password: "",
|
||||
},
|
||||
validate: zodResolver(validation.user.changePassword),
|
||||
validateInputOnBlur: true,
|
||||
validateInputOnChange: true,
|
||||
});
|
||||
|
||||
const handleSubmit = () => {
|
||||
mutate(form.values);
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={form.onSubmit(handleSubmit)}>
|
||||
<Stack>
|
||||
<Stack gap={0}>
|
||||
<Title order={5}>
|
||||
{t(
|
||||
"management.page.user.edit.section.security.changePassword.title",
|
||||
)}
|
||||
</Title>
|
||||
<PasswordInput
|
||||
label={t(
|
||||
"management.page.user.edit.section.security.changePassword.form.password.label",
|
||||
)}
|
||||
{...form.getInputProps("password")}
|
||||
/>
|
||||
</Stack>
|
||||
<Button loading={isPending} type="submit" disabled={!form.isValid()}>
|
||||
{t("common.action.confirm")}
|
||||
</Button>
|
||||
</Stack>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
@@ -20,6 +20,7 @@ import {
|
||||
import { api } from "~/trpc/server";
|
||||
import { DangerZoneAccordion } from "./_components/dangerZone.accordion";
|
||||
import { ProfileAccordion } from "./_components/profile.accordion";
|
||||
import { SecurityAccordionComponent } from "./_components/security.accordion";
|
||||
|
||||
interface Props {
|
||||
params: {
|
||||
@@ -80,12 +81,14 @@ export default async function EditUserPage({ params }: Props) {
|
||||
{t("section.security.title")}
|
||||
</Text>
|
||||
</AccordionControl>
|
||||
<AccordionPanel></AccordionPanel>
|
||||
<AccordionPanel>
|
||||
<SecurityAccordionComponent user={user} />
|
||||
</AccordionPanel>
|
||||
</AccordionItem>
|
||||
<AccordionItem
|
||||
styles={{
|
||||
item: {
|
||||
"--__item-border-color": "rgba(248,81,73,0.4)",
|
||||
borderColor: "rgba(248,81,73,0.4)",
|
||||
borderWidth: 4,
|
||||
},
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user