Sidebar: Chat als Unterpunkt von Kunden mit Zahl der ungelesenen Nachrichten

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-01 23:32:24 +00:00
1 parent 717a3323fa
commit 005875d970
7 files changed
+187 -17

No files matched your search

+37 -17
View File
@@ -16,10 +16,27 @@ import {
IconLayoutSidebarLeftCollapse,
IconLayoutSidebarLeftExpand,
IconExternalLink,
IconMessages,
} from '@tabler/icons-react'
import { openProjectAdmin } from '../lib/employeeAdminApi'
import { serverpulsApi } from '../lib/serverpulsApi'
import { startsCollapsed } from '../lib/sidebar'
import { buildNavLinks } from '../lib/navLinks'
import { useChatUnread } from '../hooks/useChatUnread'
const ICONS = {
tickets: <IconTicket />,
planboard: <IconCalendar />,
projects: <IconFolders />,
services: <IconLayoutGrid />,
customers: <IconUsers />,
chat: <IconMessages />,
leads: <IconTargetArrow />,
finance: <IconReportMoney />,
legal: <IconScale />,
serverpuls: <IconActivityHeartbeat />,
admin: <IconSettings />,
}
export default function Sidebar() {
const { user, logout, isAdmin } = useAuth()
@@ -28,6 +45,7 @@ export default function Sidebar() {
const [collapsed, setCollapsed] = useState(() => startsCollapsed())
const [switching, setSwitching] = useState(false)
const [pulseLevel, setPulseLevel] = useState('ok')
const chatUnread = useChatUnread()
// Serverpuls-Punkt: nur Admins, beim Laden und alle 5 Minuten; Fehler bleiben still
useEffect(() => {
@@ -53,20 +71,8 @@ export default function Sidebar() {
navigate('/login')
}
// Eine flache Liste: fuer ein kleines Team reichen acht Eintraege ohne Gruppen
const links = [
{ label: 'Tickets', href: '/tickets', icon: <IconTicket /> },
{ label: 'Planboard', href: '/planboard', icon: <IconCalendar /> },
{ label: 'Projekte', href: '/projects', icon: <IconFolders /> },
{ label: 'Services', href: '/services', icon: <IconLayoutGrid /> },
{ label: 'Kunden', href: '/customers', icon: <IconUsers /> },
// Leads liegen auf Eis (Lead-Automatik gestoppt 2026-09-30): grau, nicht klickbar
{ label: 'Leads', href: '/leads', icon: <IconTargetArrow />, paused: true },
...(isAdmin ? [{ label: 'Finanzen', href: '/finance', also: '/finanzen', icon: <IconReportMoney /> }] : []),
{ label: 'Rechtliches', href: '/rechtliches', icon: <IconScale /> },
...(isAdmin ? [{ label: 'Serverpuls', href: '/serverpuls', icon: <IconActivityHeartbeat />, dot: pulseLevel }] : []),
...(isAdmin ? [{ label: 'Admin', href: '/admin', icon: <IconSettings /> }] : []),
]
// Eintraege und Unterpunkte (Kunden -> Chat) aus lib/navLinks.js, Icons ueber key
const links = buildNavLinks({ isAdmin, pulseLevel, chatUnread })
const isActive = (href) =>
location.pathname === href || location.pathname.startsWith(href + '/')
@@ -92,7 +98,7 @@ export default function Sidebar() {
title={`${link.label} (pausiert)`}
aria-disabled="true"
>
{link.icon}
{ICONS[link.key]}
<span className="side-link-label">{link.label}</span>
</span>
) : (
@@ -102,7 +108,7 @@ export default function Sidebar() {
className={`side-link ${isLinkActive(link) ? 'active' : ''}`}
title={link.label}
>
{link.icon}
{ICONS[link.key]}
<span className="side-link-label">{link.label}</span>
{link.dot && link.dot !== 'ok' && (
<span
@@ -112,7 +118,21 @@ export default function Sidebar() {
/>
)}
</Link>
))}
)).flatMap((item, i) => [
item,
...(links[i].children || []).map((child) => (
<Link
key={child.href}
to={child.href}
className={`side-link side-sublink ${isActive(child.href) ? 'active' : ''}`}
title={child.count > 0 ? `${child.label} (${child.count} ungelesen)` : child.label}
>
{ICONS[child.key]}
<span className="side-link-label">{child.label}</span>
{child.count > 0 && <span className="side-count">{child.count}</span>}
</Link>
)),
])}
<button
type="button"
className="side-link side-link-button"