import React from "react";
import { Badge, Box, Center, Wrap, VStack } from "@chakra-ui/core";
import { CheckIcon, EmailIcon, StarIcon } from "@chakra-ui/icons";
import gql from "graphql-tag";
import { useParams } from "react-router-dom";
import { useQuery } from "@apollo/client";
import HangerSpinner from "./components/HangerSpinner";
import { Heading1, Heading2, Heading3 } from "./util";
import ItemCard, {
ItemBadgeList,
ItemCardList,
NcBadge,
NpBadge,
YouOwnThisBadge,
YouWantThisBadge,
ZoneBadgeList,
} from "./components/ItemCard";
import useCurrentUser from "./components/useCurrentUser";
import WIPCallout from "./components/WIPCallout";
function UserItemsPage() {
const { userId } = useParams();
const currentUser = useCurrentUser();
const isCurrentUser = currentUser.id === userId;
const { loading, error, data } = useQuery(
gql`
query ItemsPage($userId: ID!) {
user(id: $userId) {
id
username
contactNeopetsUsername
closetLists {
id
name
ownsOrWantsItems
isDefaultList
items {
id
isNc
name
thumbnailUrl
currentUserOwnsThis
currentUserWantsThis
allOccupiedZones {
id
label @client
}
}
}
}
}
`,
{ variables: { userId } }
);
if (loading) {
return (
);
}
if (error) {
return {error.message};
}
if (data.user == null) {
return User not found;
}
const listsOfOwnedItems = data.user.closetLists.filter(
(l) => l.ownsOrWantsItems === "OWNS"
);
const listsOfWantedItems = data.user.closetLists.filter(
(l) => l.ownsOrWantsItems === "WANTS"
);
// Sort default list to the end, then sort alphabetically. We use a similar
// sort hack that we use for sorting items in ClosetList!
listsOfOwnedItems.sort((a, b) => {
const aName = `${a.isDefaultList ? "ZZZ" : "AAA"} ${a.name}`;
const bName = `${b.isDefaultList ? "ZZZ" : "AAA"} ${b.name}`;
return aName.localeCompare(bName);
});
listsOfWantedItems.sort((a, b) => {
const aName = `${a.isDefaultList ? "ZZZ" : "AAA"} ${a.name}`;
const bName = `${b.isDefaultList ? "ZZZ" : "AAA"} ${b.name}`;
return aName.localeCompare(bName);
});
const allItemsTheyOwn = listsOfOwnedItems.map((l) => l.items).flat();
const allItemsTheyWant = listsOfWantedItems.map((l) => l.items).flat();
const itemsTheyOwnThatYouWant = allItemsTheyOwn.filter(
(i) => i.currentUserWantsThis
);
const itemsTheyWantThatYouOwn = allItemsTheyWant.filter(
(i) => i.currentUserOwnsThis
);
// It's important to de-duplicate these! Otherwise, if the same item appears
// in multiple lists, we'll double-count it.
const numItemsTheyOwnThatYouWant = new Set(
itemsTheyOwnThatYouWant.map((i) => i.id)
).size;
const numItemsTheyWantThatYouOwn = new Set(
itemsTheyWantThatYouOwn.map((i) => i.id)
).size;
return (
{isCurrentUser ? "Your items" : `${data.user.username}'s items`}
{data.user.contactNeopetsUsername && (
{data.user.contactNeopetsUsername}
)}
{data.user.contactNeopetsUsername && (
Neomail
)}
{/* Usually I put "Own" before "Want", but this matches the natural
* order on the page: the _matches_ for things you want are things
* _this user_ owns, so they come first. I think it's also probably a
* more natural train of thought: you come to someone's list _wanting_
* something, and _then_ thinking about what you can offer. */}
{!isCurrentUser && numItemsTheyOwnThatYouWant > 0 && (
{numItemsTheyOwnThatYouWant > 1
? `${numItemsTheyOwnThatYouWant} items you want`
: "1 item you want"}
)}
{!isCurrentUser && numItemsTheyWantThatYouOwn > 0 && (
{numItemsTheyWantThatYouOwn > 1
? `${numItemsTheyWantThatYouOwn} items you own`
: "1 item you own"}
)}
{isCurrentUser ? "Items you own" : `Items ${data.user.username} owns`}
{listsOfOwnedItems.map((closetList) => (
1}
/>
))}
{isCurrentUser ? "Items you want" : `Items ${data.user.username} wants`}
{listsOfWantedItems.map((closetList) => (
1}
/>
))}
);
}
function ClosetList({ closetList, isCurrentUser, showHeading }) {
const hasYouWantThisBadge = (item) =>
!isCurrentUser &&
closetList.ownsOrWantsItems === "OWNS" &&
item.currentUserWantsThis;
const hasYouOwnThisBadge = (item) =>
!isCurrentUser &&
closetList.ownsOrWantsItems === "WANTS" &&
item.currentUserOwnsThis;
const hasAnyTradeBadge = (item) =>
hasYouOwnThisBadge(item) || hasYouWantThisBadge(item);
const sortedItems = [...closetList.items].sort((a, b) => {
// This is a cute sort hack. We sort first by, bringing "You own/want
// this!" to the top, and then sorting by name _within_ those two groups.
const aName = `${hasAnyTradeBadge(a) ? "000" : "999"} ${a.name}`;
const bName = `${hasAnyTradeBadge(b) ? "000" : "999"} ${b.name}`;
return aName.localeCompare(bName);
});
return (
{showHeading && (
{closetList.name}
)}
{sortedItems.length > 0 ? (
{sortedItems.map((item) => (
{item.isNc ? : }
{hasYouOwnThisBadge(item) && }
{hasYouWantThisBadge(item) && }
}
/>
))}
) : (
This list is empty!
)}
);
}
function NeopetsStarIcon(props) {
// Converted from the Neopets favicon with https://www.vectorizer.io/.
return (
);
}
export default UserItemsPage;