From 6359784f3bc19e134d476ef59bc0c984d1ef61fe Mon Sep 17 00:00:00 2001 From: Gavin McDonald Date: Mon, 14 Apr 2025 17:28:02 -0400 Subject: [PATCH] buttons to copy DM/Spectator links --- app/[gameID]/page.tsx | 21 ++++++++++++++++----- components/CopyButton.tsx | 36 ++++++++++++++++++++++++++++++++++++ package-lock.json | 10 ++++++++++ package.json | 1 + 4 files changed, 63 insertions(+), 5 deletions(-) create mode 100644 components/CopyButton.tsx diff --git a/app/[gameID]/page.tsx b/app/[gameID]/page.tsx index 0634929..3f27da2 100644 --- a/app/[gameID]/page.tsx +++ b/app/[gameID]/page.tsx @@ -5,15 +5,20 @@ import { useParams } from 'next/navigation'; import { socket } from '@/socket'; import Card from '@/components/Card'; +import CopyButton from '@/components/CopyButton'; import { cardMap, layout } from '@/constants/tarokka'; -import type { GameUpdate, ClientUpdate, TarokkaGameCard } from '@/types'; +import type { GameUpdate, ClientUpdate } from '@/types'; export default function GamePage() { const { gameID: gameIDParam } = useParams(); const [gameID, setGameID] = useState(''); - const [cards, setCards] = useState([]); + const [{ dmID, spectatorID, cards }, setGameData] = useState({ + dmID: '', + spectatorID: '', + cards: [], + }); useEffect(() => { if (gameIDParam) { @@ -27,12 +32,12 @@ export default function GamePage() { socket.on('init', (data: GameUpdate) => { console.log('init', data); - setCards(data.cards); + setGameData(data); }); socket.on('card-flipped', (data: GameUpdate) => { console.log('>>>', data); - setCards(data.cards); + setGameData(data); }); } @@ -58,8 +63,14 @@ export default function GamePage() { // high deck cards: bottom and center const arrangeCards = (_cell: any, index: number) => cards[cardMap[index]]; - return cards.length ? ( + return cards ? (
+
+ {dmID && } + {spectatorID && ( + + )} +
{Array.from({ length: 9 }) .map(arrangeCards) diff --git a/components/CopyButton.tsx b/components/CopyButton.tsx new file mode 100644 index 0000000..f119bda --- /dev/null +++ b/components/CopyButton.tsx @@ -0,0 +1,36 @@ +'use client'; + +import { useState } from 'react'; +import { Copy as CopyIcon } from 'lucide-react'; + +type CopyButtonProps = { + title: string; + copy: string; +}; + +export default function CopyButton({ title, copy }: CopyButtonProps) { + const [copied, setCopied] = useState(false); + + const handleCopy = async () => { + try { + await navigator.clipboard.writeText(copy); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + } catch (err) { + console.error('Failed to copy!', err); + } + }; + + return ( + + ); +} diff --git a/package-lock.json b/package-lock.json index 42361a9..92c27a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,6 +9,7 @@ "version": "0.1.0", "dependencies": { "cross-env": "^7.0.3", + "lucide-react": "^0.488.0", "next": "latest", "react": "^19.1.0", "react-dom": "^19.1.0", @@ -4575,6 +4576,15 @@ "loose-envify": "cli.js" } }, + "node_modules/lucide-react": { + "version": "0.488.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.488.0.tgz", + "integrity": "sha512-ronlL0MyKut4CEzBY/ai2ZpKPxyWO4jUqdAkm2GNK5Zn3Rj+swDz+3lvyAUXN0PNqPKIX6XM9Xadwz/skLs/pQ==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", diff --git a/package.json b/package.json index 9896e7b..be77211 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ }, "dependencies": { "cross-env": "^7.0.3", + "lucide-react": "^0.488.0", "next": "latest", "react": "^19.1.0", "react-dom": "^19.1.0",