diff --git a/web/sdk/admin/components/CustomField.tsx b/web/sdk/admin/components/CustomField.tsx index deaa40bbf..f5eb36d0c 100644 --- a/web/sdk/admin/components/CustomField.tsx +++ b/web/sdk/admin/components/CustomField.tsx @@ -8,9 +8,15 @@ import { import { Flex, Select, Switch, Text, TextArea, Input } from "@raystack/apsara"; import React, { CSSProperties } from "react"; -import { Control, Controller, UseFormRegister } from "react-hook-form"; +import { + Control, + Controller, + UseFormRegister, + useFormState, +} from "react-hook-form"; import { capitalizeFirstLetter } from "../utils/helper"; import Skeleton from "react-loading-skeleton"; +import styles from "./custom-field.module.css"; type CustomFieldNameProps = { name: string; @@ -40,6 +46,8 @@ export const CustomFieldName = ({ CustomFieldNameProps & React.RefAttributes) => { const inputTitle = capitalizeFirstLetter(title || name); + const { errors } = useFormState({ control, name }); + const errorMessage = errors?.[name]?.message as string | undefined; return ( )} + {errorMessage ? ( + + {errorMessage} + + ) : null} ); diff --git a/web/sdk/admin/components/custom-field.module.css b/web/sdk/admin/components/custom-field.module.css new file mode 100644 index 000000000..c8242a35f --- /dev/null +++ b/web/sdk/admin/components/custom-field.module.css @@ -0,0 +1,3 @@ +.errorMessage { + color: var(--rs-color-foreground-danger-primary); +} diff --git a/web/sdk/admin/views/webhooks/webhooks/create/index.tsx b/web/sdk/admin/views/webhooks/webhooks/create/index.tsx index 1a3db2803..cf1a5e93f 100644 --- a/web/sdk/admin/views/webhooks/webhooks/create/index.tsx +++ b/web/sdk/admin/views/webhooks/webhooks/create/index.tsx @@ -1,4 +1,4 @@ -import { useCallback } from "react"; +import { useCallback, useEffect } from "react"; import { Button, Flex, Drawer, toastManager } from "@raystack/apsara"; import { SheetHeader } from "../../../../components/SheetHeader"; import { SheetFooter } from "../../../../components/SheetFooter"; @@ -23,7 +23,7 @@ const NewWebookSchema = z.object({ description: z .string() .trim() - .min(3, { message: "Must be 10 or more characters long" }), + .min(3, { message: "Must be 3 or more characters long" }), state: z.boolean().default(false), subscribed_events: z.array(z.string()).default([]), }); @@ -48,9 +48,27 @@ export default function CreateWebhooks({ open = false, onClose: onCloseProp }: C const methods = useForm({ resolver: zodResolver(NewWebookSchema), - defaultValues: {}, + defaultValues: { + url: "", + description: "", + state: false, + subscribed_events: [], + }, }); + // The drawer stays mounted and only toggles `open`, so the form keeps its + // previous values. Reset to a clean state each time it opens. + useEffect(() => { + if (open) { + methods.reset({ + url: "", + description: "", + state: false, + subscribed_events: [], + }); + } + }, [open, methods.reset]); + const onSubmit = async (data: NewWebhook) => { try { const body: WebhookRequestBody = create(WebhookRequestBodySchema, { @@ -67,6 +85,12 @@ export default function CreateWebhooks({ open = false, onClose: onCloseProp }: C toastManager.add({ title: "Webhook created", type: "success" }); await invalidateWebhooksList(); onOpenChange(); + } else { + toastManager.add({ + title: "Something went wrong", + description: "Webhook was not created. Please try again.", + type: "error", + }); } } catch (err) { console.error("Failed to create webhook:", err); diff --git a/web/sdk/admin/views/webhooks/webhooks/update/index.tsx b/web/sdk/admin/views/webhooks/webhooks/update/index.tsx index 0f8e22068..3da2b4692 100644 --- a/web/sdk/admin/views/webhooks/webhooks/update/index.tsx +++ b/web/sdk/admin/views/webhooks/webhooks/update/index.tsx @@ -23,7 +23,7 @@ const UpdateWebhookSchema = z.object({ description: z .string() .trim() - .min(3, { message: "Must be 10 or more characters long" }), + .min(3, { message: "Must be 3 or more characters long" }), state: z.boolean().default(false), subscribed_events: z.array(z.string()).default([]), });