import React from "react"; import { Badge, Box, Flex, Popover, PopoverArrow, PopoverBody, PopoverContent, PopoverTrigger, Portal, Select, Skeleton, Spinner, Tooltip, useToast, VStack, } from "@chakra-ui/react"; import { ExternalLinkIcon, ChevronRightIcon, QuestionIcon, WarningTwoIcon, } 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 && ( {shouldShowWaka() && 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 && ( 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}

The Waka Guide for NC trade values is closing down! {" "} We're sad to see them go, but excited that the team gets to move onto the next phase in their life 💖

The Waka guide was last updated August 7, 2021, so this value might not be accurate anymore. Consider checking in with the Neoboards!

Thanks again to the Waka team for letting us experiment with sharing their trade values here. Best wishes for everything to come! 💜

); } // August 21, 2021. (The month uses 0-indexing, but nothing else does! 🙃) const STOP_SHOWING_WAKA_AFTER = new Date(2021, 7, 21, 0, 0, 0, 0); /** * shouldShowWaka returns true if, according to the browser, it's not yet * August 21, 2021. It starts returning false at midnight on Aug 21. * * That way, our Waka deprecation message is on an auto-timer. After Aug 21, * it's safe to remove all Waka UI code, and the Waka API endpoint and GraphQL * fields. (It might be kind to return a placeholder string for the GraphQL * case!) */ function shouldShowWaka() { const now = new Date(); return now < STOP_SHOWING_WAKA_AFTER; } export default ItemPageLayout;