Stonks/spa/src/Search.js

94 lines
2.4 KiB
JavaScript

import React, { useMemo, useState } from "react";
import Fuse from "fuse.js";
import { Button, Center, Flex, Heading, Icon, Input } from "@chakra-ui/react";
import { FaUserCircle, FaArrowAltCircleRight } from "react-icons/fa";
import { Link } from "react-router-dom";
const Search = ({ statistics, players }) => {
const [searchTerm, setSearchTerm] = useState("");
const searchEngine = useMemo(() => {
const fullList = statistics
.map((s) => {
return {
type: "statistic",
value: s,
searchTerm: `${s.type} ${s.name}`,
};
})
.concat(
players.map((p) => {
return {
type: "player",
value: p,
searchTerm: p.name,
};
})
);
return new Fuse(fullList, {
minMatchCharLength: 3,
ignoreLocation: true,
shouldSort: true,
keys: ["searchTerm"],
});
}, [statistics, players]);
const searchResults = useMemo(() => {
return searchEngine.search(`'"${searchTerm}"'`);
}, [searchEngine, searchTerm]);
return (
<>
<Heading as="h1" size="4xl" my="8">
<Center>📈</Center>
</Heading>
<Input
placeholder="Find statistics or players"
size="lg"
variant="filled"
value={searchTerm}
onChange={(event) => setSearchTerm(event.target.value)}
/>
<Flex direction="column" align="stretch" my="4">
{searchResults.map((x, i) => {
return (
<Link
to={
x.item.type === "player"
? `/${x.item.type}/${x.item.value.id}`
: `/${x.item.type}/${x.item.value.type}/${x.item.value.name}`
}
>
<Button
key={i}
size="sm"
leftIcon={
x.item.type === "player" ? (
<Icon as={FaUserCircle} />
) : (
<Icon
as={FaArrowAltCircleRight}
transform="rotate(-45deg)"
/>
)
}
variant="ghost"
my="0.5"
display="block"
textAlign="left"
width="100%"
>
{x.item.searchTerm}
</Button>
</Link>
);
})}
</Flex>
</>
);
};
export default Search;