import React from "react"; import { Badge, Box, Flex, Popover, PopoverArrow, PopoverBody, PopoverContent, PopoverTrigger, Portal, Select, Skeleton, Spinner, Tooltip, useBreakpointValue, useToast, VStack, } from "@chakra-ui/react"; import { ExternalLinkIcon, ChevronRightIcon, QuestionIcon, } from "@chakra-ui/icons"; import { gql, useMutation } from "@apollo/client"; import { ItemBadgeList, ItemKindBadge, ItemThumbnail, } from "./components/ItemCard"; import { Heading1 } from "./util"; import useSupport from "./WardrobePage/support/useSupport"; function ItemPageLayout({ children, item, isEmbedded }) { return ( {children} ); } function ItemPageHeader({ item, isEmbedded }) { return ( {item?.name || "Item name here"} ); } /** * SubtleSkeleton hides the skeleton animation until a second has passed, and * doesn't fade in the content if it loads near-instantly. This helps avoid * flash-of-content stuff! * * For plain Skeletons, we often use instead. But * that pattern doesn't work as well for wrapper skeletons where we're using * placeholder content for layout: we don't want the delay if the content * really _is_ present! */ export function SubtleSkeleton({ isLoaded, ...props }) { const [shouldFadeIn, setShouldFadeIn] = React.useState(false); const [shouldShowSkeleton, setShouldShowSkeleton] = React.useState(false); React.useEffect(() => { const t = setTimeout(() => { if (!isLoaded) { setShouldFadeIn(true); } }, 150); return () => clearTimeout(t); }); React.useEffect(() => { const t = setTimeout(() => setShouldShowSkeleton(true), 500); return () => clearTimeout(t); }); return ( ); } function ItemPageBadges({ item, isEmbedded }) { const searchBadgesAreLoaded = item?.name != null && item?.isNc != null; return ( { // If the createdAt date is null (loaded and empty), hide the badge. item.createdAt !== null && ( {item.createdAt && } ) } Classic DTI Jellyneo {item.isNc && ( {item.wakaValueText && ( <> {/* For hover-y devices, use a hover popover over the badge. */} Waka: {item.wakaValueText} {/* For touch-y devices, use a tappable help icon. */} Waka: {item.wakaValueText} )} )} {!item?.isNc && !item?.isPb && ( Shop Wiz )} {!item?.isNc && !item?.isPb && ( Trade Post )} {!item?.isNc && !item?.isPb && ( Auctions )} ); } function ItemKindBadgeWithSupportTools({ item }) { const { isSupportUser, supportSecret } = useSupport(); const toast = useToast(); const ncRef = React.useRef(null); const isNcAutoDetectedFromRarity = item.rarityIndex === 500 || item.rarityIndex === 0; const [mutate, { loading }] = useMutation(gql` mutation ItemPageSupportSetIsManuallyNc( $itemId: ID! $isManuallyNc: Boolean! $supportSecret: String! ) { setItemIsManuallyNc( itemId: $itemId isManuallyNc: $isManuallyNc supportSecret: $supportSecret ) { id isNc isManuallyNc } } `); if (isSupportUser && item.rarityIndex != null && item.isManuallyNc != null) { // TODO: Could code-split this into a SupportOnly file... return ( NC: {loading && } PB: Support ); } return ; } const LinkBadge = React.forwardRef( ({ children, href, isEmbedded, ...props }, ref) => { return ( {children} { // We also change the icon to signal whether this will launch in a new // window or not! isEmbedded ? ( ) : ( ) } ); } ); const fullDateFormatter = new Intl.DateTimeFormat("en-US", { dateStyle: "long", }); const monthYearFormatter = new Intl.DateTimeFormat("en-US", { month: "short", year: "numeric", }); const monthDayYearFormatter = new Intl.DateTimeFormat("en-US", { month: "short", day: "numeric", year: "numeric", }); function ShortTimestamp({ when }) { const date = new Date(when); // To find the start of last month, take today, then set its date to the 1st // and its time to midnight (the start of this month), and subtract one // month. (JS handles negative months and rolls them over correctly.) const startOfLastMonth = new Date(); startOfLastMonth.setDate(1); startOfLastMonth.setHours(0); startOfLastMonth.setMinutes(0); startOfLastMonth.setSeconds(0); startOfLastMonth.setMilliseconds(0); startOfLastMonth.setMonth(startOfLastMonth.getMonth() - 1); const dateIsOlderThanLastMonth = date < startOfLastMonth; return ( {dateIsOlderThanLastMonth ? monthYearFormatter.format(date) : monthDayYearFormatter.format(date)} ); } function WakaPopover({ children, ...props }) { return ( {children}

Waka is a community resource that tracks the approximate value of NC items, based on real-world trades.

It's a super helpful starting point, but it's not the only factor! Rarity and popularity can affect trade values too, and the trade economy can change quickly.

Be sure to take all factors into account for your trades, rather than sticking to just this number! And consider asking for a "value check" on the Neoboards if you're not sure.

); } export default ItemPageLayout;