Funktionen-Reiter: News und Terminplaner je Projekt

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-02 23:57:03 +00:00
1 parent 36eb55b81b
commit 426a5d6654
7 files changed
+209 -48

No files matched your search

+52
View File
@@ -0,0 +1,52 @@
// Kunden-Reiter "Funktionen": Register der Funktionen je Projekt (News, Terminplaner), Aktionen je Zustand und
// Einarbeiten der Portal-Antwort. Rein, unter Node testbar.
/** Funktionen in Anzeigereihenfolge; key = Schluessel im Portal (features[key], POST /funktionen/:customerId/:key). */
export const FUNKTIONEN = [
{
key: 'news',
label: 'News',
bestaetigen: {
activate: 'News ohne Zahlung aktivieren?',
disable: 'News abschalten? Die Website zeigt dann keine Beiträge mehr.',
},
},
{
key: 'termine',
label: 'Terminplaner',
bestaetigen: {
activate: 'Terminplaner ohne Zahlung aktivieren?',
disable: 'Terminplaner abschalten? Auf der Website sind dann keine Buchungen mehr möglich.',
},
},
]
/** Zustand einer Funktion -> [Ton des Abzeichens, Beschriftung]. */
export const ZUSTAND = {
off: ['muted', 'Aus'],
ordered: ['warn', 'Bestellt'],
setup: ['info', 'Einrichtung'],
active: ['ok', 'Aktiv'],
disabled: ['muted', 'Abgeschaltet'],
}
/** Ansicht einer Funktion im Projekt (Portal: project.features[key]); ohne Eintrag gilt "off". */
export const funktionOf = (project, key) => project?.features?.[key] || { state: 'off' }
/** Moegliche Aktionen je Zustand: Aktivieren (ohne Zahlung) ausser bei "active", Abschalten solange bestellt, in Einrichtung oder aktiv. */
export function aktionen(state) {
const list = []
if (state !== 'active') list.push('activate')
if (['ordered', 'setup', 'active'].includes(state)) list.push('disable')
return list
}
/**
* Antwort des Portals (das eine geaenderte Projekt) in die Projektliste einarbeiten: uebernommen wird nur
* aktualisiert.features[key]; Projektfelder und die anderen Funktionen bleiben. Gibt eine neue Liste zurueck.
*/
export function mergeFunktion(projects, projectId, key, aktualisiert) {
const view = aktualisiert?.features?.[key]
if (!view) return projects
return projects.map((p) => (p.projectId === projectId ? { ...p, features: { ...p.features, [key]: view } } : p))
}
+5 -3
View File
@@ -89,11 +89,13 @@ export const listStorageTasks = () => request('/storage-tasks')
export const getStorageOpenCount = () => request('/storage-tasks/open-count')
export const markStorageDone = (id) => request(`/storage-tasks/${enc(id)}/done`, { method: 'POST', body: {} })
// --- Funktionen (News-Pinnwand je Projekt) ---
// --- Funktionen (News-Pinnwand, Terminplaner je Projekt) ---
export const getFunktionen = (customerId) => request(`/funktionen/${enc(customerId)}`)
export const setNewsFeature = (customerId, { projectId, action, note }) =>
request(`/funktionen/${enc(customerId)}/news`, { method: 'POST', body: { projectId, action, note } })
/** Aktivieren (ohne Zahlung) oder Abschalten einer Funktion (key: news | termine); Antwort { projects: [das eine Projekt] }. */
export const setFeature = (customerId, key, { projectId, action, note }) =>
request(`/funktionen/${enc(customerId)}/${enc(key)}`, { method: 'POST', body: { projectId, action, note } })
export const setNewsFeature = (customerId, body) => setFeature(customerId, 'news', body)
// --- Abo-Status (alle Mitarbeiter) ---
+3
View File
@@ -8,6 +8,9 @@ const LABELS = {
news_bild: 'News-Foto hochgeladen',
news_geaendert: 'News geändert',
news_geloescht: 'News gelöscht',
termin_einstellungen: 'Terminplaner-Einstellungen geändert',
termin_aktion: 'Termin bearbeitet',
termin_manuell: 'Termin eingetragen',
}
/** Deutsche Beschriftung einer Aktion; unbekannte Aktionen erscheinen roh. */