import React from "react"; import { Box, Breadcrumb, BreadcrumbItem, BreadcrumbLink, Center, Flex, Wrap, WrapItem, } from "@chakra-ui/react"; import { ArrowForwardIcon, ChevronRightIcon } from "@chakra-ui/icons"; import { Heading1, MajorErrorMessage, usePageTitle } from "./util"; import { gql, useQuery } from "@apollo/client"; import { Link, useParams } from "react-router-dom"; import { HashLink } from "react-router-hash-link"; import HangerSpinner from "./components/HangerSpinner"; import MarkdownAndSafeHTML from "./components/MarkdownAndSafeHTML"; import ItemCard from "./components/ItemCard"; import useCurrentUser from "./components/useCurrentUser"; function UserItemListPage() { const { listId } = useParams(); const currentUser = useCurrentUser(); const { loading, error, data } = useQuery( gql` query UserItemListPage($listId: ID!) { closetList(id: $listId) { id name description ownsOrWantsItems creator { id username } items { id isNc isPb name thumbnailUrl currentUserOwnsThis currentUserWantsThis } } } `, { variables: { listId }, context: { sendAuth: true } } ); const closetList = data?.closetList; usePageTitle(closetList?.name); if (loading) { return (
); } if (error) { return ; } if (!closetList) { return ; } const { creator, ownsOrWantsItems } = closetList; // NOTE: `currentUser` should have resolved by now, because the GraphQL query // sends authorization, which requires the current user to load first! const isCurrentUser = currentUser.id === creator.id; let linkBackText; let linkBackPath; if (ownsOrWantsItems === "OWNS") { linkBackText = `Items ${creator.username} owns`; linkBackPath = `/user/${creator.id}/lists#owned-items`; } else if (ownsOrWantsItems === "WANTS") { linkBackText = `Items ${creator.username} wants`; linkBackPath = `/user/${creator.id}/lists#wanted-items`; } else { throw new Error(`unexpected ownsOrWantsItems value: ${ownsOrWantsItems}`); } return ( } > {creator.username}'s lists {linkBackText} {closetList.name} {closetList.description && ( {closetList.description} )} ); } export function ClosetListContents({ closetList, isCurrentUser, maxNumItemsToShow = null, }) { const isTradeMatch = (item) => !isCurrentUser && ((closetList.ownsOrWantsItems === "OWNS" && item.currentUserWantsThis) || (closetList.ownsOrWantsItems === "WANTS" && item.currentUserOwnsThis)); const sortedItems = [...closetList.items].sort((a, b) => { // This is a cute sort hack. We sort first by, bringing trade matches to // the top, and then sorting by name _within_ those two groups. const aName = `${isTradeMatch(a) ? "000" : "999"} ${a.name}`; const bName = `${isTradeMatch(b) ? "000" : "999"} ${b.name}`; return aName.localeCompare(bName); }); let itemsToShow = sortedItems; if (maxNumItemsToShow != null) { itemsToShow = itemsToShow.slice(0, maxNumItemsToShow); } const numMoreItems = Math.max(sortedItems.length - itemsToShow.length, 0); let tradeMatchingMode; if (isCurrentUser) { // On your own item list, it's not helpful to show your own trade matches! tradeMatchingMode = "hide-all"; } else if (closetList.ownsOrWantsItems === "OWNS") { tradeMatchingMode = "offering"; } else if (closetList.ownsOrWantsItems === "WANTS") { tradeMatchingMode = "seeking"; } else { throw new Error( `unexpected ownsOrWantsItems value: ${closetList.ownsOrWantsItems}` ); } return ( {itemsToShow.length > 0 ? ( {itemsToShow.map((item) => ( ))} ) : ( This list is empty! )} {numMoreItems > 0 && ( Show {numMoreItems} more items )} ); } export function buildClosetListPath(closetList) { let ownsOrWants; if (closetList.ownsOrWantsItems === "OWNS") { ownsOrWants = "owns"; } else if (closetList.ownsOrWantsItems === "WANTS") { ownsOrWants = "wants"; } else { throw new Error( `unexpected ownsOrWantsItems value: ${closetList.ownsOrWantsItems}` ); } return `/user/${closetList.creator.id}/lists/${ownsOrWants}/${closetList.id}`; } export default UserItemListPage;