Files
docmost/apps/client/src/features/search/share-search-spotlight.tsx
Philip Okugbe c26a851d52 feat: enhance public sharing (#1057)
* fix tree nodes sort

* remove comment mark in shares

* remove clickoutside hook for now

* feat: search in shared pages

* fix user-select

* use Link

* render page icons
2025-04-23 14:32:35 +01:00

88 lines
2.5 KiB
TypeScript

import { Group, Center, Text } from "@mantine/core";
import { Spotlight } from "@mantine/spotlight";
import { IconSearch } from "@tabler/icons-react";
import React, { useState } from "react";
import { Link } from "react-router-dom";
import { useDebouncedValue } from "@mantine/hooks";
import { useShareSearchQuery } from "@/features/search/queries/search-query";
import { buildSharedPageUrl } from "@/features/page/page.utils.ts";
import { getPageIcon } from "@/lib";
import { useTranslation } from "react-i18next";
import { shareSearchSpotlightStore } from "@/features/search/constants.ts";
interface ShareSearchSpotlightProps {
shareId?: string;
}
export function ShareSearchSpotlight({ shareId }: ShareSearchSpotlightProps) {
const { t } = useTranslation();
const [query, setQuery] = useState("");
const [debouncedSearchQuery] = useDebouncedValue(query, 300);
const { data: searchResults } = useShareSearchQuery({
query: debouncedSearchQuery,
shareId,
});
const pages = (
searchResults && searchResults.length > 0 ? searchResults : []
).map((page) => (
<Spotlight.Action
key={page.id}
component={Link}
//@ts-ignore
to={buildSharedPageUrl({
shareId: shareId,
pageTitle: page.title,
pageSlugId: page.slugId,
})}
style={{ userSelect: "none" }}
>
<Group wrap="nowrap" w="100%">
<Center>{getPageIcon(page?.icon)}</Center>
<div style={{ flex: 1 }}>
<Text>{page.title}</Text>
{page?.highlight && (
<Text
opacity={0.6}
size="xs"
dangerouslySetInnerHTML={{ __html: page.highlight }}
/>
)}
</div>
</Group>
</Spotlight.Action>
));
return (
<>
<Spotlight.Root
store={shareSearchSpotlightStore}
query={query}
onQueryChange={setQuery}
scrollable
overlayProps={{
backgroundOpacity: 0.55,
}}
>
<Spotlight.Search
placeholder={t("Search...")}
leftSection={<IconSearch size={20} stroke={1.5} />}
/>
<Spotlight.ActionsList>
{query.length === 0 && pages.length === 0 && (
<Spotlight.Empty>{t("Start typing to search...")}</Spotlight.Empty>
)}
{query.length > 0 && pages.length === 0 && (
<Spotlight.Empty>{t("No results found...")}</Spotlight.Empty>
)}
{pages.length > 0 && pages}
</Spotlight.ActionsList>
</Spotlight.Root>
</>
);
}