feature: Split styles and JavaScript to separate files, rework layout

This commit is contained in:
Keith Solomon
2025-09-01 12:26:56 -05:00
parent da63141a1b
commit 2c1c6fcf01
4 changed files with 502 additions and 290 deletions

108
app.js Normal file
View File

@@ -0,0 +1,108 @@
async function api(action, value) {
const res = await fetch('game.php', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action, value })
});
if (!res.ok) throw new Error('Network error: ' + res.status);
return res.json();
}
function appendLog(lines) {
const log = document.getElementById('log');
const atBottom = Math.abs(log.scrollHeight - log.scrollTop - log.clientHeight) < 4;
for (const line of lines) {
const div = document.createElement('div');
div.textContent = line;
log.appendChild(div);
}
if (atBottom) log.scrollTop = log.scrollHeight;
}
function setState(state) {
if (!state) return;
const s = document.getElementById('state');
s.innerHTML = ''+`
<div>Day: <span class="mono">${state.day}</span></div>
<div>Hours Left Today: <span class="mono">${state.hours_left}</span></div>
<div>Meals Today: <span class="mono">${state.meals}</span></div>
<div>Earned Today: <span class="mono">${state.earned}</span></div>
<div>Total Earned: <span class="mono">${state.earned_total}</span></div>
<div>Debt: <span class="mono">${state.debt}</span></div>
<div>Interest: <span class="mono">${(state.interest * 100).toFixed(0)}%</span></div>
<div>Wage: <span class="mono">${state.wage}</span></div>
<div>Efficiency: <span class="mono">${state.eff}</span></div>
<div>Enhancements: <span class="mono">${state.mods}</span></div>
`;
const m = document.getElementById('miniState');
if (m) {
m.innerHTML = ''+`
<div class="kv"><span class="label">Day</span><span class="mono">${state.day}</span></div>
<div class="kv"><span class="label">Hours Left Today</span><span class="mono">${state.hours_left}</span></div>
<div class="kv"><span class="label">Debt</span><span class="mono">${state.debt}</span></div>
<div class="kv"><span class="label">Interest</span><span class="mono">${(state.interest*100).toFixed(0)}%</span></div>
<div class="kv"><span class="label">Wage</span><span class="mono">${state.wage}</span></div>
<div class="kv"><span class="label">Earned Today</span><span class="mono">${state.earned}</span></div>
<div class="kv"><span class="label">Total Earned</span><span class="mono">${state.earned_total}</span></div>
<div class="kv"><span class="label">Efficiency</span><span class="mono">${state.eff}</span></div>
<div class="kv"><span class="label">Mods</span><span class="mono">${state.mods}</span></div>
`;
}
}
function setGameOver(summary) {
if (!summary) return;
appendLog(['', 'GAME OVER', summary]);
for (const btn of document.querySelectorAll('button[data-action]')) btn.disabled = true;
}
async function doAction(action, value) {
try {
const data = await api(action, value);
if (data.messages) appendLog(data.messages);
if (data.state) setState(data.state);
if (data.game_over) setGameOver(data.final_summary || '');
return data;
} catch (e) {
appendLog(['Error: ' + e.message]);
}
}
async function onLoad() {
await doAction('start');
}
async function handleWork() {
const s = prompt('How many hours would you like to work?');
if (s == null) return;
const hours = parseInt(s, 10);
if (!Number.isFinite(hours)) return appendLog(['Invalid entry.']);
await doAction('work', hours);
}
async function handleSleep() {
const s = prompt('How many hours would you like to sleep?');
if (s == null) return;
const hours = parseInt(s, 10);
if (!Number.isFinite(hours)) return appendLog(['Invalid entry.']);
await doAction('sleep', hours);
}
async function handleEnhance() {
const resp = await doAction('enhance');
if (resp && resp.can_install) {
const ok = confirm('Install an enhancement?');
if (ok) await doAction('install_enhancement');
}
}
async function resetGame() {
// Clear log and re-enable action buttons
const log = document.getElementById('log');
log.innerHTML = '';
for (const btn of document.querySelectorAll('button[data-action]')) btn.disabled = false;
await doAction('reset');
await doAction('start');
}
window.addEventListener('DOMContentLoaded', onLoad);