Matchu
81b2a2b4a2
We add jsbuilding-rails to get esbuild running in the app, and then we copy-paste the files we need from impress-2020 into here! I stopped at the point where it was building successfully, but it's not running correctly: it's not sure about `process.env` in `next`, and I think the right next step is to delete the NextJS deps altogether and use React Router instead.
92 lines
3.1 KiB
JavaScript
92 lines
3.1 KiB
JavaScript
import React from "react";
|
|
import { Box, Flex, useBreakpointValue } from "@chakra-ui/react";
|
|
import * as Sentry from "@sentry/react";
|
|
|
|
import ItemsPanel from "./ItemsPanel";
|
|
import SearchToolbar, { searchQueryIsEmpty } from "./SearchToolbar";
|
|
import SearchPanel from "./SearchPanel";
|
|
import { MajorErrorMessage, TestErrorSender, useLocalStorage } from "../util";
|
|
|
|
/**
|
|
* ItemsAndSearchPanels manages the shared layout and state for:
|
|
* - ItemsPanel, which shows the items in the outfit now, and
|
|
* - SearchPanel, which helps you find new items to add.
|
|
*
|
|
* These panels don't share a _lot_ of concerns; they're mainly intertwined by
|
|
* the fact that they share the SearchToolbar at the top!
|
|
*
|
|
* We try to keep the search concerns in the search components, by avoiding
|
|
* letting any actual _logic_ live at the root here; and instead just
|
|
* performing some wiring to help them interact with each other via simple
|
|
* state and refs.
|
|
*/
|
|
function ItemsAndSearchPanels({
|
|
loading,
|
|
searchQuery,
|
|
onChangeSearchQuery,
|
|
outfitState,
|
|
outfitSaving,
|
|
dispatchToOutfit,
|
|
}) {
|
|
const scrollContainerRef = React.useRef();
|
|
const searchQueryRef = React.useRef();
|
|
const firstSearchResultRef = React.useRef();
|
|
|
|
const hasRoomForSearchFooter = useBreakpointValue({ base: false, md: true });
|
|
const [canUseSearchFooter] = useLocalStorage(
|
|
"DTIFeatureFlagCanUseSearchFooter",
|
|
false
|
|
);
|
|
const isShowingSearchFooter = canUseSearchFooter && hasRoomForSearchFooter;
|
|
|
|
return (
|
|
<Sentry.ErrorBoundary fallback={MajorErrorMessage}>
|
|
<TestErrorSender />
|
|
<Flex direction="column" height="100%">
|
|
{isShowingSearchFooter && <Box height="2" />}
|
|
{!isShowingSearchFooter && (
|
|
<Box paddingX="5" paddingTop="3" paddingBottom="2" boxShadow="sm">
|
|
<SearchToolbar
|
|
query={searchQuery}
|
|
searchQueryRef={searchQueryRef}
|
|
firstSearchResultRef={firstSearchResultRef}
|
|
onChange={onChangeSearchQuery}
|
|
/>
|
|
</Box>
|
|
)}
|
|
{!isShowingSearchFooter && !searchQueryIsEmpty(searchQuery) ? (
|
|
<Box
|
|
key="search-panel"
|
|
flex="1 0 0"
|
|
position="relative"
|
|
overflowY="scroll"
|
|
ref={scrollContainerRef}
|
|
data-test-id="search-panel-scroll-container"
|
|
>
|
|
<SearchPanel
|
|
query={searchQuery}
|
|
outfitState={outfitState}
|
|
dispatchToOutfit={dispatchToOutfit}
|
|
scrollContainerRef={scrollContainerRef}
|
|
searchQueryRef={searchQueryRef}
|
|
firstSearchResultRef={firstSearchResultRef}
|
|
/>
|
|
</Box>
|
|
) : (
|
|
<Box position="relative" overflow="auto" key="items-panel">
|
|
<Box px="4" py="2">
|
|
<ItemsPanel
|
|
loading={loading}
|
|
outfitState={outfitState}
|
|
outfitSaving={outfitSaving}
|
|
dispatchToOutfit={dispatchToOutfit}
|
|
/>
|
|
</Box>
|
|
</Box>
|
|
)}
|
|
</Flex>
|
|
</Sentry.ErrorBoundary>
|
|
);
|
|
}
|
|
|
|
export default ItemsAndSearchPanels;
|