diff --git a/app/[gameID]/page.tsx b/app/[gameID]/page.tsx
index 883d12c..c69c71e 100644
--- a/app/[gameID]/page.tsx
+++ b/app/[gameID]/page.tsx
@@ -6,6 +6,7 @@ import { socket } from '@/socket';
import Settings from '@/components/Settings';
import Card from '@/components/Card';
+import Notes from '@/components/Notes';
import NotFound from '@/components/NotFound';
import { cardMap, layout } from '@/constants/tarokka';
@@ -105,6 +106,7 @@ export default function GamePage() {
))}
+ {cards.every(({ flipped }) => flipped) && }
) : null;
}
diff --git a/components/Notes.tsx b/components/Notes.tsx
new file mode 100644
index 0000000..ee659a0
--- /dev/null
+++ b/components/Notes.tsx
@@ -0,0 +1,85 @@
+'use client';
+
+import { useMemo, useState } from 'react';
+import { ScrollText } from 'lucide-react';
+
+import CopyButton from '@/components/CopyButton';
+import Scrim from '@/components/Scrim';
+import getCardInfo from '@/tools/getCardInfo';
+import { cardMap, layout } from '@/constants/tarokka';
+
+import { GameUpdate } from '@/types';
+
+type NotesProps = {
+ gameData: GameUpdate;
+};
+
+export default function Notes({ gameData: { dmID, cards, settings } }: NotesProps) {
+ const isDM = !!dmID;
+
+ const [open, setOpen] = useState(false);
+
+ const gameDummy = {
+ dmID: '',
+ spectatorID: '',
+ cards: [],
+ settings: {
+ positionBack: false,
+ positionFront: false,
+ prophecy: false,
+ notes: false,
+ cardStyle: 'color',
+ },
+ };
+
+ const notes = useMemo(
+ () =>
+ Array.from({ length: 9 })
+ .map((_cell: unknown, index: number) => cards[cardMap[index]])
+ .map((card, index) =>
+ card ? getCardInfo(card, layout[cardMap[index]], isDM, settings) : null,
+ )
+ .map(
+ (_cell: unknown, index: number, cards) =>
+ cards[Object.keys(cardMap).find((key) => cardMap[key] === index) || 0],
+ )
+ .filter((truthy) => truthy),
+ [settings],
+ );
+
+ return isDM || settings.notes ? (
+
+ {!open && (
+
+ )}
+
+ {open && (
+
setOpen((prev) => !prev)}>
+
+
note!.join('\n')).join('\n\n')}
+ className="absolute top-2 right-2 p-2 bg-black/30 hover:bg-black/50 rounded-full text-gray-200 hover:text-white"
+ />
+
+ {notes.map((note, index) => (
+
+
+ {note!.map((blurb, index) => (
+
{blurb}
+ ))}
+
+ {index < notes.length - 1 &&
}
+
+ ))}
+
+
+
+ )}
+
+ ) : null;
+}
diff --git a/components/Scrim.tsx b/components/Scrim.tsx
new file mode 100644
index 0000000..435ad61
--- /dev/null
+++ b/components/Scrim.tsx
@@ -0,0 +1,26 @@
+'use client';
+
+type ScrimProps = {
+ children?: React.ReactNode;
+ onClick?: (event: React.MouseEvent) => void;
+ show?: boolean;
+ className?: string;
+};
+
+export default function Scrim({ children, onClick, show = true, className = '' }: ScrimProps) {
+ const handleClick = (event: React.MouseEvent) => {
+ if (event.target === event.currentTarget) {
+ onClick && onClick(event);
+ }
+ };
+ if (!show) return null;
+
+ return (
+
+ {children}
+
+ );
+}