Files
premier-gunner/public/js/api.js
T
Keysat 5868852686 Add records, Elijah scores, per-session notes, and PWA update prompt
App features:
- Personal-best records per metric: manually settable in Settings and
  auto-updated when a session beats them; shown in the log modal and a
  new dashboard "Personal records" card.
- Juggling now counts by 1 instead of 5.
- 1-on-1 with Elijah gains Technical Skill and Effort scores (out of 10)
  as manual inputs, plus an optional per-session note.
- Service worker now uses a controlled update flow: an in-app
  "new version ready" banner activates the update on tap and reloads.

Data model:
- category_metrics gains track_record + record; entries gains note.
- Idempotent migrations bring existing databases up to date (juggling
  step/record, Elijah score metrics) alongside the updated seed.

StartOS package:
- Bump to 0.1.2:0 with release notes.
- Build x86_64 only (drop aarch64) per deployment target.
2026-06-03 08:46:27 -05:00

48 lines
1.9 KiB
JavaScript

// Thin fetch wrapper. Redirects to login on 401.
async function req(method, url, body) {
const opts = { method, headers: {} };
if (body !== undefined) {
opts.headers['Content-Type'] = 'application/json';
opts.body = JSON.stringify(body);
}
const res = await fetch(url, opts);
if (res.status === 401 && !url.endsWith('/api/login')) {
location.href = '/login.html';
throw new Error('Not authenticated');
}
const data = res.headers.get('content-type')?.includes('application/json')
? await res.json() : null;
if (!res.ok) throw new Error((data && data.error) || `Request failed (${res.status})`);
return data;
}
export const api = {
login: (password) => req('POST', '/api/login', { password }),
logout: () => req('POST', '/api/logout'),
me: () => req('GET', '/api/me'),
setPassword: (current, next) => req('POST', '/api/password', { current, next }),
categories: (all = false) => req('GET', `/api/categories${all ? '?all=1' : ''}`),
addCategory: (c) => req('POST', '/api/categories', c),
updateCategory: (id, c) => req('PUT', `/api/categories/${id}`, c),
addMetric: (catId, m) => req('POST', `/api/categories/${catId}/metrics`, m),
updateMetric: (id, m) => req('PUT', `/api/metrics/${id}`, m),
deleteMetric: (id) => req('DELETE', `/api/metrics/${id}`),
day: (day) => req('GET', `/api/day/${day}`),
logEntry: (e) => req('POST', '/api/entries', e),
deleteEntry: (id) => req('DELETE', `/api/entries/${id}`),
saveNotes: (day, notes) => req('PUT', `/api/day/${day}/notes`, { notes }),
plans: (from, to) => req('GET', `/api/plans?from=${from}&to=${to}`),
addPlan: (p) => req('POST', '/api/plans', p),
deletePlan: (id) => req('DELETE', `/api/plans/${id}`),
goals: () => req('GET', '/api/goals'),
addGoal: (g) => req('POST', '/api/goals', g),
updateGoal: (id, g) => req('PUT', `/api/goals/${id}`, g),
deleteGoal: (id) => req('DELETE', `/api/goals/${id}`),
stats: () => req('GET', '/api/stats'),
};