KI-Chat: Markdown-Rendering, Left-Alignment, kompaktere UI, "Neuer Chat" fix

- Markdown-Renderer (Headings/Listen/**bold*/*italic*/`code`/Links) für
  Assistenten-Antworten; HTML wird vorher escaped (keine Injektion).
- Antworten explizit linksbündig, Inhalt getrimmt (keine Leerzeilen oben/unten).
- Initiale Nachrichten als JSON-Blob, einheitlich via chat.js gerendert.
- Chat-Container kompakter (Höhe/Spacing reduziert).
- "Neuer Chat" setzt clientseitig auf leeren Zustand zurück (vorher lud der
  Button nur den letzten Thread neu).

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-07 14:28:54 +00:00
co-authored by Claude
parent c389d3d5ec
commit cc397e8f71
2 changed files with 149 additions and 50 deletions
+25 -23
View File
@@ -3,25 +3,41 @@
<head>
<%- include('partials/head') %>
<style>
.chat-msg { white-space: pre-wrap; word-break: break-word; }
#chatLog::-webkit-scrollbar { width: 8px; }
#chatLog::-webkit-scrollbar-thumb { background: rgba(120,120,120,.4); border-radius: 4px; }
.typing-dot { width: 6px; height: 6px; border-radius: 9999px; background: currentColor; display: inline-block; }
/* Markdown rendering inside assistant bubbles */
.chat-md { line-height: 1.5; }
.chat-md > *:first-child { margin-top: 0; }
.chat-md > *:last-child { margin-bottom: 0; }
.chat-md p { margin: 0 0 0.5rem 0; }
.chat-md h1, .chat-md h2, .chat-md h3 { font-weight: 600; margin: 0.6rem 0 0.3rem 0; line-height: 1.25; }
.chat-md h1 { font-size: 1.05rem; }
.chat-md h2 { font-size: 1rem; }
.chat-md h3 { font-size: 0.95rem; }
.chat-md ul, .chat-md ol { margin: 0 0 0.5rem 0; padding-left: 1.25rem; }
.chat-md li { margin: 0.15rem 0; }
.chat-md code { background: rgba(0,0,0,0.08); padding: 0.1rem 0.3rem; border-radius: 4px; font-size: 0.85em; }
.dark .chat-md code { background: rgba(255,255,255,0.12); }
.chat-md pre { background: rgba(0,0,0,0.08); padding: 0.6rem; border-radius: 6px; overflow-x: auto; margin: 0 0 0.5rem 0; }
.dark .chat-md pre { background: rgba(0,0,0,0.35); }
.chat-md pre code { background: none; padding: 0; }
.chat-md a { text-decoration: underline; }
</style>
</head>
<body class="min-h-screen flex flex-col transition-colors duration-300 bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100" id="body">
<%- include('partials/header', { hideSettings: true }) %>
<main class="container mx-auto px-4 py-6">
<div class="flex items-center justify-between mb-4">
<h2 class="text-2xl font-bold text-gray-800 dark:text-white">KI-Bewerbungs-Assistent</h2>
<main class="container mx-auto px-4 py-4">
<div class="flex items-center justify-between mb-3">
<h2 class="text-xl font-bold text-gray-800 dark:text-white">KI-Bewerbungs-Assistent</h2>
<button id="newThreadBtn"
class="px-3 py-1.5 rounded-md bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium">
+ Neuer Chat
</button>
</div>
<div class="grid grid-cols-1 md:grid-cols-[260px_1fr] gap-4 h-[calc(100vh-220px)] min-h-[420px]">
<div class="grid grid-cols-1 md:grid-cols-[240px_1fr] gap-3 h-[calc(100vh-180px)] min-h-[360px]">
<!-- Thread sidebar -->
<aside class="rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 overflow-hidden flex flex-col">
<div class="px-3 py-2 text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-gray-400 border-b border-gray-200 dark:border-gray-700">Verläufe</div>
@@ -45,25 +61,10 @@
<!-- Message area -->
<section class="rounded-lg border border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-800 flex flex-col overflow-hidden">
<div id="chatLog" class="flex-1 overflow-y-auto p-4 space-y-3 text-gray-800 dark:text-gray-100">
<% if (!activeId) { %>
<div class="h-full flex items-center justify-center text-gray-400 text-sm text-center px-6">
Starte einen neuen Chat, um deinen Bewerbungs-Assistenten zu fragen.
<% if (!messages.length) { %>
<div class="h-full flex items-center justify-center text-gray-400 text-sm px-6">
Stelle eine Frage zu deinen Bewerbungen.
</div>
<% } else if (!messages.length) { %>
<div class="h-full flex items-center justify-center text-gray-400 text-sm text-center px-6">
Stelle die erste Frage zu deinen Bewerbungen.
</div>
<% } else { %>
<% messages.forEach(function(m) { %>
<div class="flex <%= m.role === 'user' ? 'justify-end' : 'justify-start' %>">
<div class="max-w-[80%] rounded-lg px-3 py-2 text-sm chat-msg
<%= m.role === 'user'
? 'bg-blue-600 text-white'
: 'bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-100' %>">
<%= m.content %>
</div>
</div>
<% }); %>
<% } %>
</div>
@@ -79,6 +80,7 @@
</div>
</main>
<script id="initialMessages" type="application/json"><%= JSON.stringify(messages.map(function(m){ return { role: m.role, content: m.content }; })) %></script>
<input type="hidden" id="activeThread" value="<%= activeId || '' %>">
<script>