start building item page
This commit is contained in:
parent
ebb8c63ac6
commit
4f6f3640bb
3 changed files with 156 additions and 10 deletions
|
@ -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
127
src/app/ItemPage.js
Normal 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;
|
|
@ -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>
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue