Skip to content

Commit

Permalink
Merge pull request #48 from JollyGrin/feat/draft-sim-v2
Browse files Browse the repository at this point in the history
Feat/draft sim v2
  • Loading branch information
JollyGrin authored Oct 6, 2024
2 parents 864c6ff + 1b9878b commit fa6510e
Show file tree
Hide file tree
Showing 10 changed files with 473 additions and 30 deletions.
21 changes: 17 additions & 4 deletions src/components/organisms/Draft/Card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ import Tilt, { GlareProps } from "react-parallax-tilt";
import { useState } from "react";
import { CardDTO } from "@/utils/api/cardData/CardDataType";

export const DraftCard = (cardDTO: CardDTO) => {
export const DraftCard = ({
isSelected,
onSelect,
...cardDTO
}: CardDTO & {
isSelected?: boolean;
onSelect?(): void;
}) => {
const [isOver, setIsOver] = useState(false);
function over() {
setIsOver(true);
Expand All @@ -28,22 +35,28 @@ export const DraftCard = (cardDTO: CardDTO) => {
zIndex: isOver ? 10000 : 1,
transform:
isOver && cardDTO.guardian.type === "Site" ? " rotate(90deg)" : "",
filter: isOver ? `saturate(1.5)` : "saturate(1)",
filter: isOver || isSelected ? `saturate(1.5)` : "saturate(1)",
}}
>
<Tilt
{...tiltOptions}
glareColor={rarityColor[cardDTO.guardian.rarity]}
scale={isOver ? 1.2 : 1}
scale={isOver ? 1.3 : 1}
>
<Flex
justifyContent="center"
w="100%"
h="23.5rem"
// bg="plum"
filter="drop-shadow(0 0 5px rgba(0,0,0,0.35))"
onMouseOver={over}
onMouseOut={out}
alignItems="center"
onClick={onSelect}
borderRadius="0.5rem"
overflow="clip"
style={{
background: isSelected ? "rgba(0,250,100,0.5)" : "",
}}
>
<CardImage img={cardDTO.slug} />
</Flex>
Expand Down
106 changes: 106 additions & 0 deletions src/components/organisms/Draft/Ribbon/SelectedCardsModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { Box, Flex, Grid } from "styled-system/jsx";
import { Modal } from "@/components/atoms/Modal";
import { getCardImage } from "../../GameBoard/constants";
import { reduceCardCount, sortAlphabetical } from "./helpers";
import { CardDTO } from "@/utils/api/cardData/CardDataType";
import { Button } from "@/components/ui/button";
import { useCopyToClipboard } from "@/utils/hooks";
import toast from "react-hot-toast";

export const SelectedCardsModal = ({
cards = [],
isOpen,
onToggle,
}: {
cards?: CardDTO[];
isOpen?: boolean;
onToggle?(): void;
}) => {
const [, copy] = useCopyToClipboard();

return (
<>
<Modal
wrapperProps={{ open: isOpen, onOpenChange: onToggle }}
content={
<Grid
gridTemplateColumns="4fr 1fr"
minW="70vw"
minH="50vh"
maxH="70vh"
w="100%"
>
<Flex
flexWrap="wrap"
gap="0.25rem"
h="100%"
overflowY="auto"
overflowX="clip"
>
{cards.sort(sortAlphabetical).map((card, index) => (
<Box
key={card.slug + index}
width="18rem"
height="fit-content"
transition="all 0.25s ease"
_hover={{
transform: `scale(1.25) ${card.guardian.type === "Site" ? "rotate(90deg)" : ""}`,
}}
>
<img
alt="card image"
src={getCardImage(card.slug)}
height="inherit"
width="inherit"
/>
</Box>
))}
</Flex>
<Box>
{cards
.sort(sortAlphabetical)
.reduce(reduceCardCount, [])
.map((card, index) => {
return (
<Grid
key={card.name + index}
gridTemplateColumns="1.5rem auto"
>
<p>{card.count}x</p>
<p>{card.name}</p>
</Grid>
);
})}
<Button
mt="2rem"
w="100%"
onClick={() => {
const list = cards
.sort(sortAlphabetical)
.reduce(reduceCardCount, [])
.map((card) => `${card.count} ${card.name}`);
const parsed = list.join("\n");
copy(parsed);
toast.success("Copied decklist to clipboard");
}}
>
Copy Bulk List
</Button>
<p
style={{
marginTop: "0.25rem",
fontSize: "0.85rem",
opacity: 0.6,
textAlign: "center",
}}
>
Copy &amp; Paste into Curiosa &apos;bulk add&apos; in Create
Deck
</p>
</Box>
</Grid>
}
/>
</>
);
};
24 changes: 24 additions & 0 deletions src/components/organisms/Draft/Ribbon/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { CardDTO } from "@/utils/api/cardData/CardDataType";

export function sortAlphabetical(a: CardDTO, b: CardDTO) {
if (a.name < b.name) {
return -1;
}
if (a.name > b.name) {
return 1;
}
return 0;
}

export function reduceCardCount(
acc: { name: string; count: number }[],
card: Card,
) {
const existingCard = acc.find((item) => item.name === card.name);
if (existingCard) {
existingCard.count += 1;
} else {
acc.push({ name: card.name, count: 1 });
}
return acc;
}
130 changes: 125 additions & 5 deletions src/components/organisms/Draft/Ribbon/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,129 @@
import { Box } from "styled-system/jsx";
import { Button } from "@/components/ui/button";
import { Flex, Grid } from "styled-system/jsx";
import { DraftProps } from "../types";
import { generateBoosterPack } from "../helpers";
import { useCardFullData } from "@/utils/api/cardData/useCardData";
import { useState } from "react";
import { SelectedCardsModal } from "./SelectedCardsModal";

export const DraftRibbon = (
props: DraftProps & {
takeAndPass?(): void;
},
) => {
const [isOpen, setIsOpen] = useState(false);
const disclosure = {
isOpen,
toggle: () => setIsOpen((prev) => !prev),
onOpen: () => setIsOpen(true),
onClose: () => setIsOpen(true),
};

const { data: cardData = [] } = useCardFullData();

function crackBooster() {
const newBooster = generateBoosterPack({
cardData,
expansionSlug: "bet",
});
props.setPlayerData({
...props.player,
activePack: newBooster,
packsOpened: (props.player.packsOpened ?? 0) + 1,
});
}

// function takeAndPass() {
// const { activePack, finishedPacks, selectedIndex, selectedCards } =
// props.player;

// if (selectedIndex === undefined) return;

// const updatedPack = [...activePack];
// const updatedSelected = [...selectedCards];

// const [card] = updatedPack.splice(selectedIndex, 1);
// updatedSelected.push(card);

// props.setPlayerData({
// ...props.player,
// activePack: [],
// finishedPacks: [...finishedPacks, updatedPack],
// selectedIndex: undefined,
// });
// }

function activatePendingPack() {
const { pendingPacks } = props.player;
const updatedPending = [...pendingPacks];
const [pack] = updatedPending.splice(0, 1);

props.setPlayerData({
...props.player,
pendingPacks: updatedPending,
activePack: pack,
});
}

const [nextPack] = props.player.pendingPacks ?? [];

export const DraftRibbon = () => {
return (
<Box bg="brown" h="100%">
<p>ribbon</p>
</Box>
<>
<SelectedCardsModal
isOpen={disclosure.isOpen}
onToggle={disclosure.toggle}
cards={props.player.selectedCards}
/>

<Grid h="100%" bg="brown" gap={0} gridTemplateColumns="1fr 4fr 1fr">
<Flex alignItems="center" justifyContent="center">
<Button
disabled={
props.player.pendingPacks.length === 0 ||
props.player.activePack.length > 0 ||
nextPack.length === 0
}
onClick={activatePendingPack}
>
Flip pack -
{(nextPack?.length > 0 && props.player.pendingPacks.length) || " 0"}
</Button>
</Flex>
<Grid
gridTemplateColumns="repeat(3,1fr)"
alignItems="center"
p="0 0.5rem"
>
<div>
<p>{props.player.packsOpened ?? "0"} packs opened</p>
</div>

{props.player.activePack.length === 0 ? (
<Button
disabled={(nextPack ?? []).length > 0}
onClick={crackBooster}
>
Open a Pack
</Button>
) : (
<Button
disabled={props.player.selectedIndex === undefined}
onClick={props.takeAndPass}
>
Take &amp; Pass
</Button>
)}
</Grid>
<Flex alignItems="center" justifyContent="center">
<Button
bg="purple.800"
onClick={disclosure.onOpen}
borderRadius="10rem"
>
View Selected
</Button>
</Flex>
</Grid>
</>
);
};
Loading

0 comments on commit fa6510e

Please sign in to comment.