From c1fda8a717c91112685f24cb58cda11088336055 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 1 Oct 2026 19:36:55 +0000 Subject: [PATCH] Kundenansicht im Dashboard: Kennung bei jeder Anfrage, Banner mit Beenden, Hinweis bei ersetzter oder abgelaufener Ansicht Co-Authored-By: Claude Opus 5.5 --- public/app.js | 31 +++++- public/dashboard.html | 2 + public/kundenansicht.js | 109 +++++++++++++++++++ public/kundenbereich.css | 12 +++ test/kundenansichtClient.test.js | 173 +++++++++++++++++++++++++++++++ test/ui/kundenansicht.ui.mjs | 121 +++++++++++++++++++++ 6 files changed, 443 insertions(+), 5 deletions(-) create mode 100644 public/kundenansicht.js create mode 100644 test/kundenansichtClient.test.js create mode 100644 test/ui/kundenansicht.ui.mjs diff --git a/public/app.js b/public/app.js index c14c643..4ad24ce 100644 --- a/public/app.js +++ b/public/app.js @@ -634,6 +634,19 @@ function renderViewAsBanner(me) { const banner = document.getElementById('viewas-banner') if (!banner || !me.viewAs) return banner.classList.remove('hidden') + // Kundenansicht aus dem Ticketsystem (mit Kennung): Beenden fuehrt zurueck auf die Kundenseite im Ticketsystem + if (me.viewId) { + banner.innerHTML = ` + Kundenansicht: ${escapeHtml(me.customer?.name || 'Kunde')} · geöffnet von ${escapeHtml(me.admin?.name || 'Mitarbeiter')} + + ` + document.getElementById('exit-viewas-btn')?.addEventListener('click', async () => { + const { redirect } = await api('/api/auth/kundenansicht/ende', { method: 'POST' }).catch(() => ({})) + window.location.href = redirect || 'https://ticket.webklar.com/customers' + }) + return + } + // Alte Ansicht "Als Kunde ansehen" aus dem Admin-Panel (bis das Panel abgeschaltet ist) banner.innerHTML = ` Admin-Ansicht: Du siehst das Portal als ${escapeHtml(me.customer?.name || 'Kunde')}. @@ -765,6 +778,12 @@ function updateChatBadge(unread) { } } +// Nachrichten als gelesen markieren; in der Kundenansicht nicht (der Kunde hat sie ja nicht gelesen) +function markChatRead() { + if (chatState.viewAs) return Promise.resolve() + return api('/api/chat/read', { method: 'POST' }).catch(() => {}) +} + async function pollChatMessages() { if (document.hidden) return try { @@ -772,7 +791,7 @@ async function pollChatMessages() { const data = await api(`/api/chat/messages${q}`) appendChatMessages(data.messages || []) if (isChatTabActive() && (data.unread || 0) > 0) { - await api('/api/chat/read', { method: 'POST' }).catch(() => {}) + await markChatRead() updateChatBadge(0) } } catch { @@ -809,7 +828,7 @@ async function initChat() { }) await pollChatMessages() - await api('/api/chat/read', { method: 'POST' }).catch(() => {}) + await markChatRead() updateChatBadge(0) chatState.pollTimer = setInterval(() => { if (isChatTabActive()) pollChatMessages() @@ -2004,7 +2023,7 @@ function showView(name, { updateHash = true } = {}) { if (box) box.innerHTML = `

${escapeHtml(err.message || 'Konnte nicht geladen werden.')}

` }) if (name === 'chat') { - api('/api/chat/read', { method: 'POST' }).catch(() => {}) + markChatRead() updateChatBadge(0) } if (updateHash) { @@ -2070,8 +2089,8 @@ async function initDashboardPage() { if (!me.authenticated) { const target = new URL(loginUrl, window.location.origin) - // Passwort auf einem anderen Gerät geändert: Hinweis auf der Anmeldeseite - if (me.reason === 'password_changed' && me.message) target.searchParams.set('error', me.message) + // Passwort auf einem anderen Gerät geändert oder Kundenansicht abgelaufen: Hinweis auf der Anmeldeseite + if ((me.reason === 'password_changed' || me.reason === 'view_expired') && me.message) target.searchParams.set('error', me.message) window.location.href = target.pathname + target.search return } @@ -2085,6 +2104,8 @@ async function initDashboardPage() { } const customer = me.customer + // Kundenansicht: ab jetzt traegt jede /api-Anfrage die Kennung dieser Ansicht (public/kundenansicht.js) + if (me.viewId) window.KbView?.setId(me.viewId) chatState.viewAs = Boolean(me.viewAs) takeoverState.customer = customer renderViewAsBanner(me) diff --git a/public/dashboard.html b/public/dashboard.html index 1d2f400..599a99d 100644 --- a/public/dashboard.html +++ b/public/dashboard.html @@ -285,6 +285,8 @@ + +