diff --git a/JournalAppPrototype/journal.html b/JournalAppPrototype/journal.html
index e081616..a04d452 100644
--- a/JournalAppPrototype/journal.html
+++ b/JournalAppPrototype/journal.html
@@ -538,6 +538,7 @@
.side-panel-actions {
display: flex;
justify-content: flex-end;
+ gap: 8px;
margin-top: 8px;
}
@@ -556,6 +557,7 @@
gap: 8px;
padding: 6px 0;
border-bottom: 1px solid var(--bg-accent);
+ align-items: flex-start;
}
.panel-entry:last-child { border-bottom: none; }
@@ -573,6 +575,60 @@
color: var(--text-primary);
line-height: 1.45;
word-break: break-word;
+ flex: 1;
+ }
+
+ .panel-entry-body textarea {
+ width: 100%;
+ background: var(--bg-accent);
+ border: 1px solid var(--accent);
+ border-radius: 4px;
+ color: var(--text-primary);
+ font-size: 0.85rem;
+ line-height: 1.45;
+ padding: 4px 6px;
+ resize: vertical;
+ min-height: 48px;
+ box-sizing: border-box;
+ }
+
+ .panel-entry-actions {
+ display: flex;
+ gap: 4px;
+ flex-shrink: 0;
+ padding-top: 1px;
+ }
+
+ .panel-entry-action-btn {
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 2px 5px;
+ border-radius: 4px;
+ font-size: 0.9rem;
+ line-height: 1;
+ color: var(--text-secondary);
+ transition: background 0.15s, color 0.15s;
+ }
+
+ .panel-entry-action-btn:hover { background: var(--bg-accent); color: var(--text-primary); }
+ .panel-entry-action-btn.del:hover { color: #e05252; }
+
+ .panel-edit-mode-btn {
+ background: transparent;
+ border: 1px solid var(--text-secondary);
+ color: var(--text-secondary);
+ border-radius: 6px;
+ padding: 8px 14px;
+ font-size: 0.85rem;
+ cursor: pointer;
+ transition: border-color 0.15s, color 0.15s;
+ }
+
+ .panel-edit-mode-btn:hover,
+ .panel-edit-mode-btn.active {
+ border-color: var(--accent);
+ color: var(--accent);
}
/* ── Breakout card in main timeline ─────────────────────── */
@@ -1481,6 +1537,7 @@
+ const actions = (panelEditMode && e._source === 'panel')
+ ? `
+
+
+
`
+ : '';
+ return `
${time}${sourceLabel}
${mood}${escapeHtml(e.text)}${tags ? '
'+tags+'
' : ''}
+ ${actions}
`;
}).join('');
return `
`;
@@ -2277,6 +2351,33 @@
});
}
+ function deleteProjectEntry(id) {
+ return new Promise((resolve, reject) => {
+ const tx = db.transaction(PROJECT_ENTRIES_STORE, 'readwrite');
+ const store = tx.objectStore(PROJECT_ENTRIES_STORE);
+ const req = store.delete(id);
+ req.onsuccess = () => resolve();
+ req.onerror = () => reject(req.error);
+ });
+ }
+
+ function updateProjectEntry(id, text) {
+ return new Promise((resolve, reject) => {
+ const tx = db.transaction(PROJECT_ENTRIES_STORE, 'readwrite');
+ const store = tx.objectStore(PROJECT_ENTRIES_STORE);
+ const getReq = store.get(id);
+ getReq.onsuccess = () => {
+ const entry = getReq.result;
+ if (!entry) { reject(new Error('Entry not found')); return; }
+ entry.text = text;
+ const putReq = store.put(entry);
+ putReq.onsuccess = () => resolve();
+ putReq.onerror = () => reject(putReq.error);
+ };
+ getReq.onerror = () => reject(getReq.error);
+ });
+ }
+
function getProjectEntries(projectId) {
return new Promise((resolve, reject) => {
const tx = db.transaction(PROJECT_ENTRIES_STORE, 'readonly');
@@ -2906,6 +3007,70 @@
if (e.key === 'Enter' && e.ctrlKey) { e.preventDefault(); if (dbReady) panelSubmit(); }
});
+ document.getElementById('panelEditModeBtn').addEventListener('click', () => {
+ panelEditMode = !panelEditMode;
+ const btn = document.getElementById('panelEditModeBtn');
+ btn.textContent = panelEditMode ? 'Done' : 'Edit';
+ btn.classList.toggle('active', panelEditMode);
+ if (activePanelProjectId != null) renderProjectTimeline(activePanelProjectId);
+ });
+
+ document.getElementById('sidePanelTimeline').addEventListener('click', async e => {
+ const actionBtn = e.target.closest('[data-action]');
+ if (!actionBtn) return;
+ const entry = actionBtn.closest('.panel-entry');
+ if (!entry || entry.dataset.source !== 'panel') return;
+ const id = parseInt(entry.dataset.id);
+
+ if (actionBtn.dataset.action === 'delete') {
+ try {
+ await deleteProjectEntry(id);
+ await renderProjectTimeline(activePanelProjectId);
+ const countEl = document.querySelector(`.breakout-card[data-project-id="${activePanelProjectId}"] .breakout-card-count`);
+ if (countEl) {
+ const count = await getCombinedProjectEntryCount(activePanelProjectId);
+ countEl.textContent = `${count} ${count === 1 ? 'entry' : 'entries'}`;
+ }
+ showToast('Entry deleted');
+ } catch (err) {
+ console.error('Failed to delete project entry:', err);
+ showToast('Error deleting entry');
+ }
+ return;
+ }
+
+ if (actionBtn.dataset.action === 'edit') {
+ const body = entry.querySelector('.panel-entry-body');
+ const currentText = entry.dataset.text;
+ body.innerHTML = `
`;
+ const textarea = body.querySelector('textarea');
+ textarea.focus();
+ textarea.setSelectionRange(textarea.value.length, textarea.value.length);
+
+ const save = async () => {
+ const newText = textarea.value.trim();
+ if (!newText || newText === currentText) {
+ await renderProjectTimeline(activePanelProjectId);
+ return;
+ }
+ try {
+ await updateProjectEntry(id, newText);
+ await renderProjectTimeline(activePanelProjectId);
+ showToast('Entry updated');
+ } catch (err) {
+ console.error('Failed to update project entry:', err);
+ showToast('Error updating entry');
+ }
+ };
+
+ textarea.addEventListener('blur', save, { once: true });
+ textarea.addEventListener('keydown', ke => {
+ if (ke.key === 'Enter' && !ke.shiftKey) { ke.preventDefault(); textarea.removeEventListener('blur', save); save(); }
+ if (ke.key === 'Escape') { textarea.removeEventListener('blur', save); renderProjectTimeline(activePanelProjectId); }
+ });
+ }
+ });
+
init();