2020-04-21 20:32:53 -07:00
|
|
|
import React from "react";
|
|
|
|
import {
|
|
|
|
Box,
|
|
|
|
Grid,
|
2020-04-22 02:39:06 -07:00
|
|
|
Icon,
|
2020-04-22 01:10:24 -07:00
|
|
|
IconButton,
|
2020-04-22 02:39:06 -07:00
|
|
|
Input,
|
|
|
|
InputGroup,
|
|
|
|
InputLeftElement,
|
|
|
|
InputRightElement,
|
2020-04-22 02:57:58 -07:00
|
|
|
useToast,
|
2020-04-21 20:32:53 -07:00
|
|
|
} from "@chakra-ui/core";
|
|
|
|
|
2020-04-25 00:22:49 -07:00
|
|
|
import ItemsPanel from "./ItemsPanel";
|
2020-04-23 13:31:39 -07:00
|
|
|
import OutfitPreview from "./OutfitPreview";
|
2020-04-24 21:17:03 -07:00
|
|
|
import SearchPanel from "./SearchPanel";
|
|
|
|
import useOutfitState from "./useOutfitState.js";
|
2020-04-21 20:32:53 -07:00
|
|
|
|
|
|
|
function WardrobePage() {
|
2020-04-24 19:16:24 -07:00
|
|
|
const { loading, error, outfitState, dispatchToOutfit } = useOutfitState();
|
2020-04-22 02:39:06 -07:00
|
|
|
const [searchQuery, setSearchQuery] = React.useState("");
|
2020-04-22 02:57:58 -07:00
|
|
|
const toast = useToast();
|
2020-04-25 02:18:03 -07:00
|
|
|
const searchContainerRef = React.useRef();
|
2020-04-22 02:57:58 -07:00
|
|
|
|
2020-04-22 15:24:38 -07:00
|
|
|
React.useEffect(() => {
|
|
|
|
if (error) {
|
2020-04-24 21:17:03 -07:00
|
|
|
console.log(error);
|
2020-04-22 15:24:38 -07:00
|
|
|
toast({
|
|
|
|
title: "We couldn't load this outfit 😖",
|
|
|
|
description: "Please reload the page to try again. Sorry!",
|
|
|
|
status: "error",
|
|
|
|
isClosable: true,
|
2020-04-24 21:17:03 -07:00
|
|
|
duration: 999999999,
|
2020-04-22 15:24:38 -07:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}, [error, toast]);
|
|
|
|
|
2020-04-25 02:18:03 -07:00
|
|
|
React.useEffect(() => {
|
|
|
|
if (searchContainerRef.current) {
|
|
|
|
searchContainerRef.current.scrollTop = 0;
|
|
|
|
}
|
|
|
|
}, [searchQuery]);
|
|
|
|
|
2020-04-21 20:32:53 -07:00
|
|
|
return (
|
2020-04-24 00:46:24 -07:00
|
|
|
<Box position="absolute" top="0" bottom="0" left="0" right="0">
|
|
|
|
<Grid
|
|
|
|
// Fullscreen, split into a vertical stack on smaller screens
|
|
|
|
// or a horizontal stack on larger ones!
|
|
|
|
templateAreas={{
|
|
|
|
base: `"outfit"
|
2020-04-24 17:48:22 -07:00
|
|
|
"search"
|
|
|
|
"items"`,
|
2020-04-24 00:46:24 -07:00
|
|
|
lg: `"outfit search"
|
2020-04-24 17:48:22 -07:00
|
|
|
"outfit items"`,
|
2020-04-24 00:46:24 -07:00
|
|
|
}}
|
|
|
|
templateRows={{
|
|
|
|
base: "minmax(100px, 1fr) auto minmax(300px, 1fr)",
|
|
|
|
lg: "auto 1fr",
|
|
|
|
}}
|
|
|
|
templateColumns={{
|
|
|
|
base: "100%",
|
|
|
|
lg: "50% 50%",
|
|
|
|
}}
|
|
|
|
height="100%"
|
|
|
|
width="100%"
|
|
|
|
>
|
|
|
|
<Box gridArea="outfit" backgroundColor="gray.900">
|
2020-04-25 04:33:05 -07:00
|
|
|
<OutfitPreview
|
|
|
|
outfitState={outfitState}
|
|
|
|
dispatchToOutfit={dispatchToOutfit}
|
|
|
|
/>
|
2020-04-22 02:39:06 -07:00
|
|
|
</Box>
|
2020-04-24 00:46:24 -07:00
|
|
|
<Box gridArea="search" boxShadow="sm">
|
|
|
|
<Box px="5" py="3">
|
|
|
|
<SearchToolbar query={searchQuery} onChange={setSearchQuery} />
|
|
|
|
</Box>
|
2020-04-21 20:32:53 -07:00
|
|
|
</Box>
|
2020-04-25 00:43:01 -07:00
|
|
|
|
|
|
|
{searchQuery ? (
|
2020-04-25 02:18:03 -07:00
|
|
|
<Box
|
|
|
|
gridArea="items"
|
|
|
|
overflow="auto"
|
|
|
|
key="search-panel"
|
|
|
|
ref={searchContainerRef}
|
|
|
|
>
|
2020-04-25 00:43:01 -07:00
|
|
|
<Box px="5" py="5">
|
2020-04-24 00:46:24 -07:00
|
|
|
<SearchPanel
|
|
|
|
query={searchQuery}
|
2020-04-24 19:16:24 -07:00
|
|
|
outfitState={outfitState}
|
2020-04-24 18:39:38 -07:00
|
|
|
dispatchToOutfit={dispatchToOutfit}
|
2020-04-24 00:46:24 -07:00
|
|
|
/>
|
2020-04-25 00:43:01 -07:00
|
|
|
</Box>
|
|
|
|
</Box>
|
|
|
|
) : (
|
|
|
|
<Box gridArea="items" overflow="auto" key="items-panel">
|
|
|
|
<Box px="5" py="5">
|
2020-04-24 00:46:24 -07:00
|
|
|
<ItemsPanel
|
|
|
|
loading={loading}
|
2020-04-24 19:16:24 -07:00
|
|
|
outfitState={outfitState}
|
2020-04-24 18:39:38 -07:00
|
|
|
dispatchToOutfit={dispatchToOutfit}
|
2020-04-24 00:46:24 -07:00
|
|
|
/>
|
2020-04-25 00:43:01 -07:00
|
|
|
</Box>
|
2020-04-24 00:46:24 -07:00
|
|
|
</Box>
|
2020-04-25 00:43:01 -07:00
|
|
|
)}
|
2020-04-24 00:46:24 -07:00
|
|
|
</Grid>
|
|
|
|
</Box>
|
2020-04-21 20:32:53 -07:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-04-22 02:39:06 -07:00
|
|
|
function SearchToolbar({ query, onChange }) {
|
|
|
|
return (
|
|
|
|
<InputGroup>
|
|
|
|
<InputLeftElement>
|
|
|
|
<Icon name="search" color="gray.400" />
|
|
|
|
</InputLeftElement>
|
|
|
|
<Input
|
2020-04-22 03:13:47 -07:00
|
|
|
placeholder="Search for items to add…"
|
2020-04-22 02:39:06 -07:00
|
|
|
focusBorderColor="green.600"
|
|
|
|
color="green.800"
|
|
|
|
value={query}
|
|
|
|
onChange={(e) => onChange(e.target.value)}
|
2020-04-22 04:07:34 -07:00
|
|
|
onKeyDown={(e) => {
|
|
|
|
if (e.key === "Escape") {
|
|
|
|
onChange("");
|
|
|
|
e.target.blur();
|
|
|
|
}
|
|
|
|
}}
|
2020-04-22 02:39:06 -07:00
|
|
|
/>
|
|
|
|
{query && (
|
|
|
|
<InputRightElement>
|
|
|
|
<IconButton
|
|
|
|
icon="close"
|
|
|
|
color="gray.400"
|
|
|
|
variant="ghost"
|
|
|
|
variantColor="green"
|
|
|
|
aria-label="Clear search"
|
|
|
|
onClick={() => onChange("")}
|
2020-04-25 02:20:23 -07:00
|
|
|
// Big style hacks here!
|
|
|
|
height="calc(100% - 2px)"
|
|
|
|
marginRight="2px"
|
2020-04-22 02:39:06 -07:00
|
|
|
/>
|
|
|
|
</InputRightElement>
|
|
|
|
)}
|
|
|
|
</InputGroup>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-04-21 20:32:53 -07:00
|
|
|
export default WardrobePage;
|