impress-2020/src/SearchPanel.js

104 lines
2.5 KiB
JavaScript
Raw Normal View History

2020-04-24 21:17:03 -07:00
import React from "react";
import gql from "graphql-tag";
import { Box, Text } from "@chakra-ui/core";
import { useQuery } from "@apollo/react-hooks";
import { Delay, Heading1, useDebounce } from "./util";
import ItemList, { ItemListSkeleton } from "./ItemList";
import { itemAppearanceFragment } from "./OutfitPreview";
function SearchPanel({ query, outfitState, dispatchToOutfit }) {
return (
<Box color="green.800">
<Heading1 mb="6">Searching for "{query}"</Heading1>
<SearchResults
query={query}
outfitState={outfitState}
dispatchToOutfit={dispatchToOutfit}
/>
</Box>
);
}
function SearchResults({ query, outfitState, dispatchToOutfit }) {
const { wornItemIds, speciesId, colorId } = outfitState;
const debouncedQuery = useDebounce(query, 300, { waitForFirstPause: true });
const { loading, error, data, variables } = useQuery(
gql`
query($query: String!, $speciesId: ID!, $colorId: ID!) {
itemSearch(query: $query) {
# TODO: De-dupe this from useOutfitState?
id
name
thumbnailUrl
appearanceOn(speciesId: $speciesId, colorId: $colorId) {
# This enables us to quickly show the item when the user clicks it!
...AppearanceForOutfitPreview
# This is used to group items by zone, and to detect conflicts when
# wearing a new item.
layers {
zone {
id
label
}
}
}
}
}
${itemAppearanceFragment}
`,
{
variables: { query: debouncedQuery, speciesId, colorId },
skip: debouncedQuery === null,
}
);
if (loading || variables.query !== query) {
return (
<Delay ms={500}>
2020-04-24 21:23:03 -07:00
<ItemListSkeleton count={8} />
2020-04-24 21:17:03 -07:00
</Delay>
);
}
if (error) {
return (
<Text color="green.500">
We hit an error trying to load your search results{" "}
<span role="img" aria-label="(sweat emoji)">
😓
</span>{" "}
Try again?
</Text>
);
}
const items = data.itemSearch;
if (items.length === 0) {
return (
<Text color="green.500">
We couldn't find any matching items{" "}
<span role="img" aria-label="(thinking emoji)">
🤔
</span>{" "}
Try again?
</Text>
);
}
return (
<ItemList
items={items}
outfitState={outfitState}
2020-04-24 21:17:03 -07:00
dispatchToOutfit={dispatchToOutfit}
/>
);
}
export default SearchPanel;