diff --git a/scripts/build.js b/scripts/build.js index 8a74170..ca78784 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -17,6 +17,7 @@ const NAV_TEMPLATE = ` German Trainer Hex-a-Row SnapMark + Bridge Builder @@ -41,8 +42,7 @@ function processHtml(filePath, outPath) { // Inject new nav if (content.includes('
]*)>/i, ` -${NAV_TEMPLATE}`); + content = content.replace(/]*)>/i, `\n${NAV_TEMPLATE}`); } else { // Fallback if no body tag found (unlikely for valid HTML) content = NAV_TEMPLATE + content; @@ -53,7 +53,7 @@ ${NAV_TEMPLATE}`); } function buildLanding() { - const landingSrc = path.join(__dirname, '..', 'src', 'landing', 'index.html'); + const landingSrc = path.join(SRC_DIR, 'landing', 'index.html'); const landingDist = path.join(DIST_DIR, 'index.html'); if (fs.existsSync(landingSrc)) { processHtml(landingSrc, landingDist); @@ -65,14 +65,15 @@ function buildLanding() { function buildApps() { if (!fs.existsSync(APPS_DIR)) return; - const apps = fs.readdirSync(APPS_DIR); - + const apps = fs.readdirSync(APPS_DIR).filter(item => { + const itemPath = path.join(APPS_DIR, item); + return !item.startsWith('.') && fs.statSync(itemPath).isDirectory(); + }); + apps.forEach(app => { const appSrc = path.join(APPS_DIR, app); const appDist = path.join(DIST_DIR, app); - if (!fs.statSync(appSrc).isDirectory()) return; - fs.mkdirSync(appDist, { recursive: true }); // Check if it's a Vite app (has package.json and vite.config.ts) @@ -146,4 +147,4 @@ function main() { console.log("Build Complete!"); } -main(); +main(); \ No newline at end of file diff --git a/src/apps/bridge-builder-math/.gitignore b/src/apps/bridge-builder-math/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/src/apps/bridge-builder-math/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/src/apps/bridge-builder-math/App.tsx b/src/apps/bridge-builder-math/App.tsx new file mode 100644 index 0000000..0eb8cbe --- /dev/null +++ b/src/apps/bridge-builder-math/App.tsx @@ -0,0 +1,269 @@ +import React, { useState, useEffect, useRef, useCallback } from 'react'; +import { GameState, GameStatus, Problem } from './types'; +import { GAME_CONFIG } from './constants'; +import { generateProblem } from './services/mathEngine'; +import { GameScene } from './components/GameScene'; +import { ControlPanel } from './components/ControlPanel'; +import { Button } from './components/Button'; +import { TutorModal } from './components/TutorModal'; +import { Confetti } from './components/Confetti'; +import { Play, RotateCcw, BrainCircuit, Flame } from 'lucide-react'; + +const INITIAL_STATE: GameState = { + status: GameStatus.MENU, + score: 0, + level: 1, + speed: GAME_CONFIG.INITIAL_SPEED, + characterX: 50, + bridgeEndX: GAME_CONFIG.GAP_START, + lives: 1, + streak: 0, +}; + +const App: React.FC = () => { + const [gameState, setGameState] = useState+ Solve math problems to build the bridge before the engineer falls! +
+ +Final Score: {gameState.score}
+ +The problem was
+Thinking...
+{data.explanation}
+"{data.encouragement}"
+Could not load explanation.
+ )} + +The problem was
+Thinking...
+{data.explanation}
+"{data.encouragement}"
+Could not load explanation.
+ )} + +