[WIP] UI for isManuallyNc support tool
This commit is contained in:
parent
281fdccb89
commit
0ae26a6633
4 changed files with 145 additions and 26 deletions
|
@ -74,6 +74,10 @@ export function ItemPageContent({ itemId, isEmbedded }) {
|
||||||
thumbnailUrl
|
thumbnailUrl
|
||||||
description
|
description
|
||||||
createdAt
|
createdAt
|
||||||
|
|
||||||
|
# For Support users.
|
||||||
|
rarityIndex
|
||||||
|
isManuallyNc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Badge, Box, Skeleton, Tooltip } from "@chakra-ui/react";
|
import {
|
||||||
|
Badge,
|
||||||
|
Box,
|
||||||
|
Flex,
|
||||||
|
Popover,
|
||||||
|
PopoverArrow,
|
||||||
|
PopoverContent,
|
||||||
|
PopoverTrigger,
|
||||||
|
Portal,
|
||||||
|
Select,
|
||||||
|
Skeleton,
|
||||||
|
Tooltip,
|
||||||
|
VStack,
|
||||||
|
} from "@chakra-ui/react";
|
||||||
import { ExternalLinkIcon, ChevronRightIcon } from "@chakra-ui/icons";
|
import { ExternalLinkIcon, ChevronRightIcon } from "@chakra-ui/icons";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -9,6 +22,8 @@ import {
|
||||||
} from "./components/ItemCard";
|
} from "./components/ItemCard";
|
||||||
import { Heading1 } from "./util";
|
import { Heading1 } from "./util";
|
||||||
|
|
||||||
|
import useSupport from "./WardrobePage/support/useSupport";
|
||||||
|
|
||||||
function ItemPageLayout({ children, item, isEmbedded }) {
|
function ItemPageLayout({ children, item, isEmbedded }) {
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
|
@ -91,7 +106,7 @@ function ItemPageBadges({ item, isEmbedded }) {
|
||||||
return (
|
return (
|
||||||
<ItemBadgeList marginTop="1">
|
<ItemBadgeList marginTop="1">
|
||||||
<SubtleSkeleton isLoaded={item?.isNc != null}>
|
<SubtleSkeleton isLoaded={item?.isNc != null}>
|
||||||
<ItemKindBadge isNc={item.isNc} isPb={item.isPb} />
|
<ItemKindBadgeWithSupportTools item={item} />
|
||||||
</SubtleSkeleton>
|
</SubtleSkeleton>
|
||||||
{
|
{
|
||||||
// If the createdAt date is null (loaded and empty), hide the badge.
|
// If the createdAt date is null (loaded and empty), hide the badge.
|
||||||
|
@ -188,6 +203,62 @@ function ItemPageBadges({ item, isEmbedded }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ItemKindBadgeWithSupportTools({ item }) {
|
||||||
|
const { isSupportUser } = useSupport();
|
||||||
|
|
||||||
|
const ncRef = React.useRef(null);
|
||||||
|
|
||||||
|
const isNcAutoDetectedFromRarity =
|
||||||
|
item.rarityIndex === 500 || item.rarityIndex === 0;
|
||||||
|
|
||||||
|
if (isSupportUser && item.rarityIndex != null && item.isManuallyNc != null) {
|
||||||
|
// TODO: Could code-split this into a SupportOnly file...
|
||||||
|
return (
|
||||||
|
<Popover placement="bottom-start" initialFocusRef={ncRef} showArrow>
|
||||||
|
<PopoverTrigger>
|
||||||
|
<ItemKindBadge isNc={item.isNc} isPb={item.isPb} isEditButton />
|
||||||
|
</PopoverTrigger>
|
||||||
|
<Portal>
|
||||||
|
<PopoverContent padding="4">
|
||||||
|
<PopoverArrow />
|
||||||
|
<Badge colorScheme="pink" position="absolute" right="4" top="4">
|
||||||
|
Support <span aria-hidden="true">💖</span>
|
||||||
|
</Badge>
|
||||||
|
<VStack spacing="2" align="flex-start">
|
||||||
|
<Flex align="center">
|
||||||
|
<Box as="span" fontWeight="600" marginRight="1">
|
||||||
|
Rarity:
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
{item.rarityIndex} (
|
||||||
|
{isNcAutoDetectedFromRarity ? "NC" : "not NC"})
|
||||||
|
</Box>
|
||||||
|
</Flex>
|
||||||
|
<Flex align="center">
|
||||||
|
<Box as="span" fontWeight="600" marginRight="2">
|
||||||
|
NC:
|
||||||
|
</Box>
|
||||||
|
<Select
|
||||||
|
ref={ncRef}
|
||||||
|
size="xs"
|
||||||
|
value={item.isManuallyNc ? "true" : "false"}
|
||||||
|
>
|
||||||
|
<option value="false">
|
||||||
|
Auto-detect ({isNcAutoDetectedFromRarity ? "Yes" : "No"})
|
||||||
|
</option>
|
||||||
|
<option value="true">Always NC (ignore rarity)</option>
|
||||||
|
</Select>
|
||||||
|
</Flex>
|
||||||
|
</VStack>
|
||||||
|
</PopoverContent>
|
||||||
|
</Portal>
|
||||||
|
</Popover>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <ItemKindBadge isNc={item.isNc} isPb={item.isPb} />;
|
||||||
|
}
|
||||||
|
|
||||||
function LinkBadge({ children, href, isEmbedded }) {
|
function LinkBadge({ children, href, isEmbedded }) {
|
||||||
return (
|
return (
|
||||||
<Badge
|
<Badge
|
||||||
|
|
|
@ -10,7 +10,12 @@ import {
|
||||||
useColorModeValue,
|
useColorModeValue,
|
||||||
useTheme,
|
useTheme,
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { CheckIcon, NotAllowedIcon, StarIcon } from "@chakra-ui/icons";
|
import {
|
||||||
|
CheckIcon,
|
||||||
|
EditIcon,
|
||||||
|
NotAllowedIcon,
|
||||||
|
StarIcon,
|
||||||
|
} from "@chakra-ui/icons";
|
||||||
import { HiSparkles } from "react-icons/hi";
|
import { HiSparkles } from "react-icons/hi";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
@ -242,43 +247,73 @@ export function ItemBadgeTooltip({ label, children }) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function NcBadge() {
|
export const NcBadge = React.forwardRef(({ isEditButton, ...props }, ref) => {
|
||||||
return (
|
return (
|
||||||
<ItemBadgeTooltip label="Neocash">
|
<ItemBadgeTooltip label="Neocash">
|
||||||
<Badge colorScheme="purple" display="block">
|
<Badge
|
||||||
|
ref={ref}
|
||||||
|
as={isEditButton ? "button" : "span"}
|
||||||
|
colorScheme="purple"
|
||||||
|
display="flex"
|
||||||
|
alignItems="center"
|
||||||
|
_focus={{ outline: "none", boxShadow: "outline" }}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
NC
|
NC
|
||||||
|
{isEditButton && <EditIcon fontSize="0.85em" marginLeft="1" />}
|
||||||
</Badge>
|
</Badge>
|
||||||
</ItemBadgeTooltip>
|
</ItemBadgeTooltip>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
export function NpBadge() {
|
export const NpBadge = React.forwardRef(({ isEditButton, ...props }, ref) => {
|
||||||
return (
|
return (
|
||||||
<ItemBadgeTooltip label="Neopoints">
|
<ItemBadgeTooltip label="Neopoints">
|
||||||
<Badge display="block">NP</Badge>
|
<Badge
|
||||||
</ItemBadgeTooltip>
|
ref={ref}
|
||||||
);
|
as={isEditButton ? "button" : "span"}
|
||||||
}
|
display="flex"
|
||||||
|
alignItems="center"
|
||||||
export function PbBadge() {
|
_focus={{ outline: "none", boxShadow: "outline" }}
|
||||||
return (
|
{...props}
|
||||||
<ItemBadgeTooltip label="This item is only obtainable via paintbrush">
|
>
|
||||||
<Badge colorScheme="orange" display="block">
|
NP
|
||||||
PB
|
{isEditButton && <EditIcon fontSize="0.85em" marginLeft="1" />}
|
||||||
</Badge>
|
</Badge>
|
||||||
</ItemBadgeTooltip>
|
</ItemBadgeTooltip>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
export function ItemKindBadge({ isNc, isPb }) {
|
export const PbBadge = React.forwardRef(({ isEditButton, ...props }, ref) => {
|
||||||
if (isNc) {
|
return (
|
||||||
return <NcBadge />;
|
<ItemBadgeTooltip label="This item is only obtainable via paintbrush">
|
||||||
} else if (isPb) {
|
<Badge
|
||||||
return <PbBadge />;
|
ref={ref}
|
||||||
} else {
|
as={isEditButton ? "button" : "span"}
|
||||||
return <NpBadge />;
|
colorScheme="orange"
|
||||||
|
display="flex"
|
||||||
|
alignItems="center"
|
||||||
|
_focus={{ outline: "none", boxShadow: "outline" }}
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
PB
|
||||||
|
{isEditButton && <EditIcon fontSize="0.85em" marginLeft="1" />}
|
||||||
|
</Badge>
|
||||||
|
</ItemBadgeTooltip>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ItemKindBadge = React.forwardRef(
|
||||||
|
({ isNc, isPb, isEditButton, ...props }, ref) => {
|
||||||
|
if (isNc) {
|
||||||
|
return <NcBadge ref={ref} isEditButton={isEditButton} {...props} />;
|
||||||
|
} else if (isPb) {
|
||||||
|
return <PbBadge ref={ref} isEditButton={isEditButton} {...props} />;
|
||||||
|
} else {
|
||||||
|
return <NpBadge ref={ref} isEditButton={isEditButton} {...props} />;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
);
|
||||||
|
|
||||||
export function YouOwnThisBadge({ variant = "long" }) {
|
export function YouOwnThisBadge({ variant = "long" }) {
|
||||||
let badge = (
|
let badge = (
|
||||||
|
|
|
@ -54,6 +54,11 @@ const typeDefs = gql`
|
||||||
# layer data from this API should be interpreted!
|
# layer data from this API should be interpreted!
|
||||||
explicitlyBodySpecific: Boolean! @cacheControl(maxAge: 0)
|
explicitlyBodySpecific: Boolean! @cacheControl(maxAge: 0)
|
||||||
|
|
||||||
|
# This is set manually by Support users, when the item is from the NC Mall
|
||||||
|
# but isn't correctly labeled as r500 on Neopets.com. When this is true,
|
||||||
|
# it sets isNc to be true as well, regardless of rarityIndex.
|
||||||
|
isManuallyNc: Boolean!
|
||||||
|
|
||||||
# Get the species that we need modeled for this item for the given color.
|
# Get the species that we need modeled for this item for the given color.
|
||||||
#
|
#
|
||||||
# NOTE: Most color IDs won't be accepted here. Either pass the ID of a
|
# NOTE: Most color IDs won't be accepted here. Either pass the ID of a
|
||||||
|
@ -328,6 +333,10 @@ const resolvers = {
|
||||||
const item = await itemLoader.load(id);
|
const item = await itemLoader.load(id);
|
||||||
return item.explicitlyBodySpecific;
|
return item.explicitlyBodySpecific;
|
||||||
},
|
},
|
||||||
|
isManuallyNc: async ({ id }, _, { itemLoader }) => {
|
||||||
|
const item = await itemLoader.load(id);
|
||||||
|
return item.isManuallyNc;
|
||||||
|
},
|
||||||
speciesThatNeedModels: async (
|
speciesThatNeedModels: async (
|
||||||
{ id },
|
{ id },
|
||||||
{ colorId = "8" }, // Blue
|
{ colorId = "8" }, // Blue
|
||||||
|
|
Loading…
Reference in a new issue