From d8e9ac70ed6ef53d02e9e9e48bb67e64b471e013 Mon Sep 17 00:00:00 2001 From: Cosmos 612 Date: Wed, 13 Nov 2024 17:43:57 +0100 Subject: [PATCH 1/5] logger --- client/src/hooks/useGame.tsx | 7 ++++- client/src/hooks/useGrid.tsx | 4 ++- client/src/ui/components/Grid.tsx | 6 +++++ client/src/utils/logger.ts | 43 +++++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 client/src/utils/logger.ts diff --git a/client/src/hooks/useGame.tsx b/client/src/hooks/useGame.tsx index 56a91d29..274d1d40 100644 --- a/client/src/hooks/useGame.tsx +++ b/client/src/hooks/useGame.tsx @@ -1,9 +1,10 @@ import { useDojo } from "@/dojo/useDojo"; -import { useMemo } from "react"; +import { useEffect, useMemo } from "react"; import { getEntityIdFromKeys } from "@dojoengine/utils"; import { useComponentValue } from "@dojoengine/react"; import { Entity } from "@dojoengine/recs"; import useDeepMemo from "./useDeepMemo"; +import { consoleTSLog } from "@/utils/logger"; export const useGame = ({ gameId, @@ -30,5 +31,9 @@ export const useGame = ({ return component ? new GameClass(component) : null; }, [component]); + useEffect(() => { + consoleTSLog("danger", "Game grid changed", game?.blocks); + }, [game?.blocks]); + return { game, gameKey }; }; diff --git a/client/src/hooks/useGrid.tsx b/client/src/hooks/useGrid.tsx index d0987519..94889014 100644 --- a/client/src/hooks/useGrid.tsx +++ b/client/src/hooks/useGrid.tsx @@ -2,6 +2,7 @@ import { useEffect, useState, useRef } from "react"; import { useGame } from "@/hooks/useGame"; import { formatBigIntToBinaryArrayCustom } from "@/utils/gridUtils"; import useDeepMemo from "./useDeepMemo"; +import { consoleTSLog } from "@/utils/logger"; interface DebugData { blocksRaw: bigint; @@ -36,6 +37,7 @@ export const useGrid = ({ return; } if (game && memoizedBlocks.length > 0) { + consoleTSLog(memoizedBlocks, "Grid updated"); if (shouldLog) { const num = game.blocksRaw; const binaryString = num.toString(2); @@ -50,7 +52,7 @@ export const useGrid = ({ blocks: memoizedBlocks, }; - console.log("Grid updated:", debugData); + //console.log("Grid updated:", debugData); } // Mettre à jour `blocks` et `blocksRef` simultanément diff --git a/client/src/ui/components/Grid.tsx b/client/src/ui/components/Grid.tsx index 61948afa..c5f1101c 100644 --- a/client/src/ui/components/Grid.tsx +++ b/client/src/ui/components/Grid.tsx @@ -14,6 +14,7 @@ import { deepCompareBlocks, getBlocksSameRow, getBlocksSameWidth, + transformToGridFormat, } from "@/utils/gridUtils"; import { MoveType } from "@/enums/moveEnum"; import AnimatedText from "../elements/animatedText"; @@ -24,6 +25,7 @@ import ConfettiExplosion, { ConfettiExplosionRef } from "./ConfettiExplosion"; import { useMusicPlayer } from "@/contexts/hooks"; import "../../grid.css"; +import { consoleTSLog } from "@/utils/logger"; const { VITE_PUBLIC_DEPLOY_TYPE } = import.meta.env; @@ -112,6 +114,10 @@ const Grid: React.FC = ({ useEffect(() => { if (applyData) { if (deepCompareBlocks(saveGridStateblocks, initialData)) { + consoleTSLog( + "Grid state is the same, no need to apply data", + transformToGridFormat(saveGridStateblocks, gridWidth, gridHeight), + ); return; } if (moveTxAwaitDone) { diff --git a/client/src/utils/logger.ts b/client/src/utils/logger.ts new file mode 100644 index 00000000..e3e1dfb7 --- /dev/null +++ b/client/src/utils/logger.ts @@ -0,0 +1,43 @@ +type LogColor = "info" | "success" | "danger"; + +export function consoleTSLog(...args: any[]): void { + const now = new Date(); + const time = now.toTimeString().split(" ")[0]; + const milliseconds = now.getMilliseconds().toString().padStart(3, "0"); + + let color: LogColor | undefined; + let messageArgs: any[]; + + // Vérifier si le premier argument est une couleur + if ( + typeof args[0] === "string" && + ["info", "success", "danger"].includes(args[0]) + ) { + color = args[0] as LogColor; + messageArgs = args.slice(1); // Exclut la couleur des arguments du message + } else { + color = "info"; // Couleur par défaut + messageArgs = args; // Utilise tous les arguments comme message + } + + // Définir la couleur de fond selon le type de log + let backgroundColor; + switch (color) { + case "info": + backgroundColor = "blue"; + break; + case "success": + backgroundColor = "green"; + break; + case "danger": + backgroundColor = "red"; + break; + } + + // Afficher le message avec le timestamp stylisé + console.log( + `%c[${time}.${milliseconds}]`, + `font-weight: bold; background-color: ${backgroundColor}; color: white; padding: 2px 4px; border-radius: 3px;`, + ...messageArgs, + ); +} From 24128d94eb0ee06e6ef868acbe470b867a73eeee Mon Sep 17 00:00:00 2001 From: Cosmos 612 Date: Thu, 14 Nov 2024 10:57:35 +0100 Subject: [PATCH 2/5] logging + start exter --- client/src/hooks/useDragHandlers.tsx | 28 ++++++++++++++++++++++++++ client/src/hooks/useGame.tsx | 4 ---- client/src/hooks/useGrid.tsx | 3 +-- client/src/ui/components/GameBoard.tsx | 4 ++++ client/src/ui/components/Grid.tsx | 19 ++++++++--------- client/src/ui/screens/Home.tsx | 5 +++++ 6 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 client/src/hooks/useDragHandlers.tsx diff --git a/client/src/hooks/useDragHandlers.tsx b/client/src/hooks/useDragHandlers.tsx new file mode 100644 index 00000000..095930c0 --- /dev/null +++ b/client/src/hooks/useDragHandlers.tsx @@ -0,0 +1,28 @@ +import { MoveType } from "@/enums/moveEnum"; +import { useCallback } from "react"; + +const useDragHandlers = ( + handleDragMove: (clientX: number, moveType: MoveType) => void, +) => { + const handleMouseMove = useCallback( + (e: React.MouseEvent) => { + handleDragMove(e.clientX, MoveType.MOUSE); + }, + [handleDragMove], + ); + + const handleTouchMove = useCallback( + (e: React.TouchEvent) => { + const touch = e.touches[0]; + handleDragMove(touch.clientX, MoveType.TOUCH); + }, + [handleDragMove], + ); + + return { + handleMouseMove, + handleTouchMove, + }; +}; + +export default useDragHandlers; diff --git a/client/src/hooks/useGame.tsx b/client/src/hooks/useGame.tsx index 274d1d40..552b5f40 100644 --- a/client/src/hooks/useGame.tsx +++ b/client/src/hooks/useGame.tsx @@ -31,9 +31,5 @@ export const useGame = ({ return component ? new GameClass(component) : null; }, [component]); - useEffect(() => { - consoleTSLog("danger", "Game grid changed", game?.blocks); - }, [game?.blocks]); - return { game, gameKey }; }; diff --git a/client/src/hooks/useGrid.tsx b/client/src/hooks/useGrid.tsx index 94889014..42a5fba0 100644 --- a/client/src/hooks/useGrid.tsx +++ b/client/src/hooks/useGrid.tsx @@ -37,7 +37,6 @@ export const useGrid = ({ return; } if (game && memoizedBlocks.length > 0) { - consoleTSLog(memoizedBlocks, "Grid updated"); if (shouldLog) { const num = game.blocksRaw; const binaryString = num.toString(2); @@ -52,7 +51,7 @@ export const useGrid = ({ blocks: memoizedBlocks, }; - //console.log("Grid updated:", debugData); + console.log("Grid updated:", debugData); } // Mettre à jour `blocks` et `blocksRef` simultanément diff --git a/client/src/ui/components/GameBoard.tsx b/client/src/ui/components/GameBoard.tsx index 99c00c82..3bb0068d 100644 --- a/client/src/ui/components/GameBoard.tsx +++ b/client/src/ui/components/GameBoard.tsx @@ -4,6 +4,7 @@ import React, { useEffect, useMemo, useRef, + useLayoutEffect, } from "react"; import { Card } from "@/ui/elements/card"; import { useDojo } from "@/dojo/useDojo"; @@ -24,6 +25,7 @@ import { Game } from "@/dojo/game/models/game"; import useRank from "@/hooks/useRank"; import "../../grid.css"; +import { consoleTSLog } from "@/utils/logger"; interface GameBoardProps { initialGrid: number[][]; @@ -79,6 +81,7 @@ const GameBoard: React.FC = ({ setOptimisticScore(score); setOptimisticCombo(combo); setOptimisticMaxCombo(maxCombo); + consoleTSLog("info", "Initial grid changed in GameBoard"); // eslint-disable-next-line react-hooks/exhaustive-deps }, [initialGrid]); @@ -197,6 +200,7 @@ const GameBoard: React.FC = ({ }, [initialGrid]); const memoizedInitialData = useMemo(() => { + consoleTSLog("success", "Transforming data in gameboard"); return transformDataContractIntoBlock(initialGrid); }, [initialGrid]); diff --git a/client/src/ui/components/Grid.tsx b/client/src/ui/components/Grid.tsx index c5f1101c..0e46409c 100644 --- a/client/src/ui/components/Grid.tsx +++ b/client/src/ui/components/Grid.tsx @@ -1,4 +1,10 @@ -import { useCallback, useEffect, useRef, useState } from "react"; +import { + useCallback, + useEffect, + useLayoutEffect, + useRef, + useState, +} from "react"; import { Account } from "starknet"; import { useDojo } from "@/dojo/useDojo"; import BlockContainer from "./Block"; @@ -26,6 +32,7 @@ import { useMusicPlayer } from "@/contexts/hooks"; import "../../grid.css"; import { consoleTSLog } from "@/utils/logger"; +import useDragHandlers from "@/hooks/useDragHandlers"; const { VITE_PUBLIC_DEPLOY_TYPE } = import.meta.env; @@ -121,6 +128,7 @@ const Grid: React.FC = ({ return; } if (moveTxAwaitDone) { + consoleTSLog("success", "Applying data to grid"); setSaveGridStateblocks(initialData); setBlocks(initialData); setNextLine(nextLineData); @@ -255,14 +263,7 @@ const Grid: React.FC = ({ handleDragStart(touch.clientX, block); }; - const handleMouseMove = (e: React.MouseEvent) => { - handleDragMove(e.clientX, MoveType.MOUSE); - }; - - const handleTouchMove = (e: React.TouchEvent) => { - const touch = e.touches[0]; - handleDragMove(touch.clientX, MoveType.TOUCH); - }; + const { handleMouseMove, handleTouchMove } = useDragHandlers(handleDragMove); const endDrag = () => { if (!dragging) return; diff --git a/client/src/ui/screens/Home.tsx b/client/src/ui/screens/Home.tsx index 3decf0b3..b9005c89 100644 --- a/client/src/ui/screens/Home.tsx +++ b/client/src/ui/screens/Home.tsx @@ -40,6 +40,7 @@ import useViewport from "@/hooks/useViewport"; import { TweetPreview } from "../components/TweetPreview"; import { Schema } from "@dojoengine/recs"; import { useGrid } from "@/hooks/useGrid"; +import { consoleTSLog } from "@/utils/logger"; export const Home = () => { const { @@ -147,6 +148,10 @@ export const Home = () => { prevGameOverRef.current = game?.over; }, [game?.over]); + useEffect(() => { + consoleTSLog("danger", "=============== Grid is changing ==============="); + }, [grid]); + /*useEffect(() => { console.log("==================> Grid is changing"); }, [grid]);*/ From ce6ae1229adceb04babb2f2999b1bcc48304cdc8 Mon Sep 17 00:00:00 2001 From: Cosmos 612 Date: Thu, 14 Nov 2024 11:32:59 +0100 Subject: [PATCH 3/5] gridPhysics --- client/src/ui/components/Grid.tsx | 76 ++++--------------------------- client/src/utils/gridPhysics.ts | 61 +++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 68 deletions(-) create mode 100644 client/src/utils/gridPhysics.ts diff --git a/client/src/ui/components/Grid.tsx b/client/src/ui/components/Grid.tsx index 0e46409c..813e9433 100644 --- a/client/src/ui/components/Grid.tsx +++ b/client/src/ui/components/Grid.tsx @@ -1,10 +1,4 @@ -import { - useCallback, - useEffect, - useLayoutEffect, - useRef, - useState, -} from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; import { Account } from "starknet"; import { useDojo } from "@/dojo/useDojo"; import BlockContainer from "./Block"; @@ -33,6 +27,7 @@ import { useMusicPlayer } from "@/contexts/hooks"; import "../../grid.css"; import { consoleTSLog } from "@/utils/logger"; import useDragHandlers from "@/hooks/useDragHandlers"; +import { calculateFallDistance, isBlocked } from "@/utils/gridPhysics"; const { VITE_PUBLIC_DEPLOY_TYPE } = import.meta.env; @@ -359,69 +354,14 @@ const Grid: React.FC = ({ [account, isMoving, gridHeight, move], ); - const isBlocked = ( - initialX: number, - newX: number, - y: number, - width: number, - blocks: Block[], - blockId: number, - ) => { - const rowBlocks = blocks.filter( - (block) => block.y === y && block.id !== blockId, - ); - - if (newX > initialX) { - for (const block of rowBlocks) { - if (block.x >= initialX + width && block.x < newX + width) { - return true; - } - } - } else { - for (const block of rowBlocks) { - if (block.x + block.width > newX && block.x <= initialX) { - return true; - } - } - } - - return false; - }; - - const calculateFallDistance = useCallback( - (block: Block, blocks: Block[]) => { - let maxFall = gridHeight - block.y - 1; - for (let y = block.y + 1; y < gridHeight; y++) { - if (isCollision(block.x, y, block.width, blocks, block.id)) { - maxFall = y - block.y - 1; - break; - } - } - return maxFall; - }, - [gridHeight], - ); - - const isCollision = ( - x: number, - y: number, - width: number, - blocks: Block[], - blockId: number, - ) => { - return blocks.some( - (block) => - block.id !== blockId && - block.y === y && - x < block.x + block.width && - x + width > block.x, - ); - }; - const applyGravity = useCallback(() => { setBlocks((prevBlocks) => { const newBlocks = prevBlocks.map((block) => { - const fallDistance = calculateFallDistance(block, prevBlocks); + const fallDistance = calculateFallDistance( + block, + prevBlocks, + gridHeight, + ); if (fallDistance > 0) { return { ...block, y: block.y + 1 }; } @@ -437,7 +377,7 @@ const Grid: React.FC = ({ return newBlocks; }); - }, [calculateFallDistance]); + }, [gridHeight]); useEffect(() => { const interval = setInterval(() => { diff --git a/client/src/utils/gridPhysics.ts b/client/src/utils/gridPhysics.ts new file mode 100644 index 00000000..a3120004 --- /dev/null +++ b/client/src/utils/gridPhysics.ts @@ -0,0 +1,61 @@ +import { Block } from "@/types/types"; + +export const isBlocked = ( + initialX: number, + newX: number, + y: number, + width: number, + blocks: Block[], + blockId: number, +) => { + const rowBlocks = blocks.filter( + (block) => block.y === y && block.id !== blockId, + ); + + if (newX > initialX) { + for (const block of rowBlocks) { + if (block.x >= initialX + width && block.x < newX + width) { + return true; + } + } + } else { + for (const block of rowBlocks) { + if (block.x + block.width > newX && block.x <= initialX) { + return true; + } + } + } + + return false; +}; + +export const isCollision = ( + x: number, + y: number, + width: number, + blocks: Block[], + blockId: number, +) => { + return blocks.some( + (block) => + block.id !== blockId && + block.y === y && + x < block.x + block.width && + x + width > block.x, + ); +}; + +export const calculateFallDistance = ( + block: Block, + blocks: Block[], + gridHeight: number, +) => { + let maxFall = gridHeight - block.y - 1; + for (let y = block.y + 1; y < gridHeight; y++) { + if (isCollision(block.x, y, block.width, blocks, block.id)) { + maxFall = y - block.y - 1; + break; + } + } + return maxFall; +}; From 3d8f4377e1078e360e3ccaba0e483203287a9c18 Mon Sep 17 00:00:00 2001 From: Cosmos 612 Date: Thu, 14 Nov 2024 15:50:25 +0100 Subject: [PATCH 4/5] Motion --- client/src/hooks/useGame.tsx | 3 +- client/src/ui/components/BackgroundBoard.tsx | 20 +- client/src/ui/components/GameBoard.tsx | 12 +- client/src/ui/screens/Home.tsx | 296 +++++++++---------- 4 files changed, 158 insertions(+), 173 deletions(-) diff --git a/client/src/hooks/useGame.tsx b/client/src/hooks/useGame.tsx index 552b5f40..56a91d29 100644 --- a/client/src/hooks/useGame.tsx +++ b/client/src/hooks/useGame.tsx @@ -1,10 +1,9 @@ import { useDojo } from "@/dojo/useDojo"; -import { useEffect, useMemo } from "react"; +import { useMemo } from "react"; import { getEntityIdFromKeys } from "@dojoengine/utils"; import { useComponentValue } from "@dojoengine/react"; import { Entity } from "@dojoengine/recs"; import useDeepMemo from "./useDeepMemo"; -import { consoleTSLog } from "@/utils/logger"; export const useGame = ({ gameId, diff --git a/client/src/ui/components/BackgroundBoard.tsx b/client/src/ui/components/BackgroundBoard.tsx index 2983e698..b91cfcd9 100644 --- a/client/src/ui/components/BackgroundBoard.tsx +++ b/client/src/ui/components/BackgroundBoard.tsx @@ -1,8 +1,6 @@ -import { ReactNode } from "react"; import { motion, MotionProps } from "framer-motion"; interface BackgroundImageProps { - children: ReactNode; imageBackground: string; animate?: MotionProps["animate"]; initial?: MotionProps["initial"]; @@ -10,23 +8,19 @@ interface BackgroundImageProps { } const BackgroundBoard: React.FC = ({ - children, imageBackground, animate, initial, transition, }) => { return ( -
- - {children} -
+ ); }; diff --git a/client/src/ui/components/GameBoard.tsx b/client/src/ui/components/GameBoard.tsx index 3bb0068d..1bd39ea4 100644 --- a/client/src/ui/components/GameBoard.tsx +++ b/client/src/ui/components/GameBoard.tsx @@ -1,11 +1,4 @@ -import React, { - useState, - useCallback, - useEffect, - useMemo, - useRef, - useLayoutEffect, -} from "react"; +import React, { useState, useCallback, useEffect, useMemo } from "react"; import { Card } from "@/ui/elements/card"; import { useDojo } from "@/dojo/useDojo"; import { GameBonus } from "../containers/GameBonus"; @@ -195,10 +188,13 @@ const GameBoard: React.FC = ({ useEffect(() => { // Reset the isTxProcessing state and the bonus state when the grid changes // meaning the tx as been processed, and the client state updated + consoleTSLog("success", "Game board is trigger"); setBonus(BonusType.None); setBonusDescription(""); }, [initialGrid]); + consoleTSLog("info", "Rendering GameBoard component"); + const memoizedInitialData = useMemo(() => { consoleTSLog("success", "Transforming data in gameboard"); return transformDataContractIntoBlock(initialGrid); diff --git a/client/src/ui/screens/Home.tsx b/client/src/ui/screens/Home.tsx index b9005c89..e90bdefd 100644 --- a/client/src/ui/screens/Home.tsx +++ b/client/src/ui/screens/Home.tsx @@ -80,6 +80,8 @@ export const Home = () => { // State variables for modals const [isTournamentsOpen, setIsTournamentsOpen] = useState(false); + const gameIsOver = game?.isOver(); + const composeTweet = useCallback(() => { setLevel(player?.points ? Level.fromPoints(player?.points).value : ""); setScore(game?.score); @@ -87,7 +89,7 @@ export const Home = () => { }, [game?.score, player?.points]); useEffect(() => { - if (game?.over) { + if (gameIsOver) { if (gameGrid.current !== null) { toPng(gameGrid.current, { cacheBust: true }) .then((dataUrl) => { @@ -100,7 +102,7 @@ export const Home = () => { } setIsGameOn("isOver"); } - }, [composeTweet, game?.over]); + }, [composeTweet, gameIsOver]); useEffect(() => { // Check if game is defined and not over @@ -111,7 +113,7 @@ export const Home = () => { setIsGameOn("isOver"); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [game?.over]); + }, [gameIsOver]); const imageTotemTheme = theme === "dark" ? imgAssets.imageTotemDark : imgAssets.imageTotemLight; @@ -135,27 +137,23 @@ export const Home = () => { const [chestIsOpen, setChestIsOpen] = useState(false); const [isGameOverOpen, setIsGameOverOpen] = useState(false); - const prevGameOverRef = useRef(game?.over); + const prevGameOverRef = useRef(gameIsOver); useEffect(() => { if (prevGameOverRef.current !== undefined) { // Check if game.over transitioned from false to true - if (!prevGameOverRef.current && game?.over) { + if (!prevGameOverRef.current && gameIsOver) { setIsGameOverOpen(true); } } // Update the ref with the current value of game.over - prevGameOverRef.current = game?.over; - }, [game?.over]); + prevGameOverRef.current = gameIsOver; + }, [gameIsOver]); useEffect(() => { consoleTSLog("danger", "=============== Grid is changing ==============="); }, [grid]); - /*useEffect(() => { - console.log("==================> Grid is changing"); - }, [grid]);*/ - // Define render functions const renderDesktopView = () => ( <> @@ -246,7 +244,10 @@ export const Home = () => { /> {/* Main Content */} - +
{ repeatType: "reverse", ease: "easeInOut", }} - > -
-
- {!isSigning && } - {(!game || (!!game && isGameOn === "isOver")) && ( - <> - {isMdOrLarger - ? renderDesktopView() - : isTournamentsOpen - ? renderTournamentsView() - : renderMobileView()} - - )} - {game && ( - setIsGameOverOpen(false)} - game={game} - /> - )} - {!!game && isGameOn === "isOver" && !isTournamentsOpen && ( - <> -
-
-

Game Over

- -
-
- {game.score} - -
-
- {game.combo} - -
-
- {game.max_combo} - -
+ /> +
+
+ {!isSigning && } + {(!game || (!!game && isGameOn === "isOver")) && ( + <> + {isMdOrLarger + ? renderDesktopView() + : isTournamentsOpen + ? renderTournamentsView() + : renderMobileView()} + + )} + {game && ( + setIsGameOverOpen(false)} + game={game} + /> + )} + {!!game && isGameOn === "isOver" && !isTournamentsOpen && ( + <> +
+
+

Game Over

+ +
+
+ {game.score} + +
+
+ {game.combo} + +
+
+ {game.max_combo} +
- - {!isTournamentsOpen && ( - - - - - - - - Feedback - -
- -
-
-
- )} - - )} - {!!game && isGameOn === "isOn" && ( -
-
- -
- {isMdOrLarger && ( -
- -
- )}
- )} -
-
- - - {!animationDone && ( - <> - - + + {!isTournamentsOpen && ( + + + + + + + + Feedback + +
+ +
+
+
+ )} )} -
- - + {!!game && isGameOn === "isOn" && ( +
+
+ +
+ {isMdOrLarger && ( +
+ +
+ )} +
+ )} +
+
+ + + {!animationDone && ( + <> + + + + )} + +
); From 279b9babd2cbae372de5dbe04b9a8583459c2b8a Mon Sep 17 00:00:00 2001 From: Cosmos 612 Date: Thu, 14 Nov 2024 16:31:43 +0100 Subject: [PATCH 5/5] fix chevron --- client/src/ui/elements/pagination.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/client/src/ui/elements/pagination.tsx b/client/src/ui/elements/pagination.tsx index d516592c..420c4aec 100644 --- a/client/src/ui/elements/pagination.tsx +++ b/client/src/ui/elements/pagination.tsx @@ -64,6 +64,11 @@ const PaginationLink = ({ ); PaginationLink.displayName = "PaginationLink"; +const isMdOrLarger = () => { + if (typeof window === "undefined") return false; + return window.matchMedia("(min-width: 768px)").matches; +}; + const PaginationPrevious = ({ className, ...props @@ -75,7 +80,7 @@ const PaginationPrevious = ({ {...props} > - Previous + {!isMdOrLarger && Previous} ); PaginationPrevious.displayName = "PaginationPrevious"; @@ -90,7 +95,7 @@ const PaginationNext = ({ className={cn("gap-1 pr-2.5", className)} {...props} > - Next + {!isMdOrLarger && Next} );