wip: search page
This commit is contained in:
@@ -4,3 +4,4 @@ export * from "./image";
|
||||
export * from "./settings";
|
||||
export * from "./login";
|
||||
export * from "./entity";
|
||||
export * from "./search";
|
||||
|
||||
48
frontend/src/pages/search/index.tsx
Normal file
48
frontend/src/pages/search/index.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import { Component, createSignal } from "solid-js";
|
||||
import { Search } from "@kobalte/core/search";
|
||||
import { IconSearch } from "@tabler/icons-solidjs";
|
||||
import { useSearch } from "./search";
|
||||
import { UserImage } from "@network/index";
|
||||
|
||||
export const SearchPage: Component = () => {
|
||||
const fuse = useSearch();
|
||||
|
||||
const [searchItems, setSearchItems] = createSignal<UserImage[]>([]);
|
||||
|
||||
return (
|
||||
<Search
|
||||
options={searchItems()}
|
||||
onInputChange={(e) => {
|
||||
const items = fuse().search(e);
|
||||
setSearchItems(items.map((i) => i.item.image));
|
||||
}}
|
||||
itemComponent={(props) => (
|
||||
<Search.Item item={props.item}>
|
||||
<Search.ItemLabel>
|
||||
{JSON.stringify(props.item.rawValue)}
|
||||
</Search.ItemLabel>
|
||||
</Search.Item>
|
||||
)}
|
||||
>
|
||||
<Search.Label />
|
||||
<Search.Control class="flex">
|
||||
<Search.Indicator class="bg-neutral-200 p-4 rounded-l-xl">
|
||||
<Search.Icon>
|
||||
<IconSearch />
|
||||
</Search.Icon>
|
||||
</Search.Indicator>
|
||||
<Search.Input
|
||||
class="w-full p-4 font-bold text-xl rounded-r-xl"
|
||||
placeholder="Woking Station..."
|
||||
/>
|
||||
</Search.Control>
|
||||
<Search.Portal>
|
||||
<Search.Content class="w-full rounded-xl bg-white p-4">
|
||||
<Search.Arrow />
|
||||
<Search.Listbox />
|
||||
<Search.NoResult>No result found</Search.NoResult>
|
||||
</Search.Content>
|
||||
</Search.Portal>
|
||||
</Search>
|
||||
);
|
||||
};
|
||||
47
frontend/src/pages/search/search.ts
Normal file
47
frontend/src/pages/search/search.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { useSearchImageContext } from "@contexts/SearchImageContext";
|
||||
import { UserImage } from "@network/index";
|
||||
import { createMemo } from "solid-js";
|
||||
import Fuse from "fuse.js";
|
||||
|
||||
const getSearchTerms = (image: UserImage): Array<string> => {
|
||||
switch (image.type) {
|
||||
case "location":
|
||||
return [
|
||||
image.data.Name,
|
||||
image.data.Description,
|
||||
image.data.Address,
|
||||
image.data.CreatedAt,
|
||||
].filter((i) => i != null);
|
||||
case "event":
|
||||
return [
|
||||
image.data.Name,
|
||||
image.data.Description,
|
||||
image.data.CreatedAt,
|
||||
].filter((i) => i != null);
|
||||
case "contact":
|
||||
return [
|
||||
image.data.Name,
|
||||
image.data.Description,
|
||||
image.data.CreatedAt,
|
||||
image.data.Email,
|
||||
image.data.PhoneNumber,
|
||||
].filter((i) => i != null);
|
||||
case "note":
|
||||
return [
|
||||
image.data.Name,
|
||||
image.data.Description,
|
||||
image.data.CreatedAt,
|
||||
image.data.Content,
|
||||
].filter((i) => i != null);
|
||||
}
|
||||
};
|
||||
|
||||
export const useSearch = () => {
|
||||
const { images } = useSearchImageContext();
|
||||
|
||||
const searchTerms = createMemo(() =>
|
||||
images().map((i) => ({ image: i, searchTerms: getSearchTerms(i) })),
|
||||
);
|
||||
|
||||
return () => new Fuse(searchTerms(), { keys: ["searchTerms"] });
|
||||
};
|
||||
Reference in New Issue
Block a user