Files
dndbeyond_src/ddb_main/subApps/sheet/components/MagicItemPlans/MagicItemPlans.tsx
T

136 lines
4.1 KiB
TypeScript

import clsx from "clsx";
import { FC, HTMLAttributes, MouseEvent } from "react";
import {
characterActions,
Item,
ItemPlan,
ItemPlanUtils,
ItemUtils,
} from "@dndbeyond/character-rules-engine";
import { Button } from "~/components/Button";
import { useSidebar } from "~/contexts/Sidebar";
import { useCharacterEngine } from "~/hooks/useCharacterEngine";
import { useDispatch } from "~/hooks/useDispatch";
import { PaneIdentifierUtils } from "~/tools/js/Shared/utils";
import ItemPreview from "~/tools/js/smartComponents/ItemPreview";
import { PaneComponentEnum } from "../Sidebar/types";
import styles from "./styles.module.css";
export interface MagicItemPlansProps extends HTMLAttributes<HTMLDivElement> {}
export const MagicItemPlans: FC<MagicItemPlansProps> = ({
className,
...props
}) => {
const { characterTheme, itemPlans, maxReplicatedItemsCount } =
useCharacterEngine();
const {
pane: { paneHistoryStart },
} = useSidebar();
const dispatch = useDispatch();
const itemPlanWithMappingsCount = itemPlans.filter((plan) =>
ItemPlanUtils.getItem(plan)
).length;
const atMax =
maxReplicatedItemsCount !== null &&
itemPlanWithMappingsCount >= maxReplicatedItemsCount;
const handleItemPlansManagePaneShow = (
e: MouseEvent<HTMLButtonElement>
): void => {
e.preventDefault();
e.stopPropagation();
paneHistoryStart(PaneComponentEnum.ITEM_PLANS_MANAGE);
};
const handleItemClick = (item: Item): void => {
const inventoryMappingId = ItemUtils.getMappingId(item);
if (inventoryMappingId) {
paneHistoryStart(
PaneComponentEnum.ITEM_DETAIL,
PaneIdentifierUtils.generateItem(inventoryMappingId)
);
}
};
const handleReplicateItem = (itemPlan: ItemPlan): void => {
const itemDefinitionKey = ItemPlanUtils.getItemDefinitionKey(itemPlan);
const itemPlanOriginDefinitionKey =
ItemPlanUtils.getOriginDefinitionKey(itemPlan);
if (itemDefinitionKey) {
dispatch(
characterActions.itemPlanInventoryMappingCreate(
itemDefinitionKey,
1,
itemPlanOriginDefinitionKey
)
);
}
};
return (
<div className={clsx([styles.magicItemPlans, className])} {...props}>
{itemPlans.length > 0 ? (
itemPlans.map((plan) => {
const planOriginDefinitionKey =
ItemPlanUtils.getOriginDefinitionKey(plan);
const planName = ItemPlanUtils.getItemName(plan);
const itemDefinitionKey = ItemPlanUtils.getItemDefinitionKey(plan);
const item = ItemPlanUtils.getItem(plan);
const planDescription = ItemPlanUtils.getDescription(plan);
return itemDefinitionKey ? (
<div className={styles.itemPlan} key={planOriginDefinitionKey}>
<div className={styles.planHeader}>
<p className={styles.planName}>{planName}</p>
<p className={styles.description}>{planDescription}</p>
</div>
<div className={styles.itemContent}>
{item ? (
<div className={styles.itemPreview}>
<ItemPreview
theme={characterTheme}
item={item}
onClick={() => handleItemClick(item)}
/>
</div>
) : (
<Button
className={styles.replicateButton}
themed
size="xx-small"
onClick={() => handleReplicateItem(plan)}
disabled={atMax}
>
{atMax ? "At Max Replicated Items" : "Replicate Item"}
</Button>
)}
</div>
</div>
) : null;
})
) : (
<div className={styles.empty}>
No Magic Item plans have been selected for this character
<Button
className={styles.emptyButton}
themed
size="x-small"
onClick={handleItemPlansManagePaneShow}
>
Add Magic Item Plans
</Button>
</div>
)}
</div>
);
};