Skip to content

Commit

Permalink
Merge pull request #12 from JollyGrin/feat/hand-actions
Browse files Browse the repository at this point in the history
Feat/hand actions
  • Loading branch information
JollyGrin authored Sep 10, 2024
2 parents 06310fe + 14717d9 commit ad21150
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 24 deletions.
8 changes: 5 additions & 3 deletions src/components/atoms/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { DialogProps } from "@radix-ui/react-dialog";
import { DialogDescription, DialogProps } from "@radix-ui/react-dialog";
import { ReactNode } from "react";
import { VisuallyHidden } from "styled-system/jsx";

export const Modal = (props: {
wrapperProps: DialogProps;
Expand All @@ -18,11 +19,12 @@ export const Modal = (props: {
<Dialog {...props.wrapperProps}>
{props.trigger && <DialogTrigger>{props.trigger}</DialogTrigger>}
<DialogContent>
{props.title && (
<VisuallyHidden>
<DialogHeader>
<DialogTitle>{props.title}</DialogTitle>
<DialogDescription>modal</DialogDescription>
</DialogHeader>
)}
</VisuallyHidden>
{props.content}
</DialogContent>
</Dialog>
Expand Down
6 changes: 3 additions & 3 deletions src/components/molecules/LoadDeck/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Box, Flex } from "styled-system/jsx";
import { button, input } from "styled-system/recipes";

export const LoadDeck = (props: GameStateActions) => {
const [deckId, setDeckId] = useState<string>();
const [deckId, setDeckId] = useState<string>("");
const { data: deck } = useCuriosaDeck(deckId);
const cards = [
...(deck?.avatar ?? []),
Expand Down Expand Up @@ -70,7 +70,7 @@ export const LoadDeck = (props: GameStateActions) => {
value={deckId}
onChange={(e) => setDeckId(e.target.value)}
/>
{deckId === undefined && (
{deckId === "" && (
<>
<p>copy the deckid from curiosa</p>
<button
Expand All @@ -82,7 +82,7 @@ export const LoadDeck = (props: GameStateActions) => {
</button>
</>
)}
{deckId !== undefined && (
{deckId !== "" && (
<button
className={button()}
style={{ marginTop: "1rem" }}
Expand Down
120 changes: 102 additions & 18 deletions src/components/organisms/GameBoard/Footer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Grid, HStack } from "styled-system/jsx";
import { Box, Grid, HStack } from "styled-system/jsx";
import { GRIDS, LAYOUT_HEIGHTS } from "../constants";
import { DroppableGridItem } from "@/components/molecules/DropGridItem";
import {
Expand All @@ -11,7 +11,22 @@ import { CardAtlas } from "@/components/atoms/mock-cards/atlas";
import { CardImage } from "@/components/atoms/mock-cards/card";
import { DecksTray } from "./Decks";
import { GraveTray } from "./Grave";
import { GameCard } from "@/types/card";
import { useState } from "react";
import { Modal } from "@/components/atoms/Modal";
import { FullCardAtlas } from "@/components/atoms/card-view/atlas";
import { CardImage as FullCard } from "@/components/atoms/card-view/card";
import { button } from "styled-system/recipes";
import { actHandToBottomDeck, actHandToTopDeck } from "@/utils/actions/hand";

import {
BiArrowToTop as IconTop,
BiArrowToBottom as IconBottom,
} from "react-icons/bi";

/**
* HAND - Drag and Drop tray of all the cards in your hand
* */
export const GameFooter = (props: GameStateActions) => {
const gridIndex = GRIDS.HAND;
const cardsInHand = props.gridItems[gridIndex] ?? [];
Expand Down Expand Up @@ -45,23 +60,13 @@ export const GameFooter = (props: GameStateActions) => {
overflowX="auto"
>
{props.gridItems?.[gridIndex]?.map((card, index) => (
<div
key={card.id}
style={{
width: "100%",
maxWidth: "220px",
minWidth: "180px",
}}
>
<SortableItem
id={card.id}
gridIndex={gridIndex}
index={index}
>
{card?.type === "site" && <CardAtlas img={card?.img} />}
{card?.type !== "site" && <CardImage img={card?.img} />}
</SortableItem>
</div>
<HandCard
key={card.id + index}
card={card}
gridIndex={gridIndex}
cardIndex={index}
gameStateActions={props}
/>
))}
</HStack>
</SortableContext>
Expand All @@ -70,3 +75,82 @@ export const GameFooter = (props: GameStateActions) => {
</div>
);
};

const HandCard = ({
card,
gridIndex,
cardIndex: index,
gameStateActions,
}: {
card: GameCard;
gridIndex: number;
cardIndex: number;
gameStateActions: GameStateActions;
}) => {
const [preview, setPreview] = useState(false);
const deckType = card.type === "site" ? "atlas" : "deck";

function topDeck() {
gameStateActions.setGridItems(
actHandToTopDeck(gameStateActions.gridItems, deckType, index),
);
}

function bottomDeck() {
gameStateActions.setGridItems(
actHandToBottomDeck(gameStateActions.gridItems, deckType, index),
);
}

return (
<div
onContextMenu={(e) => {
e.preventDefault();
setPreview(true);
}}
style={{
position: "relative",
width: "100%",
maxWidth: "220px",
minWidth: "180px",
}}
>
<SortableItem id={card.id} gridIndex={gridIndex} index={index}>
{card?.type === "site" && <CardAtlas img={card?.img} />}
{card?.type !== "site" && <CardImage img={card?.img} />}
</SortableItem>

<Modal
wrapperProps={{ open: preview, onOpenChange: setPreview }}
content={
<Box h="700px" w="460px">
{card.type === "site" && <FullCardAtlas img={card.img} />}
{card.type !== "site" && <FullCard img={card.img} />}
<HStack
position="absolute"
bottom="1rem"
w="calc(100% - 3rem)"
justifyContent="center"
borderRadius="1rem"
filter="drop-shadow(0 4px 2px rgba(0,0,0,0.25))"
>
<button className={button()} onClick={topDeck}>
<HStack>
<IconTop />
<p>Top of deck</p>
</HStack>
</button>

<button className={button()} onClick={bottomDeck}>
<HStack>
<IconBottom />
<p>Bottom of deck</p>
</HStack>
</button>
</HStack>
</Box>
}
/>
</div>
);
};
62 changes: 62 additions & 0 deletions src/utils/actions/hand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { GRIDS } from "@/components/organisms/GameBoard/constants";
import { GameState } from "@/types/card";

/**
* Return a card from hand to the top of the deck
* */
export function actHandToTopDeck(
state: GameState,
deckType: "deck" | "atlas",
handCardIndex: number,
) {
// Create a shallow copy of the previous grid items array
const newState = [...state];

// choose between deck or atlas deck
const GRIDS_DECK_TYPE = deckType === "deck" ? GRIDS.DECK : GRIDS.ATLAS_DECK;

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

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

// Update the newState array
newState[GRIDS_DECK_TYPE] = newDeck;
newState[GRIDS.HAND] = newHand;

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

/**
* Return a card from hand to the top of the deck
* */
export function actHandToBottomDeck(
state: GameState,
deckType: "deck" | "atlas",
handCardIndex: number,
) {
// Create a shallow copy of the previous grid items array
const newState = [...state];

// choose between deck or atlas deck
const GRIDS_DECK_TYPE = deckType === "deck" ? GRIDS.DECK : GRIDS.ATLAS_DECK;

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

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

// Update the newState array
newState[GRIDS_DECK_TYPE] = newDeck;
newState[GRIDS.HAND] = newHand;

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

0 comments on commit ad21150

Please sign in to comment.