diff --git a/public/counterIcon.svg b/public/counterIcon.svg new file mode 100644 index 00000000..4c91b9d1 --- /dev/null +++ b/public/counterIcon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/app/_components/Gameboard/Board/Board.tsx b/src/app/_components/Gameboard/Board/Board.tsx index f0d76e37..1dc64ee0 100644 --- a/src/app/_components/Gameboard/Board/Board.tsx +++ b/src/app/_components/Gameboard/Board/Board.tsx @@ -1,12 +1,26 @@ import React from "react"; import Grid from "@mui/material/Grid2"; import UnitsBoard from "../_subcomponents/UnitsBoard"; -import LeaderBaseBoard from "../../_sharedcomponents/LeaderBaseBoard/LeaderBaseBoard"; import { IBoardProps } from "@/app/_components/Gameboard/GameboardTypes"; +import {useGame} from "@/app/_contexts/Game.context"; +import LeaderBaseCard from "@/app/_components/_sharedcomponents/Cards/LeaderBaseCard/LeaderBaseCard"; +import {Box, Typography} from "@mui/material"; +import CardActionTray from "@/app/_components/Gameboard/_subcomponents/PlayerTray/CardActionTray"; const Board: React.FC = ({ sidebarOpen, }) => { + const { gameState, connectedPlayer } = useGame(); + + const titleOpponent = + connectedPlayer === "ThisIsTheWay" ? "Order66" : "ThisIsTheWay"; + + const playerLeader = gameState?.players[connectedPlayer].leader; + const playerBase = gameState?.players[connectedPlayer].base; + const opponentLeader = gameState?.players[titleOpponent].leader; + const opponentBase = gameState?.players[titleOpponent].base; + + //----------------Styles----------------// const leftColumnStyle = { justifyContent: "flex-end", @@ -17,7 +31,39 @@ const Board: React.FC = ({ justifyContent: "flex-start", alignItems: "center", }; + const containerStyle = { + height: "100%", + width: "100%", + justifyContent: "center", + alignItems: "center" + }; + const lobbyLeaderBaseContainer = { + display: "flex", + flexDirection: "column", + alignItems: "center", + width: "100%", + } + const rowStyle = { + flexGrow: 1, + width: "100%" + }; + //the title of the deck i believe + const redBoxStyle = { + position: "absolute", + bottom: "10px", + left: "50%", + transform: "translateX(-50%)", + backgroundColor: "red", + borderRadius: "4px", + p: "4px 8px", + }; + const redBoxTypographyStyle = { + color: "white", + fontFamily: "var(--font-barlow), sans-serif", + fontWeight: "600", + fontSize: "1em", + }; return ( @@ -26,7 +72,33 @@ const Board: React.FC = ({ /> - + + + + + + + + + + + + + + + + + void; } -export interface ICardAreaProps { - cards: ICardData[]; -} - export interface IUnitsBoardProps { sidebarOpen: boolean; arena: string; diff --git a/src/app/_components/Gameboard/_subcomponents/Overlays/ResourcesOverlay/ResourcesOverlay.tsx b/src/app/_components/Gameboard/_subcomponents/Overlays/ResourcesOverlay/ResourcesOverlay.tsx index 440a2fe1..b1907ac9 100644 --- a/src/app/_components/Gameboard/_subcomponents/Overlays/ResourcesOverlay/ResourcesOverlay.tsx +++ b/src/app/_components/Gameboard/_subcomponents/Overlays/ResourcesOverlay/ResourcesOverlay.tsx @@ -10,9 +10,10 @@ import { IconButton, } from "@mui/material"; import { Close } from "@mui/icons-material"; -import CardArea from "../../../../_sharedcomponents/CardArea/CardArea"; +import { ICardData } from "@/app/_components/_sharedcomponents/Cards/CardTypes"; import { IResourcesOverlayProps } from "@/app/_components/Gameboard/GameboardTypes"; import { useGame } from "@/app/_contexts/Game.context"; +import GameCard from "@/app/_components/_sharedcomponents/Cards/GameCard/GameCard"; const ResourcesOverlay: React.FC = ({ isModalOpen, @@ -20,7 +21,14 @@ const ResourcesOverlay: React.FC = ({ }) => { const { gameState, connectedPlayer } = useGame(); - + const mainContainerStyle = { + display: "flex", + flexWrap: "wrap", + gap: "1em", + p: "1em", + justifyContent: "center", + textWrap: "wrap", + }; return ( = ({ Your Resources - - + + {gameState.players[connectedPlayer].cardPiles["resources"].map((card: ICardData) => ( + + ))} + = ({ {cards.map((card) => ( + card={card}/> ))} diff --git a/src/app/_components/Gameboard/_subcomponents/UnitsBoard.tsx b/src/app/_components/Gameboard/_subcomponents/UnitsBoard.tsx index dcdd7d10..fcb56169 100644 --- a/src/app/_components/Gameboard/_subcomponents/UnitsBoard.tsx +++ b/src/app/_components/Gameboard/_subcomponents/UnitsBoard.tsx @@ -55,7 +55,7 @@ const UnitsBoard: React.FC = ({ {opponentUnits.map((card: ICardData) => ( - + ))} @@ -64,7 +64,7 @@ const UnitsBoard: React.FC = ({ {playerUnits.map((card: ICardData) => ( - + ))} diff --git a/src/app/_components/Lobby/Deck/Deck.tsx b/src/app/_components/Lobby/Deck/Deck.tsx index dd57d0c0..4bda5010 100644 --- a/src/app/_components/Lobby/Deck/Deck.tsx +++ b/src/app/_components/Lobby/Deck/Deck.tsx @@ -1,8 +1,9 @@ import React from "react"; -import { Card, Box, Typography } from "@mui/material"; -import CardArea from "../../_sharedcomponents/CardArea/CardArea"; +import {Card, Box, Typography, Divider} from "@mui/material"; +import { ICardData, IServerCardData } from "@/app/_components/_sharedcomponents/Cards/CardTypes"; import { useDragScroll } from "@/app/_utils/useDragScroll"; - +import {useGame} from "@/app/_contexts/Game.context"; +import GameCard from "@/app/_components/_sharedcomponents/Cards/GameCard/GameCard"; const Deck: React.FC = () => { // Use the custom hook with horizontal or vertical scrolling as required @@ -15,24 +16,28 @@ const Deck: React.FC = () => { handleTouchMove, handleTouchEnd, } = useDragScroll("vertical"); - //------------------------STYLES------------------------// - const cardStyle = { borderRadius: "1.1em", + pt: ".8em", height: "90vh", width: "100%", display: "flex", flexDirection: "column", - mt: "2.6em", - backgroundColor: "#000000E6", - backdropFilter: "blur(20px)", + backgroundColor: "#00000080", + backdropFilter: "blur(30px)", overflow: "hidden", + '@media (max-height: 759px)': { + height: '84vh', + }, + '@media (max-height: 1000px)': { + maxHeight: '85.5vh', + }, }; const headerBoxStyle = { display: "flex", - height: "10vh", + height: "50px", width: "100%", justifyContent: "space-between", position: "sticky", @@ -54,11 +59,34 @@ const Deck: React.FC = () => { color: "white", mr: ".6em", }; - + const dividerStyle = { + backgroundColor: "#fff", + mt: ".5vh", + mb: "0.5vh", + width: "80%", + alignSelf: "center", + height: "1px", + }; + const scrollableBoxStyleSideboard = { + flexGrow: 1, + height: "21%", + minHeight: "183px", + overflowY: "auto", + "::-webkit-scrollbar": { + width: "0.2vw", + }, + "::-webkit-scrollbar-thumb": { + backgroundColor: "#D3D3D3B3", + borderRadius: "1vw", + }, + "::-webkit-scrollbar-button": { + display: "none", + }, + transition: "scrollbar-color 0.3s ease-in-out", + }; const scrollableBoxStyle = { flexGrow: 1, overflowY: "auto", - px: "5em", "::-webkit-scrollbar": { width: "0.2vw", }, @@ -71,29 +99,87 @@ const Deck: React.FC = () => { }, transition: "scrollbar-color 0.3s ease-in-out", }; + const mainContainerStyle = { + display: "flex", + flexWrap: "wrap", + gap: "1em", + p: "1em", + justifyContent: "center", + textWrap: "wrap", + }; + const { connectedDeck, updateDeck } = useGame(); + const newDeck = connectedDeck?.deckCards ?? []; + const sideBoard = connectedDeck?.sideboard ?? []; + // Calculate the total counts + const deckCount = newDeck.reduce( + (sum: number, item: { count: number; }) => sum + (item.count || 0), + 0 + ) ?? 0; + + const sideboardCount = sideBoard.reduce( + (sum: number, item: { count: number; }) => sum + (item.count || 0), + 0 + ) ?? 0; return ( - - - Your Deck - - 0/0 - - - - - - + + + + Your Deck + + {deckCount}/50 + + + + + {newDeck.map((card:IServerCardData) => ( + updateDeck(['Deck', card.card.id])} + /> + ))} + + + {sideBoard?.length > 0 && ( + <> + + Sideboard + + + {sideboardCount}/10 + + + + + {sideBoard.map((card:IServerCardData) => ( + updateDeck(['Sideboard', card.card.id])} + /> + ))} + + + + )} + + ); }; -export default Deck; +export default Deck; \ No newline at end of file diff --git a/src/app/_components/Lobby/Players/Players.tsx b/src/app/_components/Lobby/Players/Players.tsx index 8a7b0f0e..6ecdbf4b 100644 --- a/src/app/_components/Lobby/Players/Players.tsx +++ b/src/app/_components/Lobby/Players/Players.tsx @@ -1,39 +1,141 @@ // Players.tsx import React from "react"; import { Card, Box, Typography } from "@mui/material"; -import LeaderBaseBoard from "../../_sharedcomponents/LeaderBaseBoard/LeaderBaseBoard"; +import Grid from "@mui/material/Grid2"; import { IPlayersProps } from "../LobbyTypes"; +import LeaderBaseCard from "@/app/_components/_sharedcomponents/Cards/LeaderBaseCard/LeaderBaseCard"; +import {useGame} from "@/app/_contexts/Game.context"; const Players: React.FC = ({ isLobbyView }) => { //------------------------STYLES------------------------// + const { connectedPlayer, connectedDeck } = useGame(); + + const titleOpponent = + connectedPlayer === "ThisIsTheWay" ? "Order66" : "ThisIsTheWay"; + let playerLeader = null; + let playerBase = null; + + // we get the connected deck + if (connectedDeck) { + playerLeader = connectedDeck.leader[0].card; + playerBase = connectedDeck.base[0].card; + } const cardStyle = { borderRadius: "1.1em", borderColor: "#FFFFFF00", - height: "90vh", + height:"90vh", // For small screens and up (600px and above) width: "80%", + minWidth: "212px", display: "flex", flexDirection: isLobbyView ? "column" : "row", justifyContent: isLobbyView ? "flex-start" : "center", - mt: "2.6em", pt: ".8em", - backgroundColor: "#000000E6", - backdropFilter: "blur(20px)", + backgroundColor: "#00000080", + backdropFilter: "blur(30px)", + '@media (max-height: 759px)': { + height: '84vh', + }, + '@media (max-height: 1000px)': { + maxHeight: '85.5vh', + }, + "::-webkit-scrollbar": { + width: "0.2vw", + }, + "::-webkit-scrollbar-thumb": { + backgroundColor: "#D3D3D3B3", + borderRadius: "1vw", + }, + "::-webkit-scrollbar-button": { + display: "none", + }, + transition: "scrollbar-color 0.3s ease-in-out", }; const typographyStyle = { - fontSize: "2.4em", + fontSize: "2.0em", fontWeight: "bold", color: "white", - ml: ".6em", - pt: ".2em", + ml: "30px", + mb: "0px" }; + const lobbyLeaderBaseContainer = { + display: "flex", + flexDirection: "column", + alignItems: "center", + width: "100%", + } + const containerStyle = { + height: "100%", + width: "100%", + justifyContent: "center", + alignItems: "center" + }; + const rowStyle = { + flexGrow: 1, + width: "100%", + alignItems: "center", + justifyContent: "center", + display: "flex" + }; + const titleTypographyStyle = { + fontFamily: "var(--font-barlow), sans-serif", + fontWeight: "600", + fontSize: "1.5em", + marginBottom: isLobbyView ? 0 : "0.5em", + textAlign: "left", + color: "white", + }; + const titleTypographyStyleOpponent = { + fontFamily: "var(--font-barlow), sans-serif", + fontWeight: "600", + fontSize: "1.5em", + marginBottom: "10px", + textAlign: "left" as const, + color: "white", + opacity: "15%", + } return ( Players - + + + + + {connectedPlayer} + + + + + + + + + {titleOpponent === undefined ? "Opponent" : titleOpponent} + + + + + + ); diff --git a/src/app/_components/Lobby/SetUp/SetUp.tsx b/src/app/_components/Lobby/SetUp/SetUp.tsx index a38502f6..f20a4c92 100644 --- a/src/app/_components/Lobby/SetUp/SetUp.tsx +++ b/src/app/_components/Lobby/SetUp/SetUp.tsx @@ -1,8 +1,10 @@ +import React from "react"; import { Card, Typography, CardActions, - Button + Button, + Box, Divider, } from "@mui/material"; import Chat from "@/app/_components/_sharedcomponents/Chat/Chat"; import GameLinkCard from "../_subcomponents/GameLinkCard/GameLinkCard"; @@ -20,32 +22,39 @@ const SetUp: React.FC = ({ const { sendMessage } = useGame(); const router = useRouter(); const searchParams = useSearchParams(); - // Extract the player from the URL query params const player = searchParams.get("player"); - const handleStartGame = () => { + const handleStartGame = async () => { sendMessage("startGame"); - if (player){ + if (player) { router.push("/GameBoard?player=" + player); - }else { + } else { router.push("/GameBoard"); } - } + + }; //------------------------STYLES------------------------// const mainCardStyle = { borderRadius: "1.1em", - height: "auto", + height: "100%", + maxHeight: "72.5vh", width: "100%", display: "flex", flexDirection: "column", - mt: "2.6em", + mt: "2.0em", p: "1.8em", - backgroundColor: "#000000E6", - backdropFilter: "blur(20px)", + backgroundColor: "#00000080", + backdropFilter: "blur(30px)", overflow: "hidden", + '@media (max-height: 1000px)': { + maxHeight: '67vh', + }, + '@media (max-height: 759px)': { + maxHeight: '64.3vh', + }, }; const initiativeCardStyle = { @@ -67,26 +76,63 @@ const SetUp: React.FC = ({ fontWeight: "800", color: "white", alignSelf: "flex-start", - mt: "1.3em", }; - + const lobbyTextStyle ={ + fontSize: "3.0em", + fontWeight: "600", + color: "white", + alignSelf: "flex-start", + mb: "0.3em", + }; + const exitCard = { + display: "flex", + pr: "1.2em", + pl: "1.2em", + width: "100%", + height: "10%", + alignItems: "center", + justifyContent: "space-between", + cursor: "pointer", + }; + const dividerStyle = { + backgroundColor: "#fff", + mt: ".5vh", + mb: "0.5vh", + }; + const boxContainer = { + width: "100%", + //maxHeight: "64vh", // this is for the small screen + height: "100%", + }; + const handleExit = () => { + router.push("/"); + } return ( - + + KARABAST - Set Up - - - - + + + + handleExit()}> + + Exit Game Lobby + + + {'<'} + + + + ); }; diff --git a/src/app/_components/Lobby/_subcomponents/GameLinkCard/GameLinkCard.tsx b/src/app/_components/Lobby/_subcomponents/GameLinkCard/GameLinkCard.tsx index 457d1c44..73b082a2 100644 --- a/src/app/_components/Lobby/_subcomponents/GameLinkCard/GameLinkCard.tsx +++ b/src/app/_components/Lobby/_subcomponents/GameLinkCard/GameLinkCard.tsx @@ -12,7 +12,7 @@ const GameLinkCard: React.FC = () => { //------------------------STYLES------------------------// const cardStyle = { - height: "15vh", + height: "fit-content", background: "#18325199", pb: "4vh", backgroundColor: "#000000E6", diff --git a/src/app/_components/_sharedcomponents/CardArea/CardArea.tsx b/src/app/_components/_sharedcomponents/CardArea/CardArea.tsx deleted file mode 100644 index 5a73a167..00000000 --- a/src/app/_components/_sharedcomponents/CardArea/CardArea.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from "react"; -import { Box } from "@mui/material"; -import GameCard from "../Cards/GameCard/GameCard"; -import { ICardAreaProps } from "@/app/_components/Gameboard/GameboardTypes"; - -const CardArea: React.FC = ({ cards }) => { - //------------------------STYLES------------------------// - const mainContainerStyle = { - display: "flex", - flexWrap: "wrap", - gap: "3em", - p: "1em", - justifyContent: "center", - textWrap: "wrap", - }; - - return ( - - {cards.map((card) => ( - - ))} - - ); -}; - -export default CardArea; diff --git a/src/app/_components/_sharedcomponents/Cards/CardTypes.ts b/src/app/_components/_sharedcomponents/Cards/CardTypes.ts index bf047f0c..f78dc54c 100644 --- a/src/app/_components/_sharedcomponents/Cards/CardTypes.ts +++ b/src/app/_components/_sharedcomponents/Cards/CardTypes.ts @@ -22,10 +22,16 @@ export interface ICardData { setId: ICardSetId; type: string; } - -export interface IGameCardProps { +export interface IServerCardData { + count: number; card: ICardData; +} +export interface IGameCardProps { + card: ICardData | IServerCardData; size?: "standard" | "square"; + onClick?: () => void; + variant?: "lobby" | "gameboard"; + disabled?: boolean; } export interface ILeaderBaseCardProps { @@ -35,4 +41,5 @@ export interface ILeaderBaseCardProps { handleSelect?: () => void; title?: string; card: ICardData; + disabled?: boolean; } \ No newline at end of file diff --git a/src/app/_components/_sharedcomponents/Cards/GameCard/GameCard.tsx b/src/app/_components/_sharedcomponents/Cards/GameCard/GameCard.tsx index 4182fa16..ed517a83 100644 --- a/src/app/_components/_sharedcomponents/Cards/GameCard/GameCard.tsx +++ b/src/app/_components/_sharedcomponents/Cards/GameCard/GameCard.tsx @@ -2,25 +2,42 @@ import React from "react"; import { Card as MuiCard, CardContent, - CardActionArea, Typography, Box, } from "@mui/material"; import Image from "next/image"; -import { IGameCardProps, ICardData } from "@/app/_components/_sharedcomponents/Cards/CardTypes"; +import { IGameCardProps, ICardData, IServerCardData } from "@/app/_components/_sharedcomponents/Cards/CardTypes"; import { useGame } from "@/app/_contexts/Game.context"; import { s3CardImageURL } from "@/app/_utils/s3Utils"; +// Type guard to check if the card is ICardData +const isICardData = (card: ICardData | IServerCardData): card is ICardData => { + return (card as ICardData).uuid !== undefined; +}; + const GameCard: React.FC = ({ card, size = "standard", + onClick, + variant, + disabled = false, }) => { // const isLobbyView = path === "/lobby"; - const isLobbyView = false; - const isFaceUp = true + const isFaceUp = true; + // Determine whether card is ICardData or IServerCardData + const cardData = isICardData(card) ? card : card.card; + const cardCounter = !isICardData(card) ? card.count : 0; const { sendGameMessage } = useGame(); + // default on click + const defaultClickFunction = () => { + if (cardData.selectable) { + sendGameMessage(["cardClicked", cardData.uuid]); + } + }; + + const handleClick = onClick ?? defaultClickFunction; const cardBorderColor = (card: ICardData) => { if (card.selected) return "yellow"; if (card.selectable) return "limegreen"; @@ -31,22 +48,35 @@ const GameCard: React.FC = ({ const styles = { cardStyles: { borderRadius: ".38em", - height: size === "standard" ? "10rem" : "8rem", - width: size === "standard" ? "7.18rem" : "8rem", + ...(variant === "lobby" + ? { + height: "13rem", + width: "10rem", + minWidth: "101px", + minHeight: "151px", + overflow: "hidden", + cursor: "pointer", + backgroundColor: "transparent", + } + : { + // For "standard" or other sizes: + height: size === "standard" ? "10rem" : "8rem", + width: size === "standard" ? "7.18rem" : "8rem", + } + ), }, + cardContentStyle: { width: "100%", height: "100%", position: "relative", - padding: ".5em", textAlign: "center", whiteSpace: "normal", - backgroundColor: "black", - backgroundImage: `url(${s3CardImageURL(card)})`, + backgroundColor: "transparent", + backgroundImage: `url(${s3CardImageURL(cardData)})`, backgroundSize: size === "standard" ? "contain" : "cover", backgroundPosition: size === "standard" ? "center" : "top", backgroundRepeat: "no-repeat", - border: `2px solid ${cardBorderColor(card)}`, }, imageStyle: { width: "2.5rem", @@ -58,21 +88,39 @@ const GameCard: React.FC = ({ fontSize: "1.3em", margin: 0, }, - } + iconLayer:{ + position: "absolute", + width: "100%", + display: "flex", + height: "20%", + bottom: "0px", + backgroundPosition: "center", + backgroundSize: "contain", + backgroundRepeat: "no-repeat", + backgroundImage: `url(/counterIcon.svg)`, + alignItems: "center", + justifyContent: "center", + }, + numberStyle:{ + fontSize: "2rem", + fontWeight: "700", + } + } return ( { - if (card.selectable) { - sendGameMessage(["cardClicked", card.uuid]); - } - }} + + onClick={disabled ? undefined : handleClick} > {isFaceUp ? ( - + {variant === "lobby" && ( + + {cardCounter} + + )} ) : ( @@ -98,4 +146,4 @@ const GameCard: React.FC = ({ ); }; -export default GameCard; +export default GameCard; \ No newline at end of file diff --git a/src/app/_components/_sharedcomponents/Cards/LeaderBaseCard/LeaderBaseCard.tsx b/src/app/_components/_sharedcomponents/Cards/LeaderBaseCard/LeaderBaseCard.tsx index c525ac9c..96ebd857 100644 --- a/src/app/_components/_sharedcomponents/Cards/LeaderBaseCard/LeaderBaseCard.tsx +++ b/src/app/_components/_sharedcomponents/Cards/LeaderBaseCard/LeaderBaseCard.tsx @@ -1,10 +1,10 @@ import React from "react"; import { - Card, - CardActionArea, - CardContent, - Typography, - Box, + Card, + CardActionArea, + CardContent, + Typography, + Box, } from "@mui/material"; import { ILeaderBaseCardProps } from "../CardTypes"; import { ICardData } from "../CardTypes"; @@ -13,116 +13,123 @@ import { s3CardImageURL } from "@/app/_utils/s3Utils"; const LeaderBaseCard: React.FC = ({ - variant, - isLobbyView = false, - title, - card + variant, + isLobbyView = false, + title, + card, + disabled = false, }) => { - const cardBorderColor = (card: ICardData) => { - if (!card) return ""; - if (card.selected) return "yellow"; - if (card.selectable) return "limegreen"; - if (card.exhausted) return "gray"; - return "black"; - }; + const cardBorderColor = (card: ICardData) => { + if (!card) return ""; + if (card.selected) return "yellow"; + if (card.selectable) return "limegreen"; + if (card.exhausted) return "gray"; + return "black"; + }; - const cardStyle = { - backgroundColor: "black", - backgroundImage: `url(${s3CardImageURL(card)})`, - backgroundSize: "contain", - backgroundPosition: "center", - width: "10rem", - height: "7.18rem", - textAlign: "center", - color: "white", - display: "flex", - cursor: "pointer", - m: "0em", - position: "relative", // Needed for positioning the red box - border: `2px solid ${cardBorderColor(card)}`, - }; + const cardStyle = { + backgroundColor: "black", + backgroundImage: `url(${s3CardImageURL(card)})`, + backgroundSize: "contain", + backgroundPosition: "center", + width: "10rem", + height: "7.18rem", + textAlign: "center", + color: "white", + display: "flex", + cursor: "pointer", + m: "0em", + position: "relative", // Needed for positioning the red box + border: `2px solid ${cardBorderColor(card)}`, + }; + const cardStyleLobby = card ? { + backgroundColor: "transparent", + backgroundImage: `url(${s3CardImageURL(card)})`, + backgroundSize: "contain", + backgroundPosition: "center", + width: "9.5vw", + height: "13vh", + backgroundRepeat: "no-repeat", + textAlign: "center" as const, + color: "white", + display: "flex", + cursor: "pointer", + position: "relative" as const, + mb: "10px", + } : { + backgroundColor: "#00000040", + backgroundSize: "contain", + backgroundPosition: "center", + width: "9.5vw", + height: "13vh", + backgroundRepeat: "no-repeat", + textAlign: "center" as const, + color: "white", + display: "flex", + cursor: "pointer", + position: "relative" as const, + mb: "10px", + }; - const typographyStyle = { - fontFamily: "var(--font-barlow), sans-serif", - fontWeight: "400", - fontSize: "1.6em", - }; + const damageStyle = { + fontWeight: "600", + fontSize: "2em", + color: "hotpink", + }; - const damageStyle = { - fontWeight: "600", - fontSize: "2em", - color: "hotpink", - }; + //the title of the deck i believe + const redBoxStyle = { + position: "absolute", + bottom: "10px", + left: "50%", + transform: "translateX(-50%)", + backgroundColor: "red", + borderRadius: "4px", + p: "4px 8px", + }; - const titleTypographyStyle = { - fontFamily: "var(--font-barlow), sans-serif", - fontWeight: "600", - fontSize: "1.5em", - marginBottom: isLobbyView ? 0 : "0.5em", - textAlign: "left", - color: "white", - }; + const redBoxTypographyStyle = { + color: "white", + fontFamily: "var(--font-barlow), sans-serif", + fontWeight: "600", + fontSize: "1em", + }; - //the title of the deck i believe - const redBoxStyle = { - position: "absolute", - bottom: "10px", - left: "50%", - transform: "translateX(-50%)", - backgroundColor: "red", - borderRadius: "4px", - p: "4px 8px", - }; + const { sendGameMessage } = useGame(); - const redBoxTypographyStyle = { - color: "white", - fontFamily: "var(--font-barlow), sans-serif", - fontWeight: "600", - fontSize: "1em", - }; + return ( + + { + // Only allow clicking if not lobby view and the card is selectable + if (!disabled && card.selectable) { + sendGameMessage(["cardClicked", card.uuid]); + } + }} + > + {/* Only show card content if not in lobby view */} + {!isLobbyView && card && ( + + + + {card.damage} + + + + )} - const { sendGameMessage } = useGame(); - - return ( - - {/* Show title above the card if in lobby view and variant is leader */} - {variant === "leader" && isLobbyView && title && ( - - {title} - - )} - - {isLobbyView ? ( - - ) : ( - { - if (card.selectable) { - sendGameMessage(["cardClicked", card.uuid]); - } - }} - > - - - {card.damage} - - - - {/* Show title inside a red box at the bottom if not in lobby view and variant is leader */} - {variant === "leader" && !isLobbyView && title && ( - - - {title} - - - )} - - )} - - - - ); + {/* Show title inside a red box only if variant is leader and not lobby view */} + {variant === "leader" && !isLobbyView && title && ( + + + {title} + + + )} + + + ); }; -export default LeaderBaseCard; +export default LeaderBaseCard; \ No newline at end of file diff --git a/src/app/_components/_sharedcomponents/Chat/Chat.tsx b/src/app/_components/_sharedcomponents/Chat/Chat.tsx index 27bd69ed..6fa6a1b1 100644 --- a/src/app/_components/_sharedcomponents/Chat/Chat.tsx +++ b/src/app/_components/_sharedcomponents/Chat/Chat.tsx @@ -13,40 +13,28 @@ import { IChatProps } from "./ChatTypes"; const Chat: React.FC = ({ chatHistory, chatMessage, - playerRoll = null, - opponentRoll = null, setChatMessage, handleChatSubmit, }) => { - const determineFirstPlayer = () => { - if (playerRoll !== null && opponentRoll !== null) { - if (playerRoll > opponentRoll) { - return "Player"; - } else if (opponentRoll > playerRoll) { - return "Opponent"; - } else { - return "It's a tie. Roll again."; - } - } - return null; - }; //------------------------STYLES------------------------// const chatContainerStyle = { - mt: 2, backgroundColor: "#28282800", + height: "55vh", + overflowY: "auto", }; const titleStyle = { fontWeight: "bold", color: "#fff", + fontSize: "1.5em", }; const dividerStyle = { backgroundColor: "#fff", mt: ".5vh", - mb: "1vh", + mb: "0.5vh", }; const chatBoxStyle = { @@ -68,7 +56,6 @@ const Chat: React.FC = ({ p: "10px", mt: 2, }; - const textFieldStyle = { backgroundColor: "#28282800", color: "#fff", @@ -103,28 +90,14 @@ const Chat: React.FC = ({ )) ) : ( - {playerRoll !== null && opponentRoll !== null ? ( - <> - - Player rolled {playerRoll} and Opponent rolled{" "} - {opponentRoll}. - - - {determineFirstPlayer() === "It's a tie. Roll again." - ? "It's a tie. Roll again." - : `${determineFirstPlayer()} chooses who goes first.`} - - - ) : ( - <> - - Player 1 has connected. - - - Player 2 has connected. - - - )} + <> + + Player 1 has connected. + + + Player 2 has connected. + + )} diff --git a/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBase/LeaderBase.tsx b/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBase/LeaderBase.tsx deleted file mode 100644 index e253e1ab..00000000 --- a/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBase/LeaderBase.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import React from "react"; -import Grid from "@mui/material/Grid2"; -import LeaderBaseCard from "../../Cards/LeaderBaseCard/LeaderBaseCard"; -import { ILeaderBaseProps } from "../LeaderBaseBoardTypes"; -import { useGame } from "@/app/_contexts/Game.context"; -import { s3CardImageURL } from "@/app/_utils/s3Utils"; - -const LeaderBase: React.FC = ({ - player, - isLobbyView = false, - title, -}) => { - - const { gameState, connectedPlayer } = useGame(); - const playerLeader = gameState?.players[player].leader; - const playerBase = gameState?.players[player].base; - - const containerStyle = { - height: "100%", - width: "100%", - justifyContent: "center", - }; - - return ( - - {isLobbyView ? ( - <> - - - - ) : player === connectedPlayer ? ( - <> - - - - ) : ( - <> - - - - )} - - ); -}; - -export default LeaderBase; diff --git a/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBaseBoard.tsx b/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBaseBoard.tsx deleted file mode 100644 index 90e1b0e4..00000000 --- a/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBaseBoard.tsx +++ /dev/null @@ -1,51 +0,0 @@ -import React from "react"; -import Grid from "@mui/material/Grid2"; -import LeaderBase from "./LeaderBase/LeaderBase"; -import CardActionTray from "@/app/_components/Gameboard/_subcomponents/PlayerTray/CardActionTray"; -import { useGame } from "@/app/_contexts/Game.context"; -import { ILeaderBaseBoardProps } from "./LeaderBaseBoardTypes"; - - -const LeaderBaseBoard: React.FC = ({ - isLobbyView, -}) => { - const { connectedPlayer, getOpponent } = useGame(); - const titleOpponent = - connectedPlayer === "ThisIsTheWay" ? "Order66" : "ThisIsTheWay"; - //------------------------STYLES------------------------// - - const containerStyle = { - height: "100%", - width: "100%", - justifyContent: "space-between", - }; - - const rowStyle = { - flexGrow: 1, - width: "100%", - }; - - return ( - - {/* Opponent's row */} - - - - { isLobbyView ? null : } - {/* Player's row */} - - - - - ); -}; - -export default LeaderBaseBoard; diff --git a/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBaseBoardTypes.ts b/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBaseBoardTypes.ts deleted file mode 100644 index 2b3c55a1..00000000 --- a/src/app/_components/_sharedcomponents/LeaderBaseBoard/LeaderBaseBoardTypes.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface ILeaderBaseBoardProps { - isLobbyView?: boolean; -} - -export interface ILeaderBaseProps { - player: string; - isLobbyView?: boolean; - title?: string; -} diff --git a/src/app/_contexts/Game.context.tsx b/src/app/_contexts/Game.context.tsx index c5334bf9..967b243b 100644 --- a/src/app/_contexts/Game.context.tsx +++ b/src/app/_contexts/Game.context.tsx @@ -16,6 +16,8 @@ interface IGameContextType { sendGameMessage: (args: any[]) => void; getOpponent: (player: string) => string; connectedPlayer: string; + connectedDeck: any, + updateDeck: (args: any[]) => void; } const GameContext = createContext(undefined); @@ -24,7 +26,7 @@ export const GameProvider = ({ children }: { children: ReactNode }) => { const [gameState, setGameState] = useState(null); const [socket, setSocket] = useState(undefined); const [connectedPlayer, setConnectedPlayer] = useState(""); - + const [connectedDeck, setDeck] = useState(null); useEffect(() => { const urlParams = new URLSearchParams(window.location.search); @@ -45,6 +47,9 @@ export const GameProvider = ({ children }: { children: ReactNode }) => { setGameState(gameState); console.log("Game state received:", gameState); }); + newSocket.on("deckData", (deck:any) =>{ + setDeck(deck); + }); setSocket(newSocket); @@ -63,6 +68,11 @@ export const GameProvider = ({ children }: { children: ReactNode }) => { socket?.emit("game", ...args); }; + const updateDeck = (args: any[]) => { + console.log("move card message", args); + socket?.emit("updateDeck", ...args); + } + const getOpponent = (player: string) => { if (!gameState) return ""; const playerNames = Object.keys(gameState.players); @@ -76,7 +86,9 @@ export const GameProvider = ({ children }: { children: ReactNode }) => { sendGameMessage, sendMessage, connectedPlayer, - getOpponent + connectedDeck, + getOpponent, + updateDeck }} > {children} diff --git a/src/app/lobby/page.tsx b/src/app/lobby/page.tsx index d0161185..433ef8c8 100644 --- a/src/app/lobby/page.tsx +++ b/src/app/lobby/page.tsx @@ -1,10 +1,11 @@ "use client"; import React, { useState } from "react"; -import { Grid2 as Grid } from "@mui/material"; +import {Grid2 as Grid, Typography} from "@mui/material"; import { usePathname } from "next/navigation"; import Players from "../_components/Lobby/Players/Players"; import Deck from "../_components/Lobby/Deck/Deck"; import SetUp from "../_components/Lobby/SetUp/SetUp"; +import {s3ImageURL} from "@/app/_utils/s3Utils"; const Lobby = () => { @@ -27,29 +28,39 @@ const Lobby = () => { const containerStyle = { height: "100vh", overflow: "hidden", + backgroundImage: `url(${s3ImageURL("game/board-background-1.png")})`, + backgroundSize: "cover", + backgroundPosition: "center", }; const setUpGridStyle = { justifyContent: "center", - alignContent: "center", pl: "20px", - mb: "16.3em", + mt: "5px", }; const playersGridStyle = { justifyContent: "center", - alignContent: "center", + mt: "78px", }; const deckGridStyle = { justifyContent: "center", - alignContent: "center", pr: "20px", + mt: "78px", + }; + const disclaimer = { + position: "absolute", + bottom: 0, + width: "100%", + padding: "1rem", + textAlign: "center", + fontSize: "0.90rem", }; return ( - + { setChatMessage={setChatMessage} /> - + - + + + + Karabast is in no way affiliated with Disney or Fantasy Flight Games. + Star Wars characters, cards, logos, and art are property of Disney + and/or Fantasy Flight Games. + + ); };