New source found from dndbeyond.com
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
import clsx from "clsx";
|
||||
import { FC, HTMLAttributes, useEffect, useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import VideoIcon from "@dndbeyond/fontawesome-cache/svgs/solid/video.svg";
|
||||
import CloseIcon from "@dndbeyond/fontawesome-cache/svgs/solid/x.svg";
|
||||
|
||||
import { Button } from "~/components/Button";
|
||||
import { Dialog } from "~/components/Dialog";
|
||||
import { MaxCharactersDialog } from "~/components/MaxCharactersDialog";
|
||||
import { useAuth } from "~/contexts/Authentication";
|
||||
import { useClaimCharacter } from "~/hooks/useClaimCharacter";
|
||||
import { appEnvSelectors } from "~/tools/js/Shared/selectors";
|
||||
|
||||
import { ClaimConfirmationDialog } from "../ClaimConfirmationDialog";
|
||||
import styles from "./styles.module.css";
|
||||
|
||||
export interface WatchTourDialogProps extends HTMLAttributes<HTMLDivElement> {}
|
||||
|
||||
export const WatchTourDialog: FC<WatchTourDialogProps> = ({
|
||||
className,
|
||||
...props
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [isMaxCharacterMessageOpen, setIsMaxCharacterMessageOpen] =
|
||||
useState(false);
|
||||
const user = useAuth();
|
||||
const { characterSlotLimit, activeCharacterCount } = useSelector(
|
||||
appEnvSelectors.getCharacterSlots
|
||||
);
|
||||
|
||||
// Character slot limit is null for admin accounts
|
||||
const hasOpenSlot =
|
||||
characterSlotLimit === null || activeCharacterCount < characterSlotLimit;
|
||||
const signedIn = !!user;
|
||||
const signupLink = `/create-account?returnUrl=${window.location.pathname}`;
|
||||
const params = new URLSearchParams(globalThis.location.search);
|
||||
const campaignJoinCode = params.get("campaignJoinCode");
|
||||
const isAssigned = params.get("isAssigned") !== "false";
|
||||
|
||||
const [
|
||||
claimCharacter,
|
||||
isClaimingCharacter,
|
||||
isFinishedClaimingCharacter,
|
||||
newCharacterId,
|
||||
campaignId,
|
||||
] = useClaimCharacter({
|
||||
campaignJoinCode,
|
||||
isAssigned,
|
||||
});
|
||||
|
||||
const handleOpen = () => setIsOpen(true);
|
||||
|
||||
const handleClose = () => setIsOpen(false);
|
||||
|
||||
const handleClaim = () => {
|
||||
if (hasOpenSlot) {
|
||||
claimCharacter();
|
||||
} else {
|
||||
setIsMaxCharacterMessageOpen(true);
|
||||
setIsOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isFinishedClaimingCharacter) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
}, [isFinishedClaimingCharacter]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={clsx([styles.watchTourDialog, className])} {...props}>
|
||||
<Button
|
||||
className={styles.trigger}
|
||||
onClick={handleOpen}
|
||||
color="secondary"
|
||||
size="x-small"
|
||||
>
|
||||
<VideoIcon />
|
||||
Watch Tour
|
||||
</Button>
|
||||
<Dialog
|
||||
className={styles.dialog}
|
||||
open={isOpen}
|
||||
onClose={handleClose}
|
||||
modal
|
||||
>
|
||||
<header className={styles.header}>
|
||||
<h2 className={styles.title}>D&D Beyond Character Sheet Tour</h2>
|
||||
<Button
|
||||
className={styles.closeButton}
|
||||
variant="tool"
|
||||
onClick={handleClose}
|
||||
aria-label="Close Modal"
|
||||
>
|
||||
<CloseIcon />
|
||||
</Button>
|
||||
</header>
|
||||
<div className={styles.content}>
|
||||
<div className={styles.videoWrapper}>
|
||||
<iframe
|
||||
className={styles.video}
|
||||
src="https://www.youtube-nocookie.com/embed/ChYPIdCrBdE"
|
||||
title="D&D Beyond Sheet Tour"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
/>
|
||||
</div>
|
||||
<p>
|
||||
For a complete guide to getting your game started, see{" "}
|
||||
<a href="https://www.dndbeyond.com/posts/754-how-to-play-dungeons-dragons-using-d-d-beyond">
|
||||
How to Play Dungeons & Dragons Using D&D Beyond
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
</div>
|
||||
<footer className={styles.footer}>
|
||||
<Button
|
||||
className={styles.claimButton}
|
||||
{...(!signedIn && { href: signupLink })}
|
||||
{...(signedIn && { onClick: handleClaim })}
|
||||
disabled={isClaimingCharacter}
|
||||
color="info"
|
||||
size="x-small"
|
||||
>
|
||||
Claim Character
|
||||
</Button>
|
||||
</footer>
|
||||
</Dialog>
|
||||
</div>
|
||||
<MaxCharactersDialog
|
||||
open={isMaxCharacterMessageOpen}
|
||||
onClose={() => setIsMaxCharacterMessageOpen(false)}
|
||||
useMyCharactersLink
|
||||
/>
|
||||
{isFinishedClaimingCharacter && !!newCharacterId && (
|
||||
<ClaimConfirmationDialog
|
||||
characterId={newCharacterId ?? 0}
|
||||
campaignId={campaignId}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user