WIP list editing on item page

Gonna have this button pop up a little thing of your lists, with checkboxes, and I guess probably quantities once I add that concept back to 2020 😅
This commit is contained in:
Emi Matchu 2021-11-26 14:42:05 -08:00
parent 894fe7d3df
commit ad249d03ab
2 changed files with 104 additions and 4 deletions

View file

@ -20,6 +20,7 @@ import {
} from "@chakra-ui/react";
import {
CheckIcon,
ChevronDownIcon,
ChevronRightIcon,
EditIcon,
StarIcon,
@ -99,8 +100,8 @@ export function ItemPageContent({ itemId, isEmbedded }) {
isEmbedded={isEmbedded}
/>
<VStack spacing="4">
{isLoggedIn && <ItemPageOwnWantButtons itemId={itemId} />}
<ItemPageTradeLinks itemId={itemId} isEmbedded={isEmbedded} />
{isLoggedIn && <ItemPageOwnWantButtons itemId={itemId} />}
</VStack>
{!isEmbedded && <ItemPageOutfitPreview itemId={itemId} />}
</VStack>
@ -147,6 +148,12 @@ function ItemPageOwnWantButtons({ itemId }) {
id
currentUserOwnsThis
currentUserWantsThis
currentUserHasInLists {
id
name
isDefaultList
ownsOrWantsItems
}
}
}
`,
@ -157,14 +164,30 @@ function ItemPageOwnWantButtons({ itemId }) {
return <Box color="red.400">{error.message}</Box>;
}
const closetLists = data?.item?.currentUserHasInLists || [];
const ownedLists = closetLists.filter((cl) => cl.ownsOrWantsItems === "OWNS");
const wantedLists = closetLists.filter(
(cl) => cl.ownsOrWantsItems === "WANTS"
);
return (
<Box display="flex">
<SubtleSkeleton isLoaded={!loading} marginRight="4">
<Grid
templateRows="auto auto"
templateColumns="auto auto"
gridAutoFlow="column"
rowGap="0.5"
columnGap="4"
>
<SubtleSkeleton isLoaded={!loading}>
<ItemPageOwnButton
itemId={itemId}
isChecked={data?.item?.currentUserOwnsThis}
/>
</SubtleSkeleton>
<ItemPageOwnWantListsButton
isVisible={data?.item?.currentUserOwnsThis}
closetLists={ownedLists}
/>
<SubtleSkeleton isLoaded={!loading}>
<ItemPageWantButton
@ -172,7 +195,61 @@ function ItemPageOwnWantButtons({ itemId }) {
isChecked={data?.item?.currentUserWantsThis}
/>
</SubtleSkeleton>
</Box>
<ItemPageOwnWantListsButton
isVisible={data?.item?.currentUserWantsThis}
closetLists={wantedLists}
/>
</Grid>
);
}
function ItemPageOwnWantListsButton({ closetLists, isVisible }) {
const toast = useToast();
const realLists = closetLists.filter((cl) => !cl.isDefaultList);
let buttonText;
if (realLists.length === 1) {
buttonText = `In list "${realLists[0].name}"`;
} else if (realLists.length > 1) {
buttonText = `In ${realLists.length} lists`;
} else {
buttonText = "Add to list";
}
return (
<Flex
as="button"
fontSize="xs"
alignItems="center"
borderRadius="sm"
_hover={{ textDecoration: "underline" }}
_focus={{
textDecoration: "underline",
outline: "0",
boxShadow: "outline",
}}
onClick={() =>
toast({
status: "warning",
title: "Feature coming soon!",
description:
"I haven't built the cute pop-up for editing your lists yet! Neat concept though, right? 😅 —Matchu",
})
}
// Even when the button isn't visible, we still render it for layout
// purposes, but hidden and disabled.
opacity={isVisible ? 1 : 0}
aria-hidden={!isVisible}
disabled={!isVisible}
>
{/* Flex tricks to center the text, ignoring the caret */}
<Box flex="1 0 0" />
<Box>{buttonText}</Box>
<Flex flex="1 0 0">
<ChevronDownIcon marginLeft="1" />
</Flex>
</Flex>
);
}

View file

@ -35,6 +35,7 @@ const typeDefs = gql`
currentUserOwnsThis: Boolean! @cacheControl(maxAge: 0, scope: PRIVATE)
currentUserWantsThis: Boolean! @cacheControl(maxAge: 0, scope: PRIVATE)
currentUserHasInLists: [ClosetList!]! @cacheControl(maxAge: 0, scope: PRIVATE)
"""
How many users are offering/seeking this in their public trade lists.
@ -337,6 +338,28 @@ const resolvers = {
const closetHangers = await userClosetHangersLoader.load(currentUserId);
return closetHangers.some((h) => h.itemId === id && !h.owned);
},
currentUserHasInLists: async (
{ id },
_,
{ currentUserId, userClosetHangersLoader }
) => {
if (currentUserId == null) return false;
const closetHangers = await userClosetHangersLoader.load(currentUserId);
const itemHangers = closetHangers.filter((h) => h.itemId === id);
const listRefs = itemHangers.map((hanger) => {
if (hanger.listId) {
return { id: hanger.listId };
} else {
return {
id: null,
isDefaultList: true,
userId: hanger.userId,
ownsOrWantsItems: hanger.owned ? "OWNS" : "WANTS",
};
}
});
return listRefs;
},
numUsersOfferingThis: async (
{ id },