fix: Handle existing user when editing profile

This commit is contained in:
Thomas Camlong
2024-05-10 15:24:40 +02:00
parent f5d71aebb4
commit 6e2bd0ce11
2 changed files with 39 additions and 5 deletions

View File

@@ -5,10 +5,15 @@ import { Button, Stack, TextInput } from "@mantine/core";
import type { RouterOutputs } from "@homarr/api"; import type { RouterOutputs } from "@homarr/api";
import { clientApi } from "@homarr/api/client"; import { clientApi } from "@homarr/api/client";
import { useForm, zodResolver } from "@homarr/form"; import { useForm, zodResolver } from "@homarr/form";
import {
showErrorNotification,
showSuccessNotification,
} from "@homarr/notifications";
import { useI18n } from "@homarr/translation/client"; import { useI18n } from "@homarr/translation/client";
import { validation } from "@homarr/validation"; import { validation } from "@homarr/validation";
import { revalidatePathAction } from "~/app/revalidatePathAction"; import { revalidatePathAction } from "~/app/revalidatePathAction";
import { ErrorDisplay } from "~/components/utils";
interface ProfileAccordionProps { interface ProfileAccordionProps {
user: NonNullable<RouterOutputs["user"]["getById"]>; user: NonNullable<RouterOutputs["user"]["getById"]>;
@@ -16,11 +21,30 @@ interface ProfileAccordionProps {
export const ProfileAccordion = ({ user }: ProfileAccordionProps) => { export const ProfileAccordion = ({ user }: ProfileAccordionProps) => {
const t = useI18n(); const t = useI18n();
const { mutate, isPending } = clientApi.user.editProfile.useMutation({ const { mutate, isPending, isError, error } =
onSettled: async () => { clientApi.user.editProfile.useMutation({
await revalidatePathAction("/manage/users"); onError(error) {
}, showErrorNotification({
}); title: t(
"management.page.user.edit.section.profile.editProfile.title",
),
message: error.message,
});
},
onSuccess: () => {
showSuccessNotification({
title: t(
"management.page.user.edit.section.profile.editProfile.title",
),
message: t(
"management.page.user.edit.section.profile.editProfile.message.profileUpdated",
),
});
},
onSettled: async () => {
await revalidatePathAction("/manage/users");
},
});
const form = useForm({ const form = useForm({
initialValues: { initialValues: {
name: user.name ?? "", name: user.name ?? "",
@@ -41,6 +65,7 @@ export const ProfileAccordion = ({ user }: ProfileAccordionProps) => {
return ( return (
<form onSubmit={form.onSubmit(handleSubmit)}> <form onSubmit={form.onSubmit(handleSubmit)}>
<Stack> <Stack>
<ErrorDisplay hidden={!isError} message={error?.message} />
<TextInput <TextInput
label={t("user.field.username.label")} label={t("user.field.username.label")}
withAsterisk withAsterisk

View File

@@ -90,7 +90,16 @@ export const userRouter = createTRPCRouter({
.from(users) .from(users)
.where(eq(users.id, input.userId)) .where(eq(users.id, input.userId))
.limit(1); .limit(1);
const existingUser = await ctx.db.query.users.findFirst({
where: eq(users.name, input.form.name),
});
if (existingUser !== undefined) {
throw new TRPCError({
code: "FORBIDDEN",
message: `User ${input.form.name} already exists`,
});
}
const emailDirty = const emailDirty =
input.form.email && user[0]?.email !== input.form.email; input.form.email && user[0]?.email !== input.form.email;
await ctx.db await ctx.db