diff --git a/frontend/src/app/[locale]/search/error.tsx b/frontend/src/app/[locale]/search/error.tsx index 33fc600d2..dbe1baaec 100644 --- a/frontend/src/app/[locale]/search/error.tsx +++ b/frontend/src/app/[locale]/search/error.tsx @@ -1,12 +1,14 @@ "use client"; import QueryProvider from "src/app/[locale]/search/QueryProvider"; +import { FrontendErrorDetails } from "src/types/apiResponseTypes"; import { ServerSideSearchParams } from "src/types/searchRequestURLTypes"; import { Breakpoints, ErrorProps } from "src/types/uiTypes"; import { convertSearchParamsToProperTypes } from "src/utils/search/convertSearchParamsToProperTypes"; import { useTranslations } from "next-intl"; import { useEffect } from "react"; +import { Alert } from "@trussworks/react-uswds"; import ContentDisplayToggle from "src/components/ContentDisplayToggle"; import SearchBar from "src/components/search/SearchBar"; @@ -18,6 +20,7 @@ export interface ParsedError { searchInputs: ServerSideSearchParams; status: number; type: string; + details?: FrontendErrorDetails; } function isValidJSON(str: string) { @@ -73,6 +76,16 @@ export default function SearchError({ error }: ErrorProps) { console.error(error); }, [error]); + // note that the validation error will contain untranslated strings + const ErrorAlert = + parsedErrorData.details && parsedErrorData.type === "ValidationError" ? ( + + {`Error in ${parsedErrorData.details.field || "a search field"}: ${parsedErrorData.details.message || "adjust your search and try again"}`} + + ) : ( + + ); + return (
@@ -95,9 +108,7 @@ export default function SearchError({ error }: ErrorProps) { />
-
- -
+
{ErrorAlert}
diff --git a/frontend/src/components/search/SearchBar.tsx b/frontend/src/components/search/SearchBar.tsx index ba6917ac6..c12d52b4d 100644 --- a/frontend/src/components/search/SearchBar.tsx +++ b/frontend/src/components/search/SearchBar.tsx @@ -1,11 +1,12 @@ "use client"; +import clsx from "clsx"; import { QueryContext } from "src/app/[locale]/search/QueryProvider"; import { useSearchParamUpdater } from "src/hooks/useSearchParamUpdater"; import { useTranslations } from "next-intl"; -import { useContext, useEffect, useRef } from "react"; -import { Icon } from "@trussworks/react-uswds"; +import { useContext, useEffect, useRef, useState } from "react"; +import { ErrorMessage, Icon } from "@trussworks/react-uswds"; interface SearchBarProps { query: string | null | undefined; @@ -16,8 +17,16 @@ export default function SearchBar({ query }: SearchBarProps) { const { queryTerm, updateQueryTerm } = useContext(QueryContext); const { updateQueryParams, searchParams } = useSearchParamUpdater(); const t = useTranslations("Search"); + const [validationError, setValidationError] = useState(); const handleSubmit = () => { + if (queryTerm && queryTerm.length > 99) { + setValidationError(t("tooLongError")); + return; + } + if (validationError) { + setValidationError(undefined); + } updateQueryParams("", "query", queryTerm, false); }; @@ -38,7 +47,11 @@ export default function SearchBar({ query }: SearchBarProps) { }, [searchParams, updateQueryParams]); return ( -
+