diff --git a/App.tsx b/App.tsx index cbfe1bf..f1cb188 100644 --- a/App.tsx +++ b/App.tsx @@ -55,8 +55,7 @@ function App() { currentCorrectShape, selectedOption, currentPlayerScore, - currentStreak, - currentPlayerId + currentStreak } = useGame(); const currentQ = quiz?.questions[currentQuestionIndex]; @@ -91,7 +90,7 @@ function App() { {gameState === 'LOBBY' ? ( ) : null} diff --git a/components/GameScreen.tsx b/components/GameScreen.tsx index 111e7d8..dff3178 100644 --- a/components/GameScreen.tsx +++ b/components/GameScreen.tsx @@ -31,7 +31,7 @@ export const GameScreen: React.FC = ({ // Timer styling logic const isUrgent = timeLeft < 5 && timeLeft > 0; const timerBorderColor = isUrgent ? 'border-red-500' : 'border-white'; - const timerTextColor = isUrgent ? 'text-red-500' : 'text-theme-primary'; + const timerTextColor = isUrgent ? 'text-red-500' : 'text-[#46178f]'; const timerAnimation = isUrgent ? 'animate-ping' : ''; return ( @@ -123,7 +123,7 @@ export const GameScreen: React.FC = ({ {isClient && hasAnswered && ( = ({ onGenerate, onCreateManual, on className="bg-white text-gray-900 p-8 rounded-[2rem] shadow-[0_10px_0_rgba(0,0,0,0.1)] max-w-md w-full border-4 border-white/50" >
-
+
-

Kaboot

+

OpenHoot

The AI Quiz Party

@@ -65,7 +65,7 @@ export const Landing: React.FC = ({ onGenerate, onCreateManual, on placeholder="Topic (e.g. 'Space')" value={topic} onChange={(e) => setTopic(e.target.value)} - className="w-full p-4 text-xl font-bold border-2 border-gray-200 rounded-2xl focus:border-theme-primary focus:ring-4 focus:ring-theme-primary/20 outline-none transition-all placeholder:font-medium text-center" + className="w-full p-4 text-xl font-bold border-2 border-gray-200 rounded-2xl focus:border-[#46178f] focus:ring-4 focus:ring-[#46178f]/20 outline-none transition-all placeholder:font-medium text-center" disabled={isLoading} /> @@ -97,14 +97,14 @@ export const Landing: React.FC = ({ onGenerate, onCreateManual, on placeholder="Game PIN" value={pin} onChange={(e) => setPin(e.target.value)} - className="w-full p-4 text-xl font-bold border-2 border-gray-200 rounded-2xl focus:border-theme-primary focus:ring-4 focus:ring-theme-primary/20 outline-none text-center" + className="w-full p-4 text-xl font-bold border-2 border-gray-200 rounded-2xl focus:border-[#46178f] focus:ring-4 focus:ring-[#46178f]/20 outline-none text-center" /> setName(e.target.value)} - className="w-full p-4 text-xl font-bold border-2 border-gray-200 rounded-2xl focus:border-theme-primary focus:ring-4 focus:ring-theme-primary/20 outline-none text-center" + className="w-full p-4 text-xl font-bold border-2 border-gray-200 rounded-2xl focus:border-[#46178f] focus:ring-4 focus:ring-[#46178f]/20 outline-none text-center" /> @@ -89,7 +89,7 @@ export const Lobby: React.FC = ({ quizTitle, players, gamePin, role, initial={{ scale: 0.5 }} animate={{ scale: 1 }} transition={{ type: 'spring', bounce: 0.6 }} - className="bg-white text-theme-primary p-8 rounded-[2rem] shadow-[0_10px_0_rgba(0,0,0,0.1)] mb-8" + className="bg-white text-[#46178f] p-8 rounded-[2rem] shadow-[0_10px_0_rgba(0,0,0,0.1)] mb-8" > diff --git a/components/Podium.tsx b/components/Podium.tsx index e1d4bd1..3f661f2 100644 --- a/components/Podium.tsx +++ b/components/Podium.tsx @@ -88,7 +88,7 @@ export const Podium: React.FC = ({ players, onRestart }) => { diff --git a/components/QuizCreator.tsx b/components/QuizCreator.tsx index 726e527..3018663 100644 --- a/components/QuizCreator.tsx +++ b/components/QuizCreator.tsx @@ -59,7 +59,7 @@ export const QuizCreator: React.FC = ({ onFinalize, onCancel } return (
-
+

Create Quiz

Build your masterpiece

@@ -83,7 +83,7 @@ export const QuizCreator: React.FC = ({ onFinalize, onCancel } type="text" value={title} onChange={(e) => setTitle(e.target.value)} - className="w-full p-4 border-4 border-gray-200 rounded-2xl text-2xl font-bold focus:border-theme-primary outline-none transition-colors" + className="w-full p-4 border-4 border-gray-200 rounded-2xl text-2xl font-bold focus:border-[#46178f] outline-none transition-colors" placeholder="e.g., The Ultimate Trivia" />
@@ -92,7 +92,7 @@ export const QuizCreator: React.FC = ({ onFinalize, onCancel } {questions.map((q, idx) => (
- + {idx + 1} {q.text} @@ -149,19 +149,17 @@ export const QuizCreator: React.FC = ({ onFinalize, onCancel } placeholder={`Option ${idx + 1}`} />
-
- { - const newReasons = [...reasons]; - newReasons[idx] = e.target.value; - setReasons(newReasons); - }} - className="w-full p-2 text-sm outline-none text-gray-500 bg-gray-50 rounded-lg placeholder:text-gray-400" - placeholder={isSelected ? "Why is this correct? (optional)" : "Why is this wrong? (optional)"} - /> -
+ { + const newReasons = [...reasons]; + newReasons[idx] = e.target.value; + setReasons(newReasons); + }} + className="w-full p-2 ml-12 text-sm outline-none text-gray-500 bg-gray-50 rounded-lg placeholder:text-gray-400" + placeholder={isSelected ? "Why is this correct? (optional)" : "Why is this wrong? (optional)"} + />
) })} diff --git a/components/Scoreboard.tsx b/components/Scoreboard.tsx index 3833449..c94747c 100644 --- a/components/Scoreboard.tsx +++ b/components/Scoreboard.tsx @@ -8,15 +8,10 @@ interface ScoreboardProps { players: Player[]; onNext: () => void; isHost: boolean; - currentPlayerId: string | null; } -export const Scoreboard: React.FC = ({ players, onNext, isHost, currentPlayerId }) => { - const playersWithDisplayName = players.map(p => ({ - ...p, - displayName: p.id === currentPlayerId ? `${p.name} (You)` : p.name - })); - const sortedPlayers = [...playersWithDisplayName].sort((a, b) => b.score - a.score).slice(0, 5); +export const Scoreboard: React.FC = ({ players, onNext, isHost }) => { + const sortedPlayers = [...players].sort((a, b) => b.score - a.score).slice(0, 5); return (
@@ -34,7 +29,7 @@ export const Scoreboard: React.FC = ({ players, onNext, isHost, = ({ players, onNext, isHost, {sortedPlayers.map((entry, index) => ( ))} @@ -52,7 +47,7 @@ export const Scoreboard: React.FC = ({ players, onNext, isHost, dataKey="score" position="right" offset={15} - style={{ fontSize: '24px', fontWeight: '900', fill: 'var(--theme-primary)', fontFamily: 'Fredoka' }} + style={{ fontSize: '24px', fontWeight: '900', fill: '#46178f', fontFamily: 'Fredoka' }} /> @@ -63,7 +58,7 @@ export const Scoreboard: React.FC = ({ players, onNext, isHost, {isHost ? ( diff --git a/constants.ts b/constants.ts index ea4f964..173b9b7 100644 --- a/constants.ts +++ b/constants.ts @@ -5,8 +5,8 @@ export const COLORS = { blue: 'bg-blue-600', yellow: 'bg-yellow-600', green: 'bg-green-600', - purple: 'bg-theme-primary', - purpleLight: 'bg-theme-primary/70', + purple: 'bg-[#46178f]', + purpleLight: 'bg-[#864cbf]', }; export const SHAPES = { @@ -23,18 +23,3 @@ export const BOT_NAMES = [ export const QUESTION_TIME = 20; // seconds export const POINTS_PER_QUESTION = 1000; - -export const PLAYER_COLORS = [ - '#2563eb', - '#e21b3c', - '#26890c', - '#ffa602', - '#d89e00', - '#0aa3a3', - '#b8008a', - '#6a4c93', - '#ff6b6b', - '#4ecdc4', - '#45b7d1', - '#8b5cf6', -]; diff --git a/hooks/useGame.ts b/hooks/useGame.ts index 2b9b6ac..6dca234 100644 --- a/hooks/useGame.ts +++ b/hooks/useGame.ts @@ -1,7 +1,7 @@ import { useState, useEffect, useRef, useCallback } from 'react'; import { Quiz, Player, GameState, GameRole, NetworkMessage, AnswerOption, Question } from '../types'; import { generateQuiz } from '../services/geminiService'; -import { POINTS_PER_QUESTION, QUESTION_TIME, PLAYER_COLORS } from '../constants'; +import { POINTS_PER_QUESTION, QUESTION_TIME } from '../constants'; import { Peer, DataConnection } from 'peerjs'; export const useGame = () => { @@ -19,8 +19,6 @@ export const useGame = () => { const [selectedOption, setSelectedOption] = useState(null); const [currentPlayerScore, setCurrentPlayerScore] = useState(0); const [currentStreak, setCurrentStreak] = useState(0); - const [currentPlayerId, setCurrentPlayerId] = useState(null); - const [currentPlayerName, setCurrentPlayerName] = useState(null); const timerRef = useRef | null>(null); const peerRef = useRef(null); @@ -73,23 +71,20 @@ export const useGame = () => { const pin = generateGamePin(); setGamePin(pin); - const peer = new Peer(`kaboot-${pin}`); + const peer = new Peer(`openhoot-${pin}`); peerRef.current = peer; peer.on('open', (id) => { const hostPlayer: Player = { id: 'host', - name: 'Host', + name: 'Host (You)', score: 0, streak: 0, lastAnswerCorrect: null, isBot: false, - avatarSeed: Math.random(), - color: PLAYER_COLORS[0] + avatarSeed: Math.random() }; setPlayers([hostPlayer]); - setCurrentPlayerId('host'); - setCurrentPlayerName('Host'); setGameState('LOBBY'); }); @@ -108,23 +103,21 @@ export const useGame = () => { const handleHostData = (conn: DataConnection, data: NetworkMessage) => { if (data.type === 'JOIN') { + const newPlayer: Player = { + id: conn.peer, + name: data.payload.name, + score: 0, + streak: 0, + lastAnswerCorrect: null, + isBot: false, + avatarSeed: Math.random() + }; setPlayers(prev => { - if (prev.find(p => p.id === conn.peer)) return prev; - const colorIndex = prev.length % PLAYER_COLORS.length; - const newPlayer: Player = { - id: conn.peer, - name: data.payload.name, - score: 0, - streak: 0, - lastAnswerCorrect: null, - isBot: false, - avatarSeed: Math.random(), - color: PLAYER_COLORS[colorIndex] - }; + if (prev.find(p => p.id === newPlayer.id)) return prev; return [...prev, newPlayer]; }); connectionsRef.current.set(conn.peer, conn); - conn.send({ type: 'WELCOME', payload: { playerId: conn.peer, quizTitle: 'Kaboot', players: [] } }); + conn.send({ type: 'WELCOME', payload: { playerId: conn.peer, quizTitle: 'OpenHoot', players: [] } }); } if (data.type === 'ANSWER') { @@ -254,13 +247,11 @@ export const useGame = () => { setRole('CLIENT'); setError(null); setGamePin(pin); - setCurrentPlayerName(name); const peer = new Peer(); peerRef.current = peer; - peer.on('open', (id) => { - setCurrentPlayerId(id); - const conn = peer.connect(`kaboot-${pin}`); + peer.on('open', () => { + const conn = peer.connect(`openhoot-${pin}`); hostConnectionRef.current = conn; conn.on('open', () => { conn.send({ type: 'JOIN', payload: { name } }); @@ -378,7 +369,7 @@ export const useGame = () => { }, []); return { - role, gameState, quiz, players, currentQuestionIndex, timeLeft, error, gamePin, hasAnswered, lastPointsEarned, currentCorrectShape, selectedOption, currentPlayerScore, currentStreak, currentPlayerId, + role, gameState, quiz, players, currentQuestionIndex, timeLeft, error, gamePin, hasAnswered, lastPointsEarned, currentCorrectShape, selectedOption, currentPlayerScore, currentStreak, startQuizGen, startManualCreation, finalizeManualQuiz, joinGame, startGame: startHostGame, handleAnswer, nextQuestion }; }; \ No newline at end of file diff --git a/index.html b/index.html index eba06a2..18e90f6 100644 --- a/index.html +++ b/index.html @@ -3,35 +3,14 @@ - Kaboot + OpenHoot -