TypeScript · 3234 bytes Raw Blame History
1 import React from 'react';
2 import Image from 'next/image';
3 import TimerDisplay from './TimerDisplay';
4 import { MoleDirection } from '@/lib/api';
5
6 interface GameStatusProps {
7 // Timer props
8 gameTreeId: number | null;
9 sessionId: number | null;
10 onTimerExpire: () => Promise<void>;
11
12 // Score props
13 score: number;
14 molesKilled: number;
15
16 // Direction indicator props
17 moleDirection: MoleDirection | null;
18 }
19
20 const GameStatus: React.FC<GameStatusProps> = ({
21 gameTreeId,
22 sessionId,
23 onTimerExpire,
24 score,
25 molesKilled,
26 moleDirection,
27 }) => {
28 // Get position for mole direction indicator
29 const getMoleIndicatorPosition = (direction: string) => {
30 const positions: Record<string, string> = {
31 'up': 'top-1/2 left-1/2 -translate-x-1/2 -translate-y-full -mt-8',
32 'down': 'bottom-20 left-1/2 -translate-x-1/2',
33 'left': 'top-1/2 left-8 -translate-y-1/2',
34 'right': 'top-1/2 right-8 -translate-y-1/2',
35 'up-left': 'top-20 left-8',
36 'up-right': 'top-20 right-8',
37 'down-left': 'bottom-20 left-8',
38 'down-right': 'bottom-20 right-8',
39 };
40 return positions[direction] || positions['up'];
41 };
42
43 // Get rotation for arrow based on angle
44 const getArrowRotation = (angle: number) => {
45 return `rotate(${angle}deg)`;
46 };
47
48 return (
49 <>
50 {/* Mole Direction Indicator */}
51 {moleDirection && (
52 <div
53 className={`absolute ${getMoleIndicatorPosition(moleDirection.direction)} z-40 animate-pulse`}
54 style={{
55 animation: 'pulse 2s ease-in-out infinite, fadeIn 0.5s ease-out'
56 }}
57 >
58 <div className="bg-red-600/90 backdrop-blur-sm border-2 border-red-400 rounded-lg p-3 shadow-2xl flex items-center gap-2">
59 <Image
60 src="/mole.svg"
61 alt="Mole"
62 width={32}
63 height={32}
64 className="w-8 h-8"
65 />
66 <div
67 className="text-white text-2xl"
68 style={{ transform: getArrowRotation(moleDirection.angle) }}
69 >
70
71 </div>
72 </div>
73 </div>
74 )}
75
76 {/* Score and Timer Display - Top Right */}
77 <div className="absolute top-4 right-4 flex flex-col gap-3 z-30">
78 {/* Timer */}
79 <TimerDisplay
80 gameTreeId={gameTreeId}
81 sessionId={sessionId}
82 onTimerExpire={onTimerExpire}
83 />
84
85 {/* Score */}
86 {molesKilled > 0 && (
87 <div className="bg-black/80 backdrop-blur-sm border border-green-500 rounded-lg p-3 shadow-2xl">
88 <div className="text-green-400 font-terminal text-sm">
89 <div>Score: {score}</div>
90 <div>Moles: {molesKilled}</div>
91 </div>
92 </div>
93 )}
94 </div>
95
96 {/* Custom styles for animations */}
97 <style jsx>{`
98 @keyframes fadeIn {
99 from { opacity: 0; transform: scale(0.8); }
100 to { opacity: 1; transform: scale(1); }
101 }
102 @keyframes pulse {
103 0%, 100% { opacity: 0.9; transform: scale(1); }
104 50% { opacity: 1; transform: scale(1.05); }
105 }
106 `}</style>
107 </>
108 );
109 };
110
111 export default GameStatus;