Screen3Results.tsx 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import type { GameStats } from '@wordle/shared';
  2. interface Screen3ResultsProps {
  3. won: boolean;
  4. attemptCount: number;
  5. revealedWord: string | null;
  6. stats: GameStats;
  7. onPlayAgain?: () => void; // Story 1.3
  8. }
  9. function Histogram({ stats }: { stats: GameStats }) {
  10. if (stats.gamesPlayed === 0) return <p style={{ color: '#787c7e' }}>No games yet.</p>;
  11. const maxCount = Math.max(...stats.histogram, 1);
  12. return (
  13. <div style={{ maxWidth: '300px', margin: '0 auto' }}>
  14. {stats.histogram.map((count, idx) => {
  15. const label = idx < 6 ? `${idx + 1}` : 'X';
  16. const pct = (count / maxCount) * 100;
  17. return (
  18. <div key={idx} style={{ display: 'flex', alignItems: 'center', gap: '8px', marginBottom: '4px' }}>
  19. <span style={{ width: '20px', textAlign: 'right', fontWeight: 'bold', color: '#555' }}>{label}</span>
  20. <div style={{ flex: 1, height: '20px', backgroundColor: count > 0 ? '#6aaa64' : '#d3d6da', width: `${Math.max(pct, count > 0 ? 5 : 0)}%`, minWidth: count > 0 ? '12px' : '4px', borderRadius: '2px' }} />
  21. <span style={{ width: '24px', fontSize: '0.8rem', color: '#555' }}>{count}</span>
  22. </div>
  23. );
  24. })}
  25. </div>
  26. );
  27. }
  28. export function Screen3Results({ won, attemptCount, revealedWord, stats, onPlayAgain }: Screen3ResultsProps) {
  29. return (
  30. <div style={{ maxWidth: '400px', margin: '24px auto', padding: '16px', fontFamily: 'sans-serif', textAlign: 'center' }}>
  31. <h1 style={{ fontSize: '1.6rem', marginBottom: '12px' }}>{won ? '🎉 Congratulations!' : 'Better luck next time'}</h1>
  32. {won ? (
  33. <p style={{ fontSize: '1.1rem', marginBottom: '8px' }}>Solved in {attemptCount} {attemptCount === 1 ? 'attempt' : 'attempts'}</p>
  34. ) : (
  35. revealedWord && <p style={{ fontSize: '1.1rem', marginBottom: '8px' }}>The word was: <strong>{revealedWord.toUpperCase()}</strong></p>
  36. )}
  37. <div style={{ margin: '24px 0' }}>
  38. <h2 style={{ fontSize: '1.1rem', marginBottom: '12px' }}>Statistics</h2>
  39. <div style={{ display: 'flex', justifyContent: 'center', gap: '24px', marginBottom: '16px' }}>
  40. <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.gamesPlayed}</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>Played</div></div>
  41. <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.gamesPlayed > 0 ? Math.round((stats.wins / stats.gamesPlayed) * 100) : 0}%</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>Win Rate</div></div>
  42. <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.currentStreak}</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>Streak</div></div>
  43. <div><div style={{ fontSize: '1.4rem', fontWeight: 'bold' }}>{stats.maxStreak}</div><div style={{ fontSize: '0.75rem', color: '#787c7e' }}>Max Streak</div></div>
  44. </div>
  45. <Histogram stats={stats} />
  46. </div>
  47. {onPlayAgain && (
  48. <button
  49. onClick={onPlayAgain}
  50. style={{
  51. padding: '12px 48px',
  52. fontSize: '1.1rem',
  53. fontWeight: 'bold',
  54. backgroundColor: '#6aaa64',
  55. color: '#fff',
  56. border: 'none',
  57. borderRadius: '8px',
  58. cursor: 'pointer',
  59. }}
  60. >
  61. Play Again
  62. </button>
  63. )}
  64. </div>
  65. );
  66. }