diff --git a/App.tsx b/App.tsx index 94495fb..5f78901 100644 --- a/App.tsx +++ b/App.tsx @@ -1,9 +1,11 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState, useEffect, Suspense } from 'react'; import { GameProvider } from './context/GameContext'; -import { HostView } from './components/HostView'; -import { PlayerView } from './components/PlayerView'; -import { SpectatorView } from './components/SpectatorView'; -import { Monitor, Smartphone, LayoutDashboard } from 'lucide-react'; +import { Monitor, Smartphone, LayoutDashboard, Loader2 } from 'lucide-react'; + +// Lazy load components to reduce initial bundle size +const HostView = React.lazy(() => import('./components/HostView').then(module => ({ default: module.HostView }))); +const PlayerView = React.lazy(() => import('./components/PlayerView').then(module => ({ default: module.PlayerView }))); +const SpectatorView = React.lazy(() => import('./components/SpectatorView').then(module => ({ default: module.SpectatorView }))); const App: React.FC = () => { const [view, setView] = useState<'HOST' | 'PLAYER' | 'SPECTATOR'>('SPECTATOR'); @@ -70,7 +72,14 @@ const App: React.FC = () => { {/* Main Content Area */}
- {renderView()} + + +

Loading Quiz Module...

+
+ }> + {renderView()} + diff --git a/components/SpectatorView.tsx b/components/SpectatorView.tsx index a4d0814..46f6da4 100644 --- a/components/SpectatorView.tsx +++ b/components/SpectatorView.tsx @@ -145,15 +145,17 @@ export const SpectatorView: React.FC = () => { // Top 5 Players const topPlayers = [...players].sort((a,b) => b.score - a.score).slice(0, 5); - // Fastest Buzzer Calculation - let fastestPlayer: Player | null = null; - let fastestTime = Infinity; - players.forEach(p => { - if (p.stats.bestReactionTime && p.stats.bestReactionTime < fastestTime) { - fastestTime = p.stats.bestReactionTime; - fastestPlayer = p; + // Fastest Buzzer Calculation using reduce with explicit generic type + const fastestPlayer = players.reduce((best, p) => { + const pTime = p.stats.bestReactionTime; + if (!pTime) return best; + if (!best || !best.stats.bestReactionTime || pTime < best.stats.bestReactionTime) { + return p; } - }); + return best; + }, null); + + const fastestTime = fastestPlayer?.stats.bestReactionTime ?? Infinity; return (
@@ -203,7 +205,7 @@ export const SpectatorView: React.FC = () => {
Fastest Finger
-
{(fastestPlayer as Player)?.name || '-'}
+
{fastestPlayer ? fastestPlayer.name : '-'}
diff --git a/index.html b/index.html index 39af5b8..67e3fb5 100644 --- a/index.html +++ b/index.html @@ -37,7 +37,7 @@ overscroll-behavior: none; } -
- + \ No newline at end of file diff --git a/package.json b/package.json index 6858eaf..e3a1565 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "react-dom": "^19.2.4", "@google/genai": "^1.38.0", "lucide-react": "^0.563.0", - "recharts": "^3.7.0" + "recharts": "^3.7.0", + "vite": "^7.3.1", + "@vitejs/plugin-react": "^5.1.2" }, "devDependencies": { "@types/node": "^22.14.0", diff --git a/vite.config.ts b/vite.config.ts index ee5fb8d..8b9bfd6 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,23 +1,12 @@ -import path from 'path'; -import { defineConfig, loadEnv } from 'vite'; +import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; -export default defineConfig(({ mode }) => { - const env = loadEnv(mode, '.', ''); - return { - server: { - port: 3000, - host: '0.0.0.0', - }, - plugins: [react()], - define: { - 'process.env.API_KEY': JSON.stringify(env.GEMINI_API_KEY), - 'process.env.GEMINI_API_KEY': JSON.stringify(env.GEMINI_API_KEY) - }, - resolve: { - alias: { - '@': path.resolve(__dirname, '.'), - } - } - }; -}); +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react()], + base: './', // Ensures assets are loaded relatively (e.g., "assets/script.js" instead of "/assets/script.js") + build: { + outDir: 'dist', + emptyOutDir: true, + }, +}); \ No newline at end of file