add item list skeleton while loading
This commit is contained in:
parent
7397243c7f
commit
d1d98e2f72
2 changed files with 79 additions and 28 deletions
|
@ -1,5 +1,5 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Box, Image, PseudoBox, Stack } from "@chakra-ui/core";
|
import { Box, Image, PseudoBox, Stack, Skeleton } from "@chakra-ui/core";
|
||||||
|
|
||||||
function ItemList({ items, wornItemIds, onWearItem }) {
|
function ItemList({ items, wornItemIds, onWearItem }) {
|
||||||
return (
|
return (
|
||||||
|
@ -17,6 +17,22 @@ function ItemList({ items, wornItemIds, onWearItem }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ItemListSkeleton() {
|
||||||
|
return (
|
||||||
|
<Stack spacing="3">
|
||||||
|
<Box>
|
||||||
|
<ItemSkeleton />
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<ItemSkeleton />
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<ItemSkeleton />
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function Item({ item, isWorn, onWear }) {
|
function Item({ item, isWorn, onWear }) {
|
||||||
return (
|
return (
|
||||||
<PseudoBox
|
<PseudoBox
|
||||||
|
@ -33,6 +49,16 @@ function Item({ item, isWorn, onWear }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ItemSkeleton() {
|
||||||
|
return (
|
||||||
|
<Box d="flex" alignItems="center">
|
||||||
|
<Skeleton width="50px" height="50px" />
|
||||||
|
<Box width="3" />
|
||||||
|
<Skeleton height="1.5rem" width="12rem" />
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function ItemThumbnail({ src, isWorn }) {
|
function ItemThumbnail({ src, isWorn }) {
|
||||||
return (
|
return (
|
||||||
<PseudoBox
|
<PseudoBox
|
||||||
|
@ -82,3 +108,4 @@ function ItemName({ children, isWorn }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ItemList;
|
export default ItemList;
|
||||||
|
export { ItemListSkeleton };
|
||||||
|
|
|
@ -15,12 +15,13 @@ import {
|
||||||
InputLeftElement,
|
InputLeftElement,
|
||||||
InputRightElement,
|
InputRightElement,
|
||||||
PseudoBox,
|
PseudoBox,
|
||||||
|
Skeleton,
|
||||||
Stack,
|
Stack,
|
||||||
Text,
|
Text,
|
||||||
useToast,
|
useToast,
|
||||||
} from "@chakra-ui/core";
|
} from "@chakra-ui/core";
|
||||||
|
|
||||||
import ItemList from "./ItemList";
|
import ItemList, { ItemListSkeleton } from "./ItemList";
|
||||||
import useOutfitState from "./useOutfitState.js";
|
import useOutfitState from "./useOutfitState.js";
|
||||||
import { ITEMS } from "./data";
|
import { ITEMS } from "./data";
|
||||||
|
|
||||||
|
@ -53,6 +54,18 @@ function WardrobePage() {
|
||||||
[toast, wearItem, hasSentToast, setHasSentToast]
|
[toast, wearItem, hasSentToast, setHasSentToast]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (error) {
|
||||||
|
toast({
|
||||||
|
title: "We couldn't load this outfit 😖",
|
||||||
|
description: "Please reload the page to try again. Sorry!",
|
||||||
|
status: "error",
|
||||||
|
isClosable: true,
|
||||||
|
duration: Infinity,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, [error, toast]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid
|
<Grid
|
||||||
// Fullscreen, split into a vertical stack on smaller screens
|
// Fullscreen, split into a vertical stack on smaller screens
|
||||||
|
@ -97,6 +110,7 @@ function WardrobePage() {
|
||||||
) : (
|
) : (
|
||||||
<ItemsPanel
|
<ItemsPanel
|
||||||
zonesAndItems={data.zonesAndItems}
|
zonesAndItems={data.zonesAndItems}
|
||||||
|
loading={loading}
|
||||||
onWearItem={wearItemAndToast}
|
onWearItem={wearItemAndToast}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -191,21 +205,29 @@ function SearchPanel({ query, wornItemIds, onWearItem }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ItemsPanel({ zonesAndItems, onWearItem }) {
|
function ItemsPanel({ zonesAndItems, loading, onWearItem }) {
|
||||||
return (
|
return (
|
||||||
<Box color="green.800">
|
<Box color="green.800">
|
||||||
<OutfitHeading />
|
<OutfitHeading />
|
||||||
<Stack spacing="10">
|
<Stack spacing="10">
|
||||||
{zonesAndItems.map(({ zoneName, items, wornItemId }) => (
|
{loading &&
|
||||||
<Box key={zoneName}>
|
[1, 2, 3].map((i) => (
|
||||||
<Heading2 mb="3">{zoneName}</Heading2>
|
<Box key={i}>
|
||||||
<ItemList
|
<Skeleton height="2.3rem" width="12rem" mb="3" />
|
||||||
items={items}
|
<ItemListSkeleton />
|
||||||
wornItemIds={[wornItemId]}
|
</Box>
|
||||||
onWearItem={onWearItem}
|
))}
|
||||||
/>
|
{!loading &&
|
||||||
</Box>
|
zonesAndItems.map(({ zoneName, items, wornItemId }) => (
|
||||||
))}
|
<Box key={zoneName}>
|
||||||
|
<Heading2 mb="3">{zoneName}</Heading2>
|
||||||
|
<ItemList
|
||||||
|
items={items}
|
||||||
|
wornItemIds={[wornItemId]}
|
||||||
|
onWearItem={onWearItem}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
@ -213,21 +235,23 @@ function ItemsPanel({ zonesAndItems, onWearItem }) {
|
||||||
|
|
||||||
function OutfitHeading() {
|
function OutfitHeading() {
|
||||||
return (
|
return (
|
||||||
<PseudoBox role="group" d="inline-block" position="relative">
|
<Box>
|
||||||
<Heading1 mb="6">
|
<PseudoBox role="group" d="inline-block" position="relative">
|
||||||
<Editable defaultValue="Zafara Agent (roopal27)">
|
<Heading1 mb="6">
|
||||||
{({ isEditing, onRequestEdit }) => (
|
<Editable defaultValue="Zafara Agent (roopal27)">
|
||||||
<>
|
{({ isEditing, onRequestEdit }) => (
|
||||||
<EditablePreview />
|
<>
|
||||||
<EditableInput />
|
<EditablePreview />
|
||||||
{!isEditing && (
|
<EditableInput />
|
||||||
<OutfitNameEditButton onRequestEdit={onRequestEdit} />
|
{!isEditing && (
|
||||||
)}
|
<OutfitNameEditButton onRequestEdit={onRequestEdit} />
|
||||||
</>
|
)}
|
||||||
)}
|
</>
|
||||||
</Editable>
|
)}
|
||||||
</Heading1>
|
</Editable>
|
||||||
</PseudoBox>
|
</Heading1>
|
||||||
|
</PseudoBox>
|
||||||
|
</Box>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue