start building item page

This commit is contained in:
Emi Matchu 2020-09-11 23:56:47 -07:00
parent ebb8c63ac6
commit 4f6f3640bb
3 changed files with 156 additions and 10 deletions

View file

@ -12,6 +12,7 @@ import PageLayout from "./PageLayout";
import WardrobePageLayout from "./WardrobePage/WardrobePageLayout";
const HomePage = loadable(() => import("./HomePage"));
const ItemPage = loadable(() => import("./ItemPage"));
const ModelingPage = loadable(() => import("./ModelingPage"));
const UserItemsPage = loadable(() => import("./UserItemsPage"));
const WardrobePage = loadable(() => import("./WardrobePage"), {
@ -63,6 +64,11 @@ function App() {
<ChakraProvider theme={theme}>
<CSSReset />
<Switch>
<Route path="/items/:itemId">
<PageLayout>
<ItemPage />
</PageLayout>
</Route>
<Route path="/outfits/new">
<WardrobePage />
</Route>

127
src/app/ItemPage.js Normal file
View file

@ -0,0 +1,127 @@
import React from "react";
import { Badge, Box, Center } from "@chakra-ui/core";
import { ExternalLinkIcon } from "@chakra-ui/icons";
import gql from "graphql-tag";
import { useQuery } from "@apollo/client";
import { useParams } from "react-router-dom";
import HangerSpinner from "./components/HangerSpinner";
import {
ItemBadgeList,
ItemThumbnail,
NcBadge,
NpBadge,
} from "./components/ItemCard";
import { Heading1, usePageTitle } from "./util";
function ItemPage() {
const { itemId } = useParams();
const { loading, error, data } = useQuery(
gql`
query ItemPage($itemId: ID!) {
item(id: $itemId) {
id
name
isNc
thumbnailUrl
}
}
`,
{ variables: { itemId } }
);
usePageTitle(data?.item?.name);
if (loading) {
return (
<Center>
<HangerSpinner />
</Center>
);
}
if (error) {
return <Box color="red.400">{error.message}</Box>;
}
const { item } = data;
return (
<Box display="flex" alignItems="center">
<ItemThumbnail
item={item}
size="lg"
isActive
marginRight="4"
flex="0 0 auto"
/>
<Box>
<Heading1 lineHeight="1.1">{item.name}</Heading1>
<ItemBadgeList>
{item.isNc ? <NcBadge /> : <NpBadge />}
<LinkBadge
href={
"https://items.jellyneo.net/search/?name=" +
encodeURIComponent(item.name) +
"&name_type=3"
}
>
Jellyneo
</LinkBadge>
{!item.isNc && (
<LinkBadge
href={
"http://www.neopets.com/market.phtml?type=wizard&string=" +
encodeURIComponent(item.name)
}
>
Shop Wiz
</LinkBadge>
)}
{!item.isNc && (
<LinkBadge
href={
"http://www.neopets.com/portal/supershopwiz.phtml?string=" +
encodeURIComponent(item.name)
}
>
Super Wiz
</LinkBadge>
)}
{!item.isNc && (
<LinkBadge
href={
"http://www.neopets.com/island/tradingpost.phtml?type=browse&criteria=item_exact&search_string=" +
encodeURIComponent(item.name)
}
>
Trades
</LinkBadge>
)}
{!item.isNc && (
<LinkBadge
href={
"http://www.neopets.com/genie.phtml?type=process_genie&criteria=exact&auctiongenie=" +
encodeURIComponent(item.name)
}
>
Auctions
</LinkBadge>
)}
</ItemBadgeList>
</Box>
</Box>
);
}
function LinkBadge({ children, href }) {
return (
<Badge as="a" href={href} display="flex" alignItems="center">
{children}
<ExternalLinkIcon marginLeft="1" />
</Badge>
);
}
export default ItemPage;

View file

@ -3,7 +3,6 @@ import { css } from "emotion";
import {
Badge,
Box,
Image,
SimpleGrid,
Tooltip,
Wrap,
@ -52,8 +51,8 @@ export function ItemCardContent({
<Box display="flex">
<Box flex="0 0 auto" marginRight="3">
<ItemThumbnail
src={safeImageUrl(item.thumbnailUrl)}
isWorn={isWorn}
item={item}
isActive={isWorn}
isDisabled={isDisabled}
focusSelector={focusSelector}
/>
@ -78,7 +77,14 @@ export function ItemCardContent({
* ItemThumbnail shows a small preview image for the item, including some
* hover/focus and worn/unworn states.
*/
function ItemThumbnail({ src, isWorn, isDisabled, focusSelector }) {
export function ItemThumbnail({
item,
size = "md",
isActive,
isDisabled,
focusSelector,
...props
}) {
const theme = useTheme();
const borderColor = useColorModeValue(
@ -93,8 +99,8 @@ function ItemThumbnail({ src, isWorn, isDisabled, focusSelector }) {
return (
<Box
width="50px"
height="50px"
width={size === "lg" ? "80px" : "50px"}
height={size === "lg" ? "80px" : "50px"}
transition="all 0.15s"
transformOrigin="center"
position="relative"
@ -103,18 +109,19 @@ function ItemThumbnail({ src, isWorn, isDisabled, focusSelector }) {
transform: "scale(0.8)",
},
!isDisabled &&
!isWorn && {
!isActive && {
[focusSelector]: {
opacity: "0.9",
transform: "scale(0.9)",
},
},
!isDisabled &&
isWorn && {
isActive && {
opacity: 1,
transform: "none",
},
])}
{...props}
>
<Box
borderRadius="lg"
@ -128,14 +135,20 @@ function ItemThumbnail({ src, isWorn, isDisabled, focusSelector }) {
borderColor: `${borderColor} !important`,
},
!isDisabled &&
!isWorn && {
!isActive && {
[focusSelector]: {
borderColor: `${focusBorderColor} !important`,
},
},
])}
>
<Image width="100%" height="100%" src={src} alt="" />
<Box
as="img"
width="100%"
height="100%"
src={safeImageUrl(item.thumbnailUrl)}
alt={`Thumbnail art for ${item.name}`}
/>
</Box>
</Box>
);