feat: Kundenportal-Ausbau - Tabs, Projekt-Einblicke, Git-Zeiterfassung, Rechnungen, Chat
Kunden-Dashboard: - Tab-Navigation: Projekte | Was wurde gemacht | Rechnungen | Chat - Projekt-Details pro Projekt: letzte Git-Commits (Titel+Beschreibung), Projektgroesse, Datei-Uebersicht (Top-Level aggregiert), Ticket-Arbeiten - Rechnungen: gestylte Liste mit Status-Pillen, Ansehen/Zahlen-Link, PDF-Download ueber Server-Proxy (IDOR-geschuetzt) - Chat mit dem Webklar-Team (Polling, Ungelesen-Badge, viewAs blockiert) Admin-Dashboard: - Chat-Tab: Konversationsliste + Thread + Antwortfeld, Ungelesen-Badge Backend: - giteaAdmin: getRepoInfo, listRepoCommits, getRepoTreeSummary - projectInsights: 5-min-Cache, Invalidierung per Gitea-Webhook - /api/projects/:id/git|files|work mit Ownership-Check (404) - /api/chat/* (Kunde) + /api/portal-admin/chats/* (Admin), portalMessages-Collection - mailer: E-Mail-Benachrichtigung an Admins bei Kundennachricht (15-min-Throttle) - gitWorksheet: dd.mm.yyyy, voller Commit-Body, startTime leer (Zeit-Nachtrag), Auto-Webpage-Ticket bei Push auf Projekt ohne Ticket (ensureProjectTicket) - customerActivity: Git-Push-Eintraege fuer Kunden sichtbar Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -49,6 +49,33 @@
|
||||
.recent-list li { padding: 7px 0; border-bottom: 1px solid rgba(255,255,255,0.07); font-size: 14px; }
|
||||
.recent-list li:last-child { border-bottom: none; }
|
||||
.two-col { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 14px; }
|
||||
|
||||
/* Chat */
|
||||
.badge-pill {
|
||||
display: inline-flex; min-width: 20px; height: 20px; padding: 0 6px;
|
||||
align-items: center; justify-content: center; border-radius: 999px;
|
||||
background: #f87171; color: #fff; font-size: 12px; font-weight: 700;
|
||||
}
|
||||
.chat-layout { display: grid; grid-template-columns: 280px 1fr; gap: 14px; min-height: 480px; }
|
||||
@media (max-width: 760px) { .chat-layout { grid-template-columns: 1fr; } }
|
||||
.chat-list { border: 1px solid rgba(255,255,255,0.1); border-radius: 12px; overflow-y: auto; max-height: 560px; }
|
||||
.chat-list-item { padding: 12px 14px; border-bottom: 1px solid rgba(255,255,255,0.07); cursor: pointer; }
|
||||
.chat-list-item:hover { background: rgba(255,255,255,0.05); }
|
||||
.chat-list-item.active { background: rgba(94,234,212,0.1); }
|
||||
.chat-list-item .last { font-size: 12px; opacity: 0.6; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
||||
.chat-thread { display: flex; flex-direction: column; border: 1px solid rgba(255,255,255,0.1); border-radius: 12px; padding: 12px; }
|
||||
.chat-messages { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 10px; padding: 4px; max-height: 440px; }
|
||||
.chat-bubble { max-width: 78%; padding: 10px 14px; border-radius: 16px; font-size: 14px; white-space: pre-wrap; word-break: break-word; }
|
||||
.chat-bubble .chat-meta { display: block; font-size: 11px; opacity: 0.6; margin-top: 4px; }
|
||||
.chat-bubble.mine { align-self: flex-end; background: rgba(94,234,212,0.18); border: 1px solid rgba(94,234,212,0.45); border-bottom-right-radius: 4px; }
|
||||
.chat-bubble.theirs { align-self: flex-start; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.14); border-bottom-left-radius: 4px; }
|
||||
.chat-input-row { display: flex; gap: 10px; margin-top: 12px; align-items: flex-end; }
|
||||
.chat-input-row textarea {
|
||||
flex: 1; resize: none; min-height: 44px; max-height: 120px; padding: 10px 12px;
|
||||
border-radius: 12px; border: 1px solid rgba(255,255,255,0.18);
|
||||
background: rgba(255,255,255,0.06); color: inherit; font: inherit;
|
||||
}
|
||||
.chat-empty { display: flex; align-items: center; justify-content: center; flex: 1; opacity: 0.6; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="portal-page dashboard-page">
|
||||
@@ -73,6 +100,7 @@
|
||||
<button class="admin-tab active" data-tab="overview">Übersicht</button>
|
||||
<button class="admin-tab" data-tab="projects">Projekte</button>
|
||||
<button class="admin-tab" data-tab="customers">Kunden</button>
|
||||
<button class="admin-tab" data-tab="chat">Chat <span id="admin-chat-badge" class="badge-pill hidden"></span></button>
|
||||
</div>
|
||||
|
||||
<!-- Übersicht -->
|
||||
@@ -119,6 +147,18 @@
|
||||
</div>
|
||||
<p class="admin-note">Kundennummer direkt im Feld ändern und mit ✓ speichern. „Als Kunde ansehen“ zeigt dir das Portal genau so, wie der Kunde es sieht.</p>
|
||||
</section>
|
||||
|
||||
<!-- Chat -->
|
||||
<section class="admin-section" id="tab-chat">
|
||||
<div class="chat-layout">
|
||||
<div class="chat-list" id="admin-chat-list">
|
||||
<div class="chat-list-item"><span class="muted">Lade Unterhaltungen…</span></div>
|
||||
</div>
|
||||
<div class="chat-thread" id="admin-chat-thread">
|
||||
<div class="chat-empty">Unterhaltung links auswählen</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<script src="/admin.js"></script>
|
||||
|
||||
Reference in New Issue
Block a user