import clsx from "clsx"; import { InfoIcon, SearchIcon, XIcon } from "~/components/ui/icons/vendor"; import ColorBackgroundUtils from "~/utils/shared/colors/ColorBackgroundUtils"; import ColorFocusUtils from "~/utils/shared/colors/ColorFocusUtils"; import ColorFocusWithinUtils from "~/utils/shared/colors/ColorFocusWithinUtils"; import ColorPlaceholderUtils from "~/utils/shared/colors/ColorPlaceholderUtils"; import ColorRingUtils from "~/utils/shared/colors/ColorRingUtils"; import ColorTextUtils from "~/utils/shared/colors/ColorTextUtils"; import { KnowledgeBaseDto } from "../dtos/KnowledgeBaseDto"; import { Link, useLoaderData, useSearchParams } from "react-router"; import { useState, useEffect } from "react"; import { useDebounce } from "use-debounce"; import { KbSearchResultDto } from "../dtos/KbSearchResultDto"; import ColorBorderUtils from "~/utils/shared/colors/ColorBorderUtils"; import { Colors } from "~/application/enums/shared/Colors"; import { KbArticleDto } from "../dtos/KbArticleDto"; import ColorHoverUtils from "~/utils/shared/colors/ColorHoverUtils"; import { useTranslation } from "react-i18next"; export default function KbSearch({ kb, autoFocus }: { kb: KnowledgeBaseDto; autoFocus: boolean }) { const { t } = useTranslation(); let data = useLoaderData< | { search: KbSearchResultDto | undefined; } | undefined >(); let [search, setSearch] = useState(data?.search?.query); let [debouncedQuery] = useDebounce(search, 500); const [searchParams, setSearchParams] = useSearchParams(); useEffect(() => { if (debouncedQuery) { searchParams.set("q", debouncedQuery); } else { searchParams.delete("q"); } if (searchParams.toString()) { setSearchParams(searchParams); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [debouncedQuery]); return (
setSearch(e.target.value)} /> {search && ( )}
{search && data?.search !== undefined && (
{!data.search || data.search.articles?.length === 0 ? (

{t("knowledgeBase.search.noResults", { query: data.search.query })}

{t("knowledgeBase.search.tryDifferent")}

) : (
{data.search.articles.map((item) => ( ))}
)}
)}
); } function Highlight({ className, color, children, highlightText }: { className: string; color: Colors; children: string; highlightText: string }) { const parts = children.split(new RegExp(`(${highlightText})`, "gi")); return ( {parts.map((part, i) => part.toLowerCase() === highlightText.toLowerCase() ? ( {part} ) : ( part ) )} ); } function Card({ kb, item, highlightText }: { kb: KnowledgeBaseDto; item: KbArticleDto; highlightText: string }) { const contentLines = item.contentPublishedAsText.split("\n"); const highlightedLines = contentLines .map((line, i) => ({ line, isHighlighted: line.toLowerCase().includes(highlightText.toLowerCase()), i })) .filter(({ isHighlighted }) => isHighlighted) .slice(0, 3); return (

{item.title}

{item.description}

{highlightedLines.map(({ line, i }) => (

{line}

))}
); }