Fix profile accordion error display

This commit is contained in:
ajnart
2024-05-10 20:02:57 +02:00
parent 6e2bd0ce11
commit 543bfc0835
5 changed files with 21 additions and 15 deletions

View File

@@ -13,7 +13,6 @@ 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"]>;
@@ -21,7 +20,7 @@ interface ProfileAccordionProps {
export const ProfileAccordion = ({ user }: ProfileAccordionProps) => { export const ProfileAccordion = ({ user }: ProfileAccordionProps) => {
const t = useI18n(); const t = useI18n();
const { mutate, isPending, isError, error } = const { mutate, isPending } =
clientApi.user.editProfile.useMutation({ clientApi.user.editProfile.useMutation({
onError(error) { onError(error) {
showErrorNotification({ showErrorNotification({
@@ -65,7 +64,6 @@ 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

@@ -15,10 +15,10 @@ import { useCallback, useMemo, useState } from "react";
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 } from "@homarr/notifications";
import { useScopedI18n } from "@homarr/translation/client"; import { useScopedI18n } from "@homarr/translation/client";
import { validation, z } from "@homarr/validation"; import { validation, z } from "@homarr/validation";
import { ErrorDisplay } from "~/components/utils";
import { StepperNavigationComponent } from "./stepper-navigation.component"; import { StepperNavigationComponent } from "./stepper-navigation.component";
export const UserCreateStepperComponent = () => { export const UserCreateStepperComponent = () => {
@@ -39,8 +39,16 @@ export const UserCreateStepperComponent = () => {
const hasNext = active < stepperMax; const hasNext = active < stepperMax;
const hasPrevious = active > 0; const hasPrevious = active > 0;
const { mutateAsync, isPending, isError, error } = const { mutateAsync, isPending } = clientApi.user.create.useMutation({
clientApi.user.create.useMutation(); onError(error) {
showErrorNotification({
autoClose: false,
id: "create-user-error",
title: t("step.error.title"),
message: error.message,
});
},
});
const generalForm = useForm({ const generalForm = useForm({
initialValues: { initialValues: {
@@ -109,7 +117,6 @@ export const UserCreateStepperComponent = () => {
return ( return (
<> <>
<Title mb="md">{t("title")}</Title> <Title mb="md">{t("title")}</Title>
<ErrorDisplay hidden={!isError} message={error?.message} my="lg" />
<Stepper <Stepper
active={active} active={active}
onStepClick={setActive} onStepClick={setActive}

View File

@@ -33,11 +33,11 @@ export const userRouter = createTRPCRouter({
.input(validation.user.create) .input(validation.user.create)
.mutation(async ({ ctx, input }) => { .mutation(async ({ ctx, input }) => {
const user = await ctx.db.query.users.findFirst({ const user = await ctx.db.query.users.findFirst({
where: eq(users.name, input.username), where: eq(users.name, input.username.toLowerCase()),
}); });
if (user !== undefined) { if (user !== undefined) {
throw new TRPCError({ throw new TRPCError({
code: "FORBIDDEN", code: "CONFLICT",
message: "User already exists", message: "User already exists",
}); });
} }
@@ -91,12 +91,12 @@ export const userRouter = createTRPCRouter({
.where(eq(users.id, input.userId)) .where(eq(users.id, input.userId))
.limit(1); .limit(1);
const existingUser = await ctx.db.query.users.findFirst({ const existingUser = await ctx.db.query.users.findFirst({
where: eq(users.name, input.form.name), where: eq(users.name, input.form.name.toLowerCase()),
}); });
if (existingUser !== undefined) { if (existingUser !== undefined) {
throw new TRPCError({ throw new TRPCError({
code: "FORBIDDEN", code: "CONFLICT",
message: `User ${input.form.name} already exists`, message: `User ${input.form.name} already exists`,
}); });
} }

View File

@@ -2,16 +2,14 @@ import type { NotificationData } from "@mantine/notifications";
import { notifications } from "@mantine/notifications"; import { notifications } from "@mantine/notifications";
import { IconCheck, IconX } from "@tabler/icons-react"; import { IconCheck, IconX } from "@tabler/icons-react";
type CommonNotificationProps = Pick<NotificationData, "title" | "message">; export const showSuccessNotification = (props: NotificationData) =>
export const showSuccessNotification = (props: CommonNotificationProps) =>
notifications.show({ notifications.show({
...props, ...props,
color: "teal", color: "teal",
icon: <IconCheck size={20} />, icon: <IconCheck size={20} />,
}); });
export const showErrorNotification = (props: CommonNotificationProps) => export const showErrorNotification = (props: NotificationData) =>
notifications.show({ notifications.show({
...props, ...props,
color: "red", color: "red",

View File

@@ -1108,6 +1108,9 @@ export default {
completed: { completed: {
title: "User created", title: "User created",
}, },
error: {
title: "User creation failed",
},
}, },
action: { action: {
createAnother: "Create another user", createAnother: "Create another user",