Skip to content

Commit

Permalink
Merge pull request #17 from JollyGrin/feat/add-player-tooltips
Browse files Browse the repository at this point in the history
Feat/add player tooltips
  • Loading branch information
JollyGrin authored Sep 14, 2024
2 parents 13f09fd + 6cda4b8 commit fe1e9fa
Show file tree
Hide file tree
Showing 11 changed files with 377 additions and 95 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@tanstack/react-query-devtools": "^5.55.4",
"axios": "^1.7.7",
"next": "14.2.8",
"polished": "^4.3.1",
"react": "^18",
"react-dom": "^18",
"react-hot-toast": "^2.4.1",
Expand Down
24 changes: 24 additions & 0 deletions pnpm-lock.yaml

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

157 changes: 106 additions & 51 deletions src/components/organisms/GameBoard/Footer/Counters/index.tsx
Original file line number Diff line number Diff line change
@@ -1,78 +1,133 @@
import { useState } from "react";
import { PlayerData, PlayerDataProps } from "@/types/card";
import { useHover } from "@/utils/hooks/useHover";
import { useRouter } from "next/router";
import { useMemo, useRef } from "react";
import { cva } from "styled-system/css/cva.mjs";
import { Flex, Grid, HStack, VStack } from "styled-system/jsx";
import { button } from "styled-system/recipes";

export const CountersTray = () => {
import { GiHealthNormal as IconHealth } from "react-icons/gi";

import { mix } from "polished";

export const CountersTray = (props: PlayerDataProps) => {
const { query } = useRouter();
const name = query?.name ?? "p1";
const me = props?.players?.[name as string].data;

function setField(field: keyof PlayerData) {
return (value: number) => {
const newData = { ...me, [field]: value };
props.setMyData(newData as PlayerData);
};
}

return (
<Flex
direction="column"
h="100%"
overflowY="auto"
p={0}
m={0}
justifyContent="center"
p="0.5rem"
justifyContent="space-between"
alignItems="center"
gap="0.5rem"
>
{(["earth", "fire", "water", "wind"] as const).map((type) => (
<Resource key={type} type={type} />
{(["life", "earth", "fire", "water", "wind"] as const).map((type) => (
<Resource
key={type}
type={type}
setValue={setField(type)}
value={me?.[type] ?? 0}
/>
))}
</Flex>
);
};

const Resource = (props: { type: "fire" | "water" | "wind" | "earth" }) => {
const [amount, setAmount] = useState(0);
const Resource = (props: {
type: "fire" | "water" | "wind" | "earth" | "life";
setValue(value: number): void;
value: number;
}) => {
const hoverRef = useRef(null);
const isHovering = useHover(hoverRef);

function increment() {
setAmount((prev) => prev + 1);
props.setValue(props.value + 1);
}

function decrement() {
setAmount((prev) => (prev === 0 ? prev : prev - 1));
if (props.value === 0) return;
props.setValue(props.value - 1);
}

const bg = useMemo(() => {
if (props.type !== "life") return "";
const percent = Math.min(props.value / 20, 1);
if (props.value > 10) return mix(percent, "#00b8a9", "#f8f3d4");
if (props.value === 10) return "#f8f3d4";
if (props.value > 1) return mix(props.value / 20, "#f8f3d4", "#f6416c");

return "purple";
}, [props.value]);

return (
<VStack gap={0} p={0}>
<Grid gridTemplateColumns="1fr 1fr" alignItems="center">
<img
src={`/icon/${props.type}.webp`}
alt="fire"
className={iconStyle()}
style={{ height: "21px", width: "20px" }}
/>
<p style={{ justifySelf: "end", fontSize: "0.8rem" }}>{amount}</p>
</Grid>
<HStack
gap={0}
p={0}
opacity="0.05"
_hover={{ opacity: 1 }}
transition="all 0.25s ease"
>
<button
onClick={decrement}
className={button({ variant: "destructive", size: "sm" })}
style={{
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
height: "20px",
}}
>
-
</button>
<VStack gap={0} p={0} ref={hoverRef} w="100%">
<Grid gridTemplateColumns="2fr 1fr" alignItems="center" w="inherit">
{isHovering && (
<HStack
gap={0}
p={0}
opacity="0.05"
_hover={{ opacity: 1 }}
transition="all 0.25s ease"
>
<button
onClick={decrement}
className={button({ variant: "destructive", size: "sm" })}
style={{
padding: "0.5rem",
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
height: "20px",
}}
>
-
</button>

<button
onClick={increment}
className={button({ size: "sm" })}
style={{
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
height: "20px",
}}
>
+
</button>
</HStack>
<button
onClick={increment}
className={button({ size: "sm" })}
style={{
padding: "0.5rem",
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
height: "20px",
}}
>
+
</button>
</HStack>
)}
{!isHovering && props.type === "life" && (
<IconHealth
color={bg}
fontSize="1rem"
style={{
filter: "drop-shadow(0 1px 1px rgba(0,0,0,0.45))",
}}
/>
)}
{!isHovering && props.type !== "life" && (
<img
src={`/icon/${props.type}.webp`}
alt="fire"
className={iconStyle()}
style={{ height: "21px", width: "20px" }}
/>
)}
<p style={{ justifySelf: "end", fontSize: "0.8rem" }}>{props.value}</p>
</Grid>
</VStack>
);
};
Expand Down
6 changes: 3 additions & 3 deletions src/components/organisms/GameBoard/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ 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 { GameCard, PlayerDataProps } from "@/types/card";
import { useState } from "react";
import { Modal } from "@/components/atoms/Modal";
import { FullCardAtlas } from "@/components/atoms/card-view/atlas";
Expand All @@ -28,7 +28,7 @@ import { CountersTray } from "./Counters";
/**
* HAND - Drag and Drop tray of all the cards in your hand
* */
export const GameFooter = (props: GameStateActions) => {
export const GameFooter = (props: GameStateActions & PlayerDataProps) => {
const gridIndex = GRIDS.HAND;
const cardsInHand = props.gridItems[gridIndex] ?? [];

Expand All @@ -50,7 +50,7 @@ export const GameFooter = (props: GameStateActions) => {
>
<GraveTray {...props} />
<DecksTray {...props} />
<CountersTray />
<CountersTray {...props} />
<DroppableGridItem id={gridIndex.toString()} gridIndex={gridIndex}>
<SortableContext
id={`grid-${gridIndex}`}
Expand Down
Loading

0 comments on commit fe1e9fa

Please sign in to comment.