diff --git a/index.html b/index.html index 1de8749..da80586 100644 --- a/index.html +++ b/index.html @@ -405,27 +405,47 @@ } tick(); setInterval(tick, 1000); - // ── Notes ────────────────────────────────────────────────────────────── - const NOTES_KEY = 'dashboard_notes'; + // ── Notes — server-backed so they sync across all devices ───────────── + const API = '/notes.php'; + let _notes = []; - function loadNotes() { - return JSON.parse(localStorage.getItem(NOTES_KEY) || '[]'); + function escHtml(s) { + return String(s).replace(/&/g,'&').replace(//g,'>').replace(/\n/g,'
'); } - function saveNotes(notes) { - localStorage.setItem(NOTES_KEY, JSON.stringify(notes)); + + async function notesApi(action, body = {}) { + try { + const r = await fetch(API, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ action, ...body }), + credentials: 'same-origin', + }); + return await r.json(); + } catch (e) { return { ok: false }; } + } + + async function fetchNotes() { + const el = document.getElementById('notes-list'); + if (el && !_notes.length) el.innerHTML = '
Loading…
'; + try { + const r = await fetch(API + '?action=list', { credentials: 'same-origin' }); + const d = await r.json(); + _notes = d.notes || []; + } catch (e) { _notes = []; } + renderNotes(); } function renderNotes() { - const notes = loadNotes(); - const list = document.getElementById('notes-list'); + const list = document.getElementById('notes-list'); if (!list) return; - if (!notes.length) { + if (!_notes.length) { list.innerHTML = '
No notes yet. Add one above.
'; return; } - list.innerHTML = notes.map((n, i) => ` -
-
@@ -433,49 +453,48 @@ ${n.detail ? `
${escHtml(n.detail)}
` : ''}
${new Date(n.ts).toLocaleString('en-US',{month:'short',day:'numeric',hour:'2-digit',minute:'2-digit'})}
- +
`).join(''); } - function escHtml(s) { - return String(s).replace(/&/g,'&').replace(//g,'>').replace(/\n/g,'
'); - } - - function addNote() { + async function addNote() { const txt = document.getElementById('note-input').value.trim(); const det = document.getElementById('note-detail').value.trim(); if (!txt) { document.getElementById('note-input').focus(); return; } - const notes = loadNotes(); - notes.unshift({ text: txt, detail: det, done: false, ts: Date.now() }); - saveNotes(notes); - document.getElementById('note-input').value = ''; - document.getElementById('note-detail').value = ''; - document.getElementById('note-detail').style.display = 'none'; - document.getElementById('note-detail-toggle').textContent = '+ Add details'; - renderNotes(); + const btn = document.querySelector('.btn-note-add'); + btn.disabled = true; + const r = await notesApi('add', { text: txt, detail: det }); + btn.disabled = false; + if (r.ok) { + _notes.unshift(r.note); + document.getElementById('note-input').value = ''; + document.getElementById('note-detail').value = ''; + document.getElementById('note-detail').style.display = 'none'; + document.getElementById('note-detail-toggle').textContent = '+ Add details'; + renderNotes(); + } } - function toggleNote(i) { - const notes = loadNotes(); - notes[i].done = !notes[i].done; - saveNotes(notes); + async function toggleNote(id) { + _notes = _notes.map(n => n.id === id ? {...n, done: !n.done} : n); renderNotes(); + await notesApi('toggle', { id }); } - function deleteNote(i) { - const notes = loadNotes(); - notes.splice(i, 1); - saveNotes(notes); + async function deleteNote(id) { + _notes = _notes.filter(n => n.id !== id); renderNotes(); + await notesApi('delete', { id }); } - function clearDone() { - saveNotes(loadNotes().filter(n => !n.done)); + async function clearDone() { + _notes = _notes.filter(n => !n.done); renderNotes(); + await notesApi('clear-done'); } function toggleDetail() { - const d = document.getElementById('note-detail'); + const d = document.getElementById('note-detail'); const btn = document.getElementById('note-detail-toggle'); const show = d.style.display === 'none'; d.style.display = show ? 'block' : 'none'; @@ -484,7 +503,11 @@ } document.addEventListener('DOMContentLoaded', () => { - renderNotes(); + fetchNotes(); + // Re-sync when tab becomes visible (switching back from another device) + document.addEventListener('visibilitychange', () => { + if (document.visibilityState === 'visible') fetchNotes(); + }); document.getElementById('note-input').addEventListener('keydown', e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); addNote(); } });