diff --git a/backend/static/js/app.js b/backend/static/js/app.js
index 581a260..45724cb 100644
--- a/backend/static/js/app.js
+++ b/backend/static/js/app.js
@@ -3,7 +3,7 @@
Router, State-Management, Navigation, Initialisierung.
============================================================ */
-const APP_VER = '536'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
+const APP_VER = '537'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen
const APP_VERSION = '1.1.3'; // ← semantische Version, wird bei make release gesetzt
const IS_STAGING = location.hostname === 'staging.banyaro.app';
diff --git a/backend/static/js/pages/notes.js b/backend/static/js/pages/notes.js
index d9ce75d..d78797d 100644
--- a/backend/static/js/pages/notes.js
+++ b/backend/static/js/pages/notes.js
@@ -136,7 +136,13 @@ window.Page_notes = (() => {
@@ -361,6 +367,11 @@ window.Page_notes = (() => {
_container.querySelector('#notes-privacy-notice')?.remove();
});
+ // Neue Notiz
+ _container.querySelector('#notes-new-btn')?.addEventListener('click', () => {
+ _openCreateModal(_filterType || '');
+ });
+
// Filter-Chips
_container.querySelectorAll('.notes-chip').forEach(btn => {
btn.addEventListener('click', () => {
@@ -464,6 +475,101 @@ window.Page_notes = (() => {
_render();
}
+ // ----------------------------------------------------------
+ // Create-Modal — neue Notiz mit vorausgewählter Kategorie
+ // ----------------------------------------------------------
+ function _openCreateModal(preselectedType = '') {
+ const ERSTELL_RUBRIKEN = RUBRIKEN.filter(r => r.type !== ''); // ohne "Alle"
+ let _selType = preselectedType || ERSTELL_RUBRIKEN[0].type;
+
+ const modalId = 'notes-create-modal';
+ document.getElementById(modalId)?.remove();
+
+ const overlay = document.createElement('div');
+ overlay.id = modalId;
+ overlay.style.cssText = `position:fixed;inset:0;z-index:9999;display:flex;align-items:flex-end;justify-content:center;background:rgba(0,0,0,0.45)`;
+
+ const _buildContent = () => {
+ const rb = _rubrik(_selType);
+ return `
+
+
+
Neue Notiz
+
+
+
+
+
+ ${ERSTELL_RUBRIKEN.map(r => `
+ `).join('')}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
`;
+ };
+
+ overlay.innerHTML = _buildContent();
+ document.body.appendChild(overlay);
+
+ const _rebind = () => {
+ overlay.querySelectorAll('.nc-cat').forEach(btn => {
+ btn.addEventListener('click', () => {
+ _selType = btn.dataset.type;
+ overlay.innerHTML = _buildContent();
+ _rebind();
+ overlay.querySelector('#nc-text')?.focus();
+ });
+ });
+
+ overlay.querySelector('#nc-cancel')?.addEventListener('click', () => overlay.remove());
+ overlay.addEventListener('click', e => { if (e.target === overlay) overlay.remove(); });
+
+ overlay.querySelector('#nc-save')?.addEventListener('click', async () => {
+ const text = overlay.querySelector('#nc-text')?.value?.trim();
+ if (!text) { UI.toast.warning('Bitte einen Text eingeben.'); return; }
+ const btn = overlay.querySelector('#nc-save');
+ await UI.asyncButton(btn, async () => {
+ const rb = _rubrik(_selType);
+ await API.notes.create(_selType, 'standalone', {
+ text,
+ parent_label: rb.label,
+ });
+ overlay.remove();
+ _filterType = _selType;
+ await _reload();
+ UI.toast.success('Notiz gespeichert.');
+ });
+ });
+
+ setTimeout(() => overlay.querySelector('#nc-text')?.focus(), 100);
+ };
+
+ _rebind();
+ }
+
// ----------------------------------------------------------
// Edit-Modal (Bottom-Sheet Stil)
// ----------------------------------------------------------
diff --git a/backend/static/sw.js b/backend/static/sw.js
index ecb2350..aa968c2 100644
--- a/backend/static/sw.js
+++ b/backend/static/sw.js
@@ -3,7 +3,7 @@
Offline-Cache + Push Notifications + Tile-Cache
============================================================ */
-const CACHE_VERSION = 'by-v559';
+const CACHE_VERSION = 'by-v560';
const CACHE_STATIC = `${CACHE_VERSION}-static`;
const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten
const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache