diff --git a/packages/validation/src/form/i18n.ts b/packages/validation/src/form/i18n.ts index 5a8e4f65d..1f94a5c8c 100644 --- a/packages/validation/src/form/i18n.ts +++ b/packages/validation/src/form/i18n.ts @@ -11,10 +11,11 @@ export const zodErrorMap = < ) => { return (issue: z.ZodIssueOptionalMessage, ctx: ErrorMapCtx) => { const error = handleZodError(issue, ctx); - if ("message" in error && error.message) + if ("message" in error && error.message) { return { message: error.message, }; + } return { message: t(error.key ? `common.zod.${error.key}` : "common.zod.errors.default", error.params ?? {}), }; @@ -103,6 +104,7 @@ const handleZodError = (issue: z.ZodIssueOptionalMessage, ctx: ErrorMapCtx) => { params: {}, } as const; } + if (issue.code === ZodIssueCode.invalid_string) { return handleStringError(issue); } @@ -112,6 +114,12 @@ const handleZodError = (issue: z.ZodIssueOptionalMessage, ctx: ErrorMapCtx) => { if (issue.code === ZodIssueCode.too_big) { return handleTooBigError(issue); } + if (issue.code === ZodIssueCode.invalid_type && ctx.data === "") { + return { + key: "errors.required", + params: {}, + } as const; + } if (issue.code === ZodIssueCode.custom && issue.params?.i18n) { const { i18n } = issue.params as CustomErrorParams; return { diff --git a/packages/validation/src/location.ts b/packages/validation/src/location.ts index 2b9b12f2f..b8d71ca3c 100644 --- a/packages/validation/src/location.ts +++ b/packages/validation/src/location.ts @@ -14,9 +14,18 @@ const searchCityInput = z.object({ query: z.string(), }); -const searchCityOutput = z.object({ - results: z.array(citySchema), -}); +const searchCityOutput = z + .object({ + results: z.array(citySchema), + }) + .or( + z + .object({ + generationtime_ms: z.number(), + }) + .refine((data) => Object.keys(data).length === 1, { message: "Invalid response" }) + .transform(() => ({ results: [] })), // We fallback to empty array if no results + ); export const locationSchemas = { searchCity: { diff --git a/packages/widgets/src/_inputs/widget-location-input.tsx b/packages/widgets/src/_inputs/widget-location-input.tsx index baa6aca42..b37c1817f 100644 --- a/packages/widgets/src/_inputs/widget-location-input.tsx +++ b/packages/widgets/src/_inputs/widget-location-input.tsx @@ -1,6 +1,5 @@ "use client"; -import type { ChangeEvent } from "react"; import { useCallback } from "react"; import { ActionIcon, @@ -33,23 +32,18 @@ export const WidgetLocationInput = ({ property, kind }: CommonWidgetInputProps<" const tLocation = useScopedI18n("widget.common.location"); const form = useFormContext(); const { openModal } = useModalAction(LocationSearchModal); - const value = form.values.options[property] as OptionLocation; + const inputProps = form.getInputProps(`options.${property}`); + const value = inputProps.value as OptionLocation; const selectionEnabled = value.name.length > 1; - const handleChange = form.getInputProps(`options.${property}`).onChange as LocationOnChange; + const handleChange = inputProps.onChange as LocationOnChange; const unknownLocation = tLocation("unknownLocation"); - const onQueryChange = useCallback((event: ChangeEvent) => { - handleChange({ - name: event.currentTarget.value, - longitude: "", - latitude: "", - }); - }, []); - const onLocationSelect = useCallback( (location: OptionLocation) => { handleChange(location); + form.clearFieldError(`options.${property}.latitude`); + form.clearFieldError(`options.${property}.longitude`); }, [handleChange], ); @@ -63,35 +57,21 @@ export const WidgetLocationInput = ({ property, kind }: CommonWidgetInputProps<" }); }, [selectionEnabled, value.name, onLocationSelect, openModal]); - const onLatitudeChange = useCallback( - (inputValue: number | string) => { - if (typeof inputValue !== "number") return; - handleChange({ - ...value, - name: unknownLocation, - latitude: inputValue, - }); - }, - [value], - ); + form.watch(`options.${property}.latitude`, ({ value }) => { + if (typeof value !== "number") return; + form.setFieldValue(`options.${property}.name`, unknownLocation); + }); - const onLongitudeChange = useCallback( - (inputValue: number | string) => { - if (typeof inputValue !== "number") return; - handleChange({ - ...value, - name: unknownLocation, - longitude: inputValue, - }); - }, - [value], - ); + form.watch(`options.${property}.longitude`, ({ value }) => { + if (typeof value !== "number") return; + form.setFieldValue(`options.${property}.name`, unknownLocation); + }); return (
- +