"use client"; import Link from "next/link"; import { useEffect, useMemo, useState } from "react"; import { useRouter } from "next/navigation"; import { ArcadeImportModal } from "@/components/arcade/ArcadeImportModal"; import type { ArcadeAttemptSummary, ArcadePackSummary } from "@/types/arcade"; export function ConnectionsHub({ classId, classSlug, initialPacks, }: { classId: string; classSlug: string; initialPacks: ArcadePackSummary[]; }) { const router = useRouter(); const [selectedId, setSelectedId] = useState(initialPacks[0]?.id ?? ""); const [showImport, setShowImport] = useState(false); const [allowedMistakes, setAllowedMistakes] = useState(initialPacks[0]?.defaultAllowedMistakes ?? 4); const [oneAwayFeedback, setOneAwayFeedback] = useState(true); const [attempts, setAttempts] = useState([]); const [attemptsLoading, setAttemptsLoading] = useState(initialPacks.length > 0); const effectiveSelectedId = initialPacks.some((pack) => pack.id === selectedId) ? selectedId : initialPacks[0]?.id ?? ""; const selected = useMemo(() => initialPacks.find((pack) => pack.id === effectiveSelectedId) ?? null, [effectiveSelectedId, initialPacks]); useEffect(() => { if (!selected) return; fetch(`/api/arcade/packs/${selected.id}/attempts`) .then((response) => response.ok ? response.json() : []) .then(setAttempts) .finally(() => setAttemptsLoading(false)); }, [selected]); function selectPack(pack: ArcadePackSummary) { setSelectedId(pack.id); setAllowedMistakes(pack.defaultAllowedMistakes); setAttempts([]); setAttemptsLoading(true); } async function renamePack(pack: ArcadePackSummary) { const name = window.prompt("Rename Connections pack", pack.name)?.trim(); if (!name || name === pack.name) return; await fetch(`/api/arcade/packs/${pack.id}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ name }), }); router.refresh(); } async function deletePack(pack: ArcadePackSummary) { if (!window.confirm(`Delete “${pack.name}” and its attempt history?`)) return; await fetch(`/api/arcade/packs/${pack.id}`, { method: "DELETE" }); if (selectedId === pack.id) setSelectedId(""); router.refresh(); } const playHref = selected ? `/${classSlug}/arcade/connections/${selected.id}/play?mistakes=${allowedMistakes}&oneAway=${oneAwayFeedback ? "1" : "0"}` : "#"; return (
← Back to Arcade

The pattern room

Connections

Choose a pack, tune the mistake limit, and find the four hidden groups.

{initialPacks.length === 0 ? (
{["bg-amber-400", "bg-emerald-500", "bg-sky-500", "bg-violet-500"].map((color) => )}

Import your first board

Connections uses purpose-built packs with four groups of four terms.

) : (

Study packs

{initialPacks.map((pack) => { const active = pack.id === effectiveSelectedId; return (
); })}
)} {showImport && setShowImport(false)} onImported={() => { setShowImport(false); router.refresh(); }} />}
); }