Team-API, Sidebar-Zaehler und Format-Hilfen fuer Gutschriften, Angebote und E-Mail-Speicher

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-02 02:55:48 +00:00
1 parent 813c6a7e18
commit 91d526e909
13 files changed
+487 -47

No files matched your search

-31
View File
@@ -1,31 +0,0 @@
import { useEffect, useState } from 'react'
import { getChatUnreadCount } from '../lib/teamApi'
// Zahl ungelesener Kundennachrichten fuer die Sidebar: jede Minute bei sichtbarem Tab und sofort beim
// Zurueckkehren; Fehler behalten den letzten Wert.
const POLL_MS = 60 * 1000
export function useChatUnread() {
const [unread, setUnread] = useState(0)
useEffect(() => {
let dead = false
const load = () => {
if (document.visibilityState === 'hidden') return
getChatUnreadCount()
.then((r) => { if (!dead) setUnread(Number(r?.unread) || 0) })
.catch(() => {})
}
load()
const iv = setInterval(load, POLL_MS)
const onVisible = () => { if (document.visibilityState === 'visible') load() }
document.addEventListener('visibilitychange', onVisible)
return () => {
dead = true
clearInterval(iv)
document.removeEventListener('visibilitychange', onVisible)
}
}, [])
return unread
}
+2 -1
View File
@@ -1,5 +1,6 @@
import { useEffect, useState } from 'react'
import { getCustomerAbo } from '../lib/customerAdminApi'
// Team-Eingang: alle Mitarbeiter (vorher Admin-Route, Nicht-Admins bekamen 403 und damit immer den Schalter)
import { getCustomerAboStatus as getCustomerAbo } from '../lib/teamApi'
// Ergebnis je Kunde zwischengespeichert (nur Erfolge), laufende Abfragen werden geteilt
const cache = new Map()
+38
View File
@@ -0,0 +1,38 @@
import { useEffect, useState } from 'react'
import { getChatUnreadCount, getCreditOpenCount, getStorageOpenCount } from '../lib/teamApi'
// Zahlen in der Sidebar unter Kunden: ungelesene Chats, offene Gutschrift-Antraege, offene Speicher-Aufgaben.
// Jede Minute bei sichtbarem Tab und sofort beim Zurueckkehren; Fehler behalten den letzten Wert.
const POLL_MS = 60 * 1000
const SOURCES = [
['chat', () => getChatUnreadCount().then((r) => r?.unread)],
['credits', () => getCreditOpenCount().then((r) => r?.open)],
['storage', () => getStorageOpenCount().then((r) => r?.open)],
]
export function useSidebarCounts() {
const [counts, setCounts] = useState({ chat: 0, credits: 0, storage: 0 })
useEffect(() => {
let dead = false
const load = () => {
if (document.visibilityState === 'hidden') return
for (const [key, fetchCount] of SOURCES) {
fetchCount()
.then((n) => { if (!dead) setCounts((c) => ({ ...c, [key]: Number(n) || 0 })) })
.catch(() => {})
}
}
load()
const iv = setInterval(load, POLL_MS)
const onVisible = () => { if (document.visibilityState === 'visible') load() }
document.addEventListener('visibilitychange', onVisible)
return () => {
dead = true
clearInterval(iv)
document.removeEventListener('visibilitychange', onVisible)
}
}, [])
return counts
}