Skip to content

Commit

Permalink
Merge pull request #11 from JollyGrin/feat/grave
Browse files Browse the repository at this point in the history
Feat/grave
  • Loading branch information
JollyGrin authored Sep 9, 2024
2 parents 6bb8339 + 34470e0 commit 06310fe
Show file tree
Hide file tree
Showing 12 changed files with 263 additions and 16 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"axios": "^1.7.7",
"next": "14.2.8",
"react": "^18",
"react-dom": "^18"
"react-dom": "^18",
"react-icons": "^5.3.0"
},
"devDependencies": {
"@pandacss/dev": "^0.45.2",
Expand Down
12 changes: 12 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions src/components/atoms/Modal/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
Expand All @@ -17,12 +16,14 @@ export const Modal = (props: {
}) => {
return (
<Dialog {...props.wrapperProps}>
<DialogTrigger>{props.trigger}</DialogTrigger>
{props.trigger && <DialogTrigger>{props.trigger}</DialogTrigger>}
<DialogContent>
<DialogHeader>
<DialogTitle>{props.title}</DialogTitle>
<DialogDescription>{props.content}</DialogDescription>
</DialogHeader>
{props.title && (
<DialogHeader>
<DialogTitle>{props.title}</DialogTitle>
</DialogHeader>
)}
{props.content}
</DialogContent>
</Dialog>
);
Expand Down
4 changes: 3 additions & 1 deletion src/components/atoms/card-view/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import { Box } from "styled-system/jsx";
export const CardImage = ({
img = "headless_haunt.webp",
position = "top",
minH = "300px",
}: {
img?: string;
position?: "top" | "bottom";
minH?: string;
}) => {
return (
<Box
Expand All @@ -28,7 +30,7 @@ export const CardImage = ({
}}
w="100%"
h="100%"
minH="300px"
minH={minH}
backgroundPosition="top"
backgroundSize="contain"
backgroundRepeat="no-repeat"
Expand Down
2 changes: 1 addition & 1 deletion src/components/atoms/mock-cards/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export const CardImage = ({
transform={show ? "scale(1.5)" : "unset"}
transition="all 0.25s ease"
style={{
backgroundImage: `url(${CARD_CDN}/5/${img}.webp)`,
backgroundImage: `url(${CARD_CDN}/${img}.webp)`,
}}
/>{" "}
</Box>
Expand Down
8 changes: 5 additions & 3 deletions src/components/organisms/GameBoard/Footer/Decks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ export const DecksTray = (props: GameStateActions) => {

return (
<VStack
bg="blue"
w="100%"
py="1rem"
// style={{ height: LAYOUT_HEIGHTS.footer }}
style={{ height: LAYOUT_HEIGHTS.footer }}
style={{
height: LAYOUT_HEIGHTS.footer,
background:
"linear-gradient(90deg, rgba(131,58,180,0.15) 0%, rgba(253,29,29,0.15) 50%, rgba(252,176,69,0.35) 100%)",
}}
>
<Grid
h="70px"
Expand Down
85 changes: 85 additions & 0 deletions src/components/organisms/GameBoard/Footer/Grave/DiscardModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { CardImage } from "@/components/atoms/card-view/card";
import { GameCard, GridItem } from "@/types/card";
import { Box, Grid, HStack } from "styled-system/jsx";
import { button } from "styled-system/recipes";

import { PiHandWithdrawFill as IconHand } from "react-icons/pi";
import { useHover } from "@/utils/hooks/useHover";
import { useRef } from "react";
import { GameStateActions } from "../..";
import { actDrawDiscard } from "@/utils/actions/discard";

export const DiscardModalBody = (
props: {
cards: GridItem;
} & GameStateActions,
) => {
function returnToHand(cardIndex: number) {
props.setGridItems(actDrawDiscard(props.gridItems, cardIndex));
}

return (
<Grid
gridTemplateColumns="repeat(auto-fill, minmax(300px, 1fr))"
gridTemplateRows="auto"
minW="75vw"
h="70vh"
overflowX="clip"
overflowY="scroll"
>
{props.cards?.map((card, index) => (
<Card
key={card.id}
card={card}
returnToHand={() => returnToHand(index)}
/>
))}
</Grid>
);
};

const Card = ({
card,
returnToHand,
}: {
card: GameCard;
returnToHand(): void;
}) => {
const hoverRef = useRef(null);
const isHovering = useHover(hoverRef);

return (
<Box
ref={hoverRef}
key={card.id + "discard"}
aspectRatio={8 / 11}
w="100%"
h="100%"
maxH="500px"
position="relative"
filter="saturate(1)"
_hover={{
filter: "saturate(1.75)",
}}
>
<CardImage img={card.img} minH={"0"} />
<button
onClick={returnToHand}
className={button()}
style={{
position: "absolute",
bottom: "50%",
right: "calc(50% - 50px)",
opacity: isHovering ? 1 : 0.1,
width: "100px",
transition: "all 0.25s ease",
}}
>
<HStack gap={0}>
<p>Return</p>
<IconHand size="2rem" style={{ fontSize: "2rem", color: "white" }} />
</HStack>
</button>
</Box>
);
};
114 changes: 114 additions & 0 deletions src/components/organisms/GameBoard/Footer/Grave/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { DroppableGridItem } from "@/components/molecules/DropGridItem";
import { GRIDS } from "@/components/organisms/GameBoard/constants";
import { Box, Grid } from "styled-system/jsx";

import { GiPirateGrave as IconGrave } from "react-icons/gi";
import { CardImage } from "@/components/atoms/card-view/card";
import { Modal } from "@/components/atoms/Modal";
import { useState } from "react";
import { GameStateActions } from "@/components/organisms/GameBoard";
import { DiscardModalBody } from "./DiscardModal";

export const GraveTray = (props: GameStateActions) => {
const graveCards = props.gridItems[GRIDS.GRAVE];
const graveAmount = graveCards?.length ?? 0;
const hasCards = graveCards?.length > 0;

const [preview, setPreview] = useState(false);

return (
<Box position="relative" overflow="clip" h="100%">
<IconGrave
style={{
position: "absolute",
fontSize: "6rem",
bottom: "-1rem",
left: "-0.5rem",
opacity: 0.3,
}}
/>
{preview && (
<Modal
wrapperProps={{ open: preview, onOpenChange: setPreview }}
content={<DiscardModalBody cards={graveCards} {...props} />}
/>
)}
<DroppableGridItem gridIndex={GRIDS.GRAVE} id="droppable-grave">
{hasCards && (
<Grid
position="relative"
placeItems="center"
h="100%"
cursor="pointer"
onClick={(e) => {
e.preventDefault();
setPreview(true);
}}
onContextMenu={(e) => {
e.preventDefault();
setPreview(true);
}}
>
{graveAmount > 0 && (
<Box w="100px" h="120px" position="absolute">
<CardImage img={graveCards?.[0].img} minH={"0"} />
</Box>
)}

{graveAmount > 1 && (
<Box
w="100px"
h="120px"
position="absolute"
left={9}
top={9}
rotate="4deg"
>
<CardImage img={graveCards?.[1].img} minH={"0"} />
</Box>
)}

{graveAmount > 2 && (
<Box
w="100px"
h="120px"
position="absolute"
left={4}
top={8}
rotate="-2deg"
>
<CardImage img={graveCards?.[2].img} minH={"0"} />
</Box>
)}

{graveAmount > 3 && (
<Box
w="100px"
h="120px"
position="absolute"
left={7}
top={4}
rotate="3deg"
>
<CardImage img={graveCards?.[3].img} minH={"0"} />
</Box>
)}

{graveAmount > 4 && (
<Box
w="100px"
h="120px"
position="absolute"
left={5}
top={9}
rotate="0deg"
>
<CardImage img={graveCards?.[graveAmount - 1].img} minH={"0"} />
</Box>
)}
</Grid>
)}
</DroppableGridItem>
</Box>
);
};
5 changes: 3 additions & 2 deletions src/components/organisms/GameBoard/Footer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Grid, HStack } from "styled-system/jsx";
import { Grid, HStack } from "styled-system/jsx";
import { GRIDS, LAYOUT_HEIGHTS } from "../constants";
import { DroppableGridItem } from "@/components/molecules/DropGridItem";
import {
Expand All @@ -10,6 +10,7 @@ import { SortableItem } from "@/components/molecules/SortItem";
import { CardAtlas } from "@/components/atoms/mock-cards/atlas";
import { CardImage } from "@/components/atoms/mock-cards/card";
import { DecksTray } from "./Decks";
import { GraveTray } from "./Grave";

export const GameFooter = (props: GameStateActions) => {
const gridIndex = GRIDS.HAND;
Expand All @@ -25,7 +26,7 @@ export const GameFooter = (props: GameStateActions) => {
}}
>
<Grid h="100%" gridTemplateColumns="repeat(2,150px) 1fr" gap={0}>
<Box bg="yellow">Grave</Box>
<GraveTray {...props} />
<DecksTray {...props} />
<DroppableGridItem id={gridIndex.toString()} gridIndex={gridIndex}>
<SortableContext
Expand Down
2 changes: 1 addition & 1 deletion src/components/organisms/GameBoard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ const SortItemWrapper = ({
<Modal
wrapperProps={{ open: preview, onOpenChange: setPreview }}
content={
<Box h="600px">
<Box h="600px" w="460px">
{card.type === "site" && <FullCardAtlas img={card.img} />}
{card.type !== "site" && <FullCard img={card.img} />}
</Box>
Expand Down
9 changes: 8 additions & 1 deletion src/components/ui/dialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,14 @@ const Content = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
{...props}
style={{ background: "transparent", border: 0, boxShadow: "none" }}
style={{
background: "transparent",
// border: "solid 1rem black",
border: 0,
// boxShadow: "none",
maxWidth: "80vw",
width: "fit-content",
}}
>
{children}
{/* <DialogClose> */}
Expand Down
22 changes: 22 additions & 0 deletions src/utils/actions/discard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { GRIDS } from "@/components/organisms/GameBoard/constants";
import { GameState } from "@/types/card";

export function actDrawDiscard(state: GameState, graveCardIndex: number) {
// Create a shallow copy of the previous grid items array
const newState = [...state];

// Make a copy of the deck and hand arrays, preserving their positions
const newGrave = [...newState[GRIDS.GRAVE]];
const newHand = [...newState[GRIDS.HAND]];

// Pop a card from the deck and push it to the hand
const [card] = newGrave.splice(graveCardIndex, 1);
if (card) newHand.push(card);

// Update the newState array with the updated deck and hand arrays
newState[GRIDS.GRAVE] = newGrave;
newState[GRIDS.HAND] = newHand;

// Return the updated newState array to trigger a re-render
return newState;
}

0 comments on commit 06310fe

Please sign in to comment.