Button disabled untill valid value entered
This commit is contained in:
parent
68737da735
commit
a1984033bb
1 changed files with 19 additions and 5 deletions
24
index.php
24
index.php
|
|
@ -210,7 +210,7 @@ function event_class(?string $type): string {
|
|||
<link rel="apple-touch-icon" href="/favicon.svg">
|
||||
<style>
|
||||
:root{color-scheme:dark;--bg:#0b0b0b;--card:#1b1b1b;--field:#101010;--line:#333;--text:#f2f2f2;--muted:#aaa;--green:#2f8f3a;--blue:#2d6cdf;--orange:#d9822b}
|
||||
*{box-sizing:border-box}body{font-family:system-ui,-apple-system,Segoe UI,sans-serif;margin:0;background:linear-gradient(rgba(11,11,11,.82),rgba(11,11,11,.92)),url('/img/fjr.jpg') center top/cover fixed no-repeat,var(--bg);color:var(--text);font-size:16px;-webkit-text-size-adjust:100%}.wrap{max-width:850px;margin:auto;padding:14px;padding-bottom:34px}h1{font-size:26px;margin:4px 0 12px}.topbar{display:flex;align-items:center;gap:12px}.logo{width:64px;height:64px;object-fit:contain;border-radius:0;background:transparent;padding:0;border:0;box-shadow:none}h2{font-size:20px;margin:0 0 12px}.card{background:rgba(27,27,27,.88);backdrop-filter:blur(3px);border:1px solid var(--line);border-radius:18px;padding:16px;margin:12px 0;box-shadow:0 8px 24px #0004}label{display:block;margin-top:14px;margin-bottom:6px;color:#d0d0d0;font-weight:650}input,select,textarea,button{width:100%;font:inherit;font-size:18px;padding:15px 14px;border-radius:14px;border:1px solid #444;background:var(--field);color:var(--text)}select{min-height:54px}textarea{resize:vertical}button{background:var(--green);border:0;margin-top:16px;font-weight:800;min-height:56px;touch-action:manipulation}.bikePhoto{width:100%;max-height:330px;object-fit:cover;border-radius:18px;border:1px solid var(--line);box-shadow:0 8px 24px #0006;margin:0 0 12px}.hero{text-decoration:none;color:inherit;display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:10px;align-items:stretch}.heroBox{background:rgba(16,16,16,.84);border:1px solid #2a2a2a;border-radius:14px;padding:13px}.heroBox.main{border-color:#3b5f45}.icon{font-size:22px;margin-right:6px}.grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}.stat{background:rgba(16,16,16,.84);border:1px solid #2a2a2a;border-radius:14px;padding:13px;min-height:112px}.big{font-size:30px;line-height:1.05;font-weight:850}.ok{background:#17351a;border-color:var(--green)}.muted{color:var(--muted);font-size:13px}.historyList{display:grid;gap:10px}.historyItem{position:relative;overflow:hidden;background:rgba(16,16,16,.82);border:1px solid #2a2a2a;border-left:5px solid #555;border-radius:14px;padding:12px 13px;box-shadow:0 4px 14px #0003}.historyItem:before{content:"";position:absolute;inset:0;background:linear-gradient(90deg,var(--event-glow,transparent),transparent 46%);opacity:.16;pointer-events:none}.historyNote{position:relative;color:#f2f2f2;font-size:16px;font-weight:750;line-height:1.35;overflow-wrap:anywhere}.historyNote.emptyNote{color:var(--muted);font-weight:650;font-style:italic}.historyMeta{position:relative;display:flex;align-items:center;flex-wrap:wrap;gap:7px;margin-top:9px}.eventType{display:inline-flex;align-items:center;border-radius:999px;padding:5px 9px;background:#303030;color:#f5f5f5;font-size:13px;font-weight:800;line-height:1.1}.historyDate{color:var(--muted);font-size:13px}.historyKm{margin-left:auto;font-size:16px;font-weight:900;white-space:nowrap;color:#fff}.event-odometer{border-left-color:#555;--event-glow:#555}.event-oil{border-left-color:var(--orange);--event-glow:#d9822b}.event-tyre{border-left-color:#8b7cf6;--event-glow:#8b7cf6}.event-shaft{border-left-color:#b7a05b;--event-glow:#b7a05b}.event-brakes{border-left-color:#dc3545;--event-glow:#dc3545}.event-registration{border-left-color:var(--green);--event-glow:#2f8f3a}.event-fuel{border-left-color:#00a896;--event-glow:#00a896}.event-note{border-left-color:#777;--event-glow:#777}.event-odometer .eventType{background:#18325f}.event-oil .eventType{background:#553113}.event-tyre .eventType{background:#332b64}.event-shaft .eventType{background:#4a4124}.event-brakes .eventType{background:#561b22}.event-registration .eventType{background:#17351a}.event-fuel .eventType{background:#0f463d}.event-note .eventType{background:#333}.emptyHistory{color:var(--muted);padding:8px 0}
|
||||
*{box-sizing:border-box}body{font-family:system-ui,-apple-system,Segoe UI,sans-serif;margin:0;background:linear-gradient(rgba(11,11,11,.82),rgba(11,11,11,.92)),url('/img/fjr.jpg') center top/cover fixed no-repeat,var(--bg);color:var(--text);font-size:16px;-webkit-text-size-adjust:100%}.wrap{max-width:850px;margin:auto;padding:14px;padding-bottom:34px}h1{font-size:26px;margin:4px 0 12px}.topbar{display:flex;align-items:center;gap:12px}.logo{width:64px;height:64px;object-fit:contain;border-radius:0;background:transparent;padding:0;border:0;box-shadow:none}h2{font-size:20px;margin:0 0 12px}.card{background:rgba(27,27,27,.88);backdrop-filter:blur(3px);border:1px solid var(--line);border-radius:18px;padding:16px;margin:12px 0;box-shadow:0 8px 24px #0004}label{display:block;margin-top:14px;margin-bottom:6px;color:#d0d0d0;font-weight:650}input,select,textarea,button{width:100%;font:inherit;font-size:18px;padding:15px 14px;border-radius:14px;border:1px solid #444;background:var(--field);color:var(--text)}select{min-height:54px}textarea{resize:vertical}button{background:var(--green);border:0;margin-top:16px;font-weight:800;min-height:56px;touch-action:manipulation}button:disabled{background:#3a3a3a;color:#888;cursor:not-allowed;opacity:.75}.bikePhoto{width:100%;max-height:330px;object-fit:cover;border-radius:18px;border:1px solid var(--line);box-shadow:0 8px 24px #0006;margin:0 0 12px}.hero{text-decoration:none;color:inherit;display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:10px;align-items:stretch}.heroBox{background:rgba(16,16,16,.84);border:1px solid #2a2a2a;border-radius:14px;padding:13px}.heroBox.main{border-color:#3b5f45}.icon{font-size:22px;margin-right:6px}.grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}.stat{background:rgba(16,16,16,.84);border:1px solid #2a2a2a;border-radius:14px;padding:13px;min-height:112px}.big{font-size:30px;line-height:1.05;font-weight:850}.ok{background:#17351a;border-color:var(--green)}.muted{color:var(--muted);font-size:13px}.historyList{display:grid;gap:10px}.historyItem{position:relative;overflow:hidden;background:rgba(16,16,16,.82);border:1px solid #2a2a2a;border-left:5px solid #555;border-radius:14px;padding:12px 13px;box-shadow:0 4px 14px #0003}.historyItem:before{content:"";position:absolute;inset:0;background:linear-gradient(90deg,var(--event-glow,transparent),transparent 46%);opacity:.16;pointer-events:none}.historyNote{position:relative;color:#f2f2f2;font-size:16px;font-weight:750;line-height:1.35;overflow-wrap:anywhere}.historyNote.emptyNote{color:var(--muted);font-weight:650;font-style:italic}.historyMeta{position:relative;display:flex;align-items:center;flex-wrap:wrap;gap:7px;margin-top:9px}.eventType{display:inline-flex;align-items:center;border-radius:999px;padding:5px 9px;background:#303030;color:#f5f5f5;font-size:13px;font-weight:800;line-height:1.1}.historyDate{color:var(--muted);font-size:13px}.historyKm{margin-left:auto;font-size:16px;font-weight:900;white-space:nowrap;color:#fff}.event-odometer{border-left-color:#555;--event-glow:#555}.event-oil{border-left-color:var(--orange);--event-glow:#d9822b}.event-tyre{border-left-color:#8b7cf6;--event-glow:#8b7cf6}.event-shaft{border-left-color:#b7a05b;--event-glow:#b7a05b}.event-brakes{border-left-color:#dc3545;--event-glow:#dc3545}.event-registration{border-left-color:var(--green);--event-glow:#2f8f3a}.event-fuel{border-left-color:#00a896;--event-glow:#00a896}.event-note{border-left-color:#777;--event-glow:#777}.event-odometer .eventType{background:#18325f}.event-oil .eventType{background:#553113}.event-tyre .eventType{background:#332b64}.event-shaft .eventType{background:#4a4124}.event-brakes .eventType{background:#561b22}.event-registration .eventType{background:#17351a}.event-fuel .eventType{background:#0f463d}.event-note .eventType{background:#333}.emptyHistory{color:var(--muted);padding:8px 0}
|
||||
@media (max-width:520px){.logo{width:52px;height:52px}.wrap{padding:10px}.card{border-radius:16px;padding:14px;margin:10px 0}h1{font-size:24px}.hero{grid-template-columns:1fr}.grid{grid-template-columns:1fr 1fr;gap:8px}.stat{padding:11px;min-height:104px}.stat b{font-size:15px}.big{font-size:26px}input,select,textarea,button{font-size:17px;padding:14px 12px}.historyNote{font-size:17px}.historyKm{margin-left:0;font-size:18px}}
|
||||
@media (max-width:360px){.grid{grid-template-columns:1fr}.big{font-size:28px}}
|
||||
</style>
|
||||
|
|
@ -245,13 +245,13 @@ foreach ([ 'oil_change'=>'Oil', 'front_tyre_change'=>'Front tyre', 'rear_tyre_ch
|
|||
<div class="stat"><b><span class="icon"><?=$card['icon']?></span><?=$card['label']?></b><br><span class="big"><?=$card['value']?></span> <span class="muted"><?=$card['suffix']?></span><br><span class="muted"><?=$card['last']?></span></div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="card"><h2>Add update</h2><form method="post">
|
||||
<label>Current km / event km</label><input name="km" type="number" inputmode="numeric" min="0" value="<?=h($state['odometer'])?>" required>
|
||||
<div class="card"><h2>Add update</h2><form method="post" id="updateForm">
|
||||
<label>Current km / event km</label><input name="km" id="kmInput" type="number" inputmode="numeric" min="<?=h((int)$state['odometer'] + 1)?>" step="1" data-current-km="<?=h($state['odometer'])?>" placeholder="> <?=h(number_format((int)$state['odometer']))?>" required>
|
||||
<label>Date</label><input name="event_date" type="date" value="<?=h(date('Y-m-d'))?>" required>
|
||||
<label>Type</label><select name="type"><?php foreach ($types as $k=>$v): ?><option value="<?=h($k)?>"><?=h($v)?></option><?php endforeach; ?></select>
|
||||
<label>Cost (optional)</label><input name="cost" placeholder="e.g. 42.50">
|
||||
<label>Note (optional)</label><textarea name="note" rows="3" placeholder="brand, details, reminder..."></textarea>
|
||||
<button>Save + publish MQTT</button>
|
||||
<button id="saveButton" disabled>Save</button>
|
||||
</form></div>
|
||||
<div class="card"><h2>Recent history</h2><div class="historyList">
|
||||
<?php if (!$events): ?>
|
||||
|
|
@ -268,4 +268,18 @@ foreach ([ 'oil_change'=>'Oil', 'front_tyre_change'=>'Front tyre', 'rear_tyre_ch
|
|||
</article>
|
||||
<?php endforeach; ?>
|
||||
</div></div>
|
||||
</div></body></html>
|
||||
</div><script>
|
||||
(() => {
|
||||
const kmInput = document.getElementById('kmInput');
|
||||
const saveButton = document.getElementById('saveButton');
|
||||
if (!kmInput || !saveButton) return;
|
||||
const currentKm = Number(kmInput.dataset.currentKm || 0);
|
||||
const updateSaveState = () => {
|
||||
const rawValue = kmInput.value.trim();
|
||||
const enteredKm = Number(rawValue);
|
||||
saveButton.disabled = rawValue === '' || !Number.isFinite(enteredKm) || enteredKm <= currentKm;
|
||||
};
|
||||
kmInput.addEventListener('input', updateSaveState);
|
||||
updateSaveState();
|
||||
})();
|
||||
</script></body></html>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue