88 lines
2.8 KiB
TypeScript
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}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
};
|