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

88 lines
2.8 KiB
TypeScript

import clsx from "clsx";
import { FC, useState } from "react";
import { useSelector } from "react-redux";
import ChevronRight from "@dndbeyond/fontawesome-cache/svgs/solid/chevron-right.svg";
import { Button, ButtonProps } from "~/components/Button";
import { MaxCharactersDialog } from "~/components/MaxCharactersDialog";
import { useAuth } from "~/contexts/Authentication";
import { useClaimCharacter } from "~/hooks/useClaimCharacter";
import bgImage from "~/images/claim.png";
import { appEnvSelectors } from "~/tools/js/Shared/selectors";
import { ClaimConfirmationDialog } from "../ClaimConfirmationDialog";
import styles from "./styles.module.css";
/**
* This component is used when previewing a premade character. It is displayed on the character
* sheet and renders with an onclick when signed in or a link to create an account when not signed
* in.
*/
export const ClaimPremadeButton: FC<ButtonProps> = ({
className,
...props
}) => {
const createAccountLink = `/create-account?returnUrl=${window.location.pathname}`;
const params = new URLSearchParams(globalThis.location.search);
const campaignJoinCode = params.get("campaignJoinCode");
const isAssigned = params.get("isAssigned") === "true";
const [isMaxCharacterOpen, setIsMaxCharacterOpen] = useState(false);
const user = useAuth();
const { characterSlotLimit, activeCharacterCount } = useSelector(
appEnvSelectors.getCharacterSlots
);
const [
claimCharacter,
isClaimingCharacter,
isFinishedClaimingCharacter,
newCharacterId,
campaignId,
] = useClaimCharacter({
campaignJoinCode,
isAssigned,
});
const isClaimed = isFinishedClaimingCharacter && !!newCharacterId;
// Character slot limit is null for admin accounts
const hasOpenSlot =
characterSlotLimit === null || activeCharacterCount < characterSlotLimit;
const handleClick = () => {
hasOpenSlot ? claimCharacter() : setIsMaxCharacterOpen(true);
};
return (
<>
{!isClaimed && (
<Button
className={clsx([styles.claimPremadeButton, className])}
href={!user ? createAccountLink : undefined}
onClick={!!user ? handleClick : undefined}
disabled={isClaimingCharacter}
tabIndex={0}
{...props}
>
<img className={styles.bgImage} src={bgImage} alt="" />
<div className={styles.content}>
{!user && "Create Account to "}
Claim Character <ChevronRight />
</div>
</Button>
)}
<MaxCharactersDialog
open={isMaxCharacterOpen}
onClose={() => setIsMaxCharacterOpen(false)}
useMyCharactersLink
/>
{isClaimed && (
<ClaimConfirmationDialog
characterId={newCharacterId}
campaignId={campaignId}
/>
)}
</>
);
};