Only show 14 items on list page, then link to full
Woo, it's the big UI experiment! Let's see how it plays for folks 😅
Scrolling through a big lists page right now, I think this is a _huge_ improvement, I can get a sense of the lists and what's in them fast, and see matches fast, and dive quickly and with no extra load time when I want more. I'm pleased tbh!
This commit is contained in:
parent
482d710fd1
commit
96d7fb70ff
2 changed files with 58 additions and 28 deletions
|
@ -9,7 +9,7 @@ import {
|
|||
Wrap,
|
||||
WrapItem,
|
||||
} from "@chakra-ui/react";
|
||||
import { ChevronRightIcon } from "@chakra-ui/icons";
|
||||
import { ArrowForwardIcon, ChevronRightIcon } from "@chakra-ui/icons";
|
||||
import { Heading1, MajorErrorMessage } from "./util";
|
||||
import { gql, useQuery } from "@apollo/client";
|
||||
import { Link, useParams } from "react-router-dom";
|
||||
|
@ -18,7 +18,6 @@ import { HashLink } from "react-router-hash-link";
|
|||
import HangerSpinner from "./components/HangerSpinner";
|
||||
import MarkdownAndSafeHTML from "./components/MarkdownAndSafeHTML";
|
||||
import ItemCard from "./components/ItemCard";
|
||||
import WIPCallout from "./components/WIPCallout";
|
||||
import useCurrentUser from "./components/useCurrentUser";
|
||||
|
||||
function UserItemListPage() {
|
||||
|
@ -104,13 +103,7 @@ function UserItemListPage() {
|
|||
</BreadcrumbItem>
|
||||
</Breadcrumb>
|
||||
<Box height="1" />
|
||||
<Flex wrap="wrap">
|
||||
<Heading1>{closetList.name}</Heading1>
|
||||
<WIPCallout
|
||||
marginLeft="auto"
|
||||
details="We're planning to make this the detail view for each list, and then your lists page will be a easy-to-scan summary!"
|
||||
/>
|
||||
</Flex>
|
||||
<Heading1>{closetList.name}</Heading1>
|
||||
<Box height="6" />
|
||||
{closetList.description && (
|
||||
<MarkdownAndSafeHTML>{closetList.description}</MarkdownAndSafeHTML>
|
||||
|
@ -123,7 +116,11 @@ function UserItemListPage() {
|
|||
);
|
||||
}
|
||||
|
||||
export function ClosetListContents({ closetList, isCurrentUser }) {
|
||||
export function ClosetListContents({
|
||||
closetList,
|
||||
isCurrentUser,
|
||||
maxNumItemsToShow = null,
|
||||
}) {
|
||||
const isTradeMatch = (item) =>
|
||||
!isCurrentUser &&
|
||||
((closetList.ownsOrWantsItems === "OWNS" && item.currentUserWantsThis) ||
|
||||
|
@ -137,6 +134,13 @@ export function ClosetListContents({ closetList, isCurrentUser }) {
|
|||
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!
|
||||
|
@ -153,9 +157,9 @@ export function ClosetListContents({ closetList, isCurrentUser }) {
|
|||
|
||||
return (
|
||||
<Box>
|
||||
{sortedItems.length > 0 ? (
|
||||
{itemsToShow.length > 0 ? (
|
||||
<Wrap spacing="4" justify="center">
|
||||
{sortedItems.map((item) => (
|
||||
{itemsToShow.map((item) => (
|
||||
<WrapItem key={item.id}>
|
||||
<ItemCard
|
||||
item={item}
|
||||
|
@ -168,8 +172,48 @@ export function ClosetListContents({ closetList, isCurrentUser }) {
|
|||
) : (
|
||||
<Box fontStyle="italic">This list is empty!</Box>
|
||||
)}
|
||||
{numMoreItems > 0 && (
|
||||
<Box
|
||||
as={Link}
|
||||
to={buildClosetListPath(closetList)}
|
||||
display="flex"
|
||||
width="100%"
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
marginTop="6"
|
||||
fontStyle="italic"
|
||||
textAlign="center"
|
||||
role="group"
|
||||
>
|
||||
<Flex
|
||||
align="center"
|
||||
borderBottom="1px solid transparent"
|
||||
_groupHover={{ borderBottomColor: "currentColor" }}
|
||||
_groupFocus={{ borderBottomColor: "currentColor" }}
|
||||
>
|
||||
<Box>Show {numMoreItems} more items</Box>
|
||||
<Box width="1" />
|
||||
<ArrowForwardIcon />
|
||||
</Flex>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
|
@ -42,7 +42,7 @@ import SupportOnly from "./WardrobePage/support/SupportOnly";
|
|||
import useSupport from "./WardrobePage/support/useSupport";
|
||||
import useCurrentUser from "./components/useCurrentUser";
|
||||
import WIPCallout from "./components/WIPCallout";
|
||||
import { ClosetListContents } from "./UserItemListPage";
|
||||
import { ClosetListContents, buildClosetListPath } from "./UserItemListPage";
|
||||
|
||||
const BadgeButton = React.forwardRef((props, ref) => (
|
||||
<Badge as="button" ref={ref} {...props} />
|
||||
|
@ -590,26 +590,12 @@ function ClosetList({ closetList, isCurrentUser, showHeading }) {
|
|||
<ClosetListContents
|
||||
closetList={closetList}
|
||||
isCurrentUser={isCurrentUser}
|
||||
maxNumItemsToShow={14}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
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}`;
|
||||
}
|
||||
|
||||
function UserSupportMenu({ children, user }) {
|
||||
const { supportSecret } = useSupport();
|
||||
const toast = useToast();
|
||||
|
|
Loading…
Reference in a new issue