rsnarsna
fifth commit
bccb680
Raw
History Blame Contribute Delete
6.51 kB
{% extends "layouts/dashboard.html" %}
{% block title %}Chat: {{ session.title }}{% endblock %}
{% block dashboard_content %}
{# ─── Chat Container ─────────────────────────────────────────────── #}
<div class="flex flex-col h-[calc(100vh-12rem)]">
{# ─── Chat Header ──────────────────────────────────────────────── #}
<div class="flex items-center justify-between pb-4 border-b border-[--border] mb-4">
<div class="flex items-center gap-3">
<a href="{{ url('intelligence:chat-sessions') }}" class="p-2 rounded-lg text-[--muted-foreground] hover:bg-[--muted] hover:text-[--foreground] transition-colors">
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7"/></svg>
</a>
<div>
<h2 class="text-lg font-bold text-[--foreground]">{{ session.title or 'Chat' }}</h2>
<p class="text-xs text-[--muted-foreground]">
Started {{ session.created_at|date("M d, Y H:i") }}
{% if session.model %} Β· {{ session.model.name }}{% endif %}
</p>
</div>
</div>
<a href="{{ url('intelligence:chat-start') }}" class="inline-flex items-center gap-1.5 rounded-lg px-3 py-2 text-xs font-medium text-[--muted-foreground] border border-[--border] hover:bg-[--muted] hover:text-[--foreground] transition-colors">
<svg class="h-3.5 w-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
New Chat
</a>
</div>
{# ─── Messages Area ────────────────────────────────────────────── #}
<div id="chat-messages" class="flex-1 overflow-y-auto space-y-4 pr-2 scroll-smooth">
{% if messages %}
{% for msg in messages %}
{% if msg.role == 'user' %}
<div class="flex justify-end">
<div class="max-w-[70%] rounded-2xl rounded-tr-md bg-[--primary] px-4 py-3 text-sm text-[--primary-foreground] shadow-sm">
{{ msg.content }}
</div>
</div>
{% elif msg.role == 'assistant' %}
<div class="flex justify-start">
<div class="flex gap-3 max-w-[70%]">
<div class="flex-shrink-0 mt-1">
<div class="h-7 w-7 rounded-lg bg-gradient-to-br from-purple-500 to-indigo-600 flex items-center justify-center shadow-sm">
<svg class="h-4 w-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/></svg>
</div>
</div>
<div class="rounded-2xl rounded-tl-md bg-[--card] border border-[--border] px-4 py-3 text-sm text-[--foreground] shadow-sm">
{{ msg.content }}
</div>
</div>
</div>
{% elif msg.role == 'system' %}
<div class="flex justify-center">
<span class="text-xs text-[--muted-foreground] bg-[--muted]/30 px-3 py-1 rounded-full">{{ msg.content }}</span>
</div>
{% endif %}
{% endfor %}
{% else %}
<div class="flex flex-col items-center justify-center h-full text-center">
<div class="h-16 w-16 rounded-2xl bg-gradient-to-br from-purple-500 to-indigo-600 flex items-center justify-center shadow-xl shadow-purple-500/20 mb-6">
<svg class="h-8 w-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"/></svg>
</div>
<p class="text-lg font-semibold text-[--foreground] mb-1">Start the conversation</p>
<p class="text-sm text-[--muted-foreground]">Type a message below to chat with the AI assistant.</p>
</div>
{% endif %}
</div>
{# ─── Input Area ───────────────────────────────────────────────── #}
<div class="pt-4 border-t border-[--border] mt-4">
<form hx-post="{{ url('intelligence:chat-message-create', session_id=session.pk) }}"
hx-target="#chat-messages"
hx-swap="beforeend scroll:#chat-messages:bottom"
class="flex items-end gap-3">
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<div class="flex-1">
<textarea id="chat-input" name="content" rows="1" required
placeholder="Type a message..."
class="block w-full resize-none rounded-xl bg-[--card] px-4 py-3 text-sm text-[--foreground] border border-[--border] placeholder:text-[--muted-foreground] focus:outline-none focus:ring-2 focus:ring-[--primary]/50 focus:border-[--primary]/50"
onkeydown="if(event.key==='Enter'&&!event.shiftKey){event.preventDefault();this.form.requestSubmit()}"
oninput="this.style.height='auto';this.style.height=this.scrollHeight+'px'"></textarea>
</div>
<button type="submit" class="flex-shrink-0 inline-flex items-center justify-center h-11 w-11 rounded-xl bg-[--primary] text-[--primary-foreground] shadow-sm hover:bg-[--primary]/90 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[--primary]">
<svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"/></svg>
</button>
</form>
</div>
</div>
<script>
// Auto-scroll to bottom on page load
(function() {
const el = document.getElementById('chat-messages');
if (el) el.scrollTop = el.scrollHeight;
})();
// Clear input after HTMX request
document.body.addEventListener('htmx:afterRequest', function(e) {
const input = document.getElementById('chat-input');
if (input) { input.value = ''; input.style.height = 'auto'; }
});
</script>
{% endblock %}