243 lines
8.5 KiB
HTML
243 lines
8.5 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}Chat Dashboard - Kasico{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<link rel="stylesheet" href="{% static 'css/chat-dashboard.css' %}">
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="chat-dashboard">
|
|
<!-- Header -->
|
|
<div class="dashboard-header">
|
|
<div class="dashboard-title">
|
|
<h1><i class="fas fa-comments"></i> Chat Dashboard</h1>
|
|
<p>Live-Support Management</p>
|
|
</div>
|
|
<div class="dashboard-stats">
|
|
<div class="stat-card">
|
|
<div class="stat-icon">
|
|
<i class="fas fa-users"></i>
|
|
</div>
|
|
<div class="stat-content">
|
|
<h3>{{ total_rooms }}</h3>
|
|
<p>Gesamt Chats</p>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card active">
|
|
<div class="stat-icon">
|
|
<i class="fas fa-comment-dots"></i>
|
|
</div>
|
|
<div class="stat-content">
|
|
<h3>{{ active_rooms }}</h3>
|
|
<p>Aktive Chats</p>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card waiting">
|
|
<div class="stat-icon">
|
|
<i class="fas fa-clock"></i>
|
|
</div>
|
|
<div class="stat-content">
|
|
<h3>{{ waiting_rooms }}</h3>
|
|
<p>Wartend</p>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card messages">
|
|
<div class="stat-icon">
|
|
<i class="fas fa-envelope"></i>
|
|
</div>
|
|
<div class="stat-content">
|
|
<h3>{{ today_messages }}</h3>
|
|
<p>Heute</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions -->
|
|
<div class="quick-actions">
|
|
<a href="{% url 'chat:room_list' %}" class="action-btn">
|
|
<i class="fas fa-list"></i>
|
|
Alle Chats
|
|
</a>
|
|
<a href="{% url 'chat:quick_response_list' %}" class="action-btn">
|
|
<i class="fas fa-reply"></i>
|
|
Quick Responses
|
|
</a>
|
|
<a href="{% url 'chat:analytics' %}" class="action-btn">
|
|
<i class="fas fa-chart-bar"></i>
|
|
Analytics
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Recent Chats -->
|
|
<div class="dashboard-section">
|
|
<div class="section-header">
|
|
<h2><i class="fas fa-history"></i> Letzte Chats</h2>
|
|
<a href="{% url 'chat:room_list' %}" class="view-all">Alle anzeigen</a>
|
|
</div>
|
|
|
|
<div class="chat-list">
|
|
{% for room in recent_rooms %}
|
|
<div class="chat-item {% if room.status == 'waiting' %}waiting{% elif room.status == 'active' %}active{% else %}closed{% endif %}">
|
|
<div class="chat-item-avatar">
|
|
<img src="{% static 'images/dog-user-icon.svg' %}" alt="User">
|
|
<div class="status-indicator {{ room.status }}"></div>
|
|
</div>
|
|
<div class="chat-item-content">
|
|
<div class="chat-item-header">
|
|
<h4>{{ room.customer.username }}</h4>
|
|
<span class="chat-time">{{ room.last_message_at|timesince }} ago</span>
|
|
</div>
|
|
<p class="chat-subject">{{ room.subject|default:"Kein Betreff" }}</p>
|
|
<div class="chat-meta">
|
|
<span class="chat-status-badge {{ room.status }}">
|
|
{{ room.get_status_display }}
|
|
</span>
|
|
{% if room.admin %}
|
|
<span class="assigned-admin">
|
|
<i class="fas fa-user-shield"></i>
|
|
{{ room.admin.username }}
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="chat-item-actions">
|
|
<a href="{% url 'chat:room_detail' room.id %}" class="btn btn-primary btn-sm">
|
|
<i class="fas fa-eye"></i>
|
|
Öffnen
|
|
</a>
|
|
</div>
|
|
</div>
|
|
{% empty %}
|
|
<div class="empty-state">
|
|
<i class="fas fa-comments"></i>
|
|
<h3>Keine Chats vorhanden</h3>
|
|
<p>Es sind noch keine Chat-Anfragen eingegangen.</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Responses -->
|
|
<div class="dashboard-section">
|
|
<div class="section-header">
|
|
<h2><i class="fas fa-reply"></i> Quick Responses</h2>
|
|
<a href="{% url 'chat:quick_response_list' %}" class="view-all">Verwalten</a>
|
|
</div>
|
|
|
|
<div class="quick-response-grid">
|
|
{% for response in quick_responses %}
|
|
<div class="quick-response-card">
|
|
<div class="response-header">
|
|
<span class="response-category">{{ response.get_category_display }}</span>
|
|
<span class="response-count">{{ response.use_count }}x</span>
|
|
</div>
|
|
<h4>{{ response.title }}</h4>
|
|
<p>{{ response.content|truncatewords:20 }}</p>
|
|
<button class="btn btn-outline-primary btn-sm copy-response" data-content="{{ response.content }}">
|
|
<i class="fas fa-copy"></i>
|
|
Kopieren
|
|
</button>
|
|
</div>
|
|
{% empty %}
|
|
<div class="empty-state">
|
|
<i class="fas fa-reply"></i>
|
|
<h3>Keine Quick Responses</h3>
|
|
<p>Erstelle Quick Responses für häufige Fragen.</p>
|
|
<a href="{% url 'chat:quick_response_list' %}" class="btn btn-primary">
|
|
Erste erstellen
|
|
</a>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Online Status -->
|
|
<div class="dashboard-section">
|
|
<div class="section-header">
|
|
<h2><i class="fas fa-circle"></i> Online Status</h2>
|
|
</div>
|
|
|
|
<div class="online-status">
|
|
<div class="status-item">
|
|
<div class="status-indicator online"></div>
|
|
<span>Online Admins: {{ online_admins }}</span>
|
|
</div>
|
|
<div class="status-item">
|
|
<div class="status-indicator offline"></div>
|
|
<span>Offline</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script>
|
|
// Quick Response Copy
|
|
document.querySelectorAll('.copy-response').forEach(button => {
|
|
button.addEventListener('click', function() {
|
|
const content = this.dataset.content;
|
|
navigator.clipboard.writeText(content).then(() => {
|
|
// Success feedback
|
|
const originalText = this.innerHTML;
|
|
this.innerHTML = '<i class="fas fa-check"></i> Kopiert!';
|
|
this.classList.add('btn-success');
|
|
|
|
setTimeout(() => {
|
|
this.innerHTML = originalText;
|
|
this.classList.remove('btn-success');
|
|
}, 2000);
|
|
});
|
|
});
|
|
});
|
|
|
|
// Real-time updates (WebSocket)
|
|
if (typeof WebSocket !== 'undefined') {
|
|
const ws = new WebSocket(`ws://${window.location.host}/ws/notifications/`);
|
|
|
|
ws.onmessage = function(event) {
|
|
const data = JSON.parse(event.data);
|
|
if (data.type === 'notification') {
|
|
// Show notification
|
|
showNotification(data.notification);
|
|
}
|
|
};
|
|
}
|
|
|
|
function showNotification(notification) {
|
|
// Browser notification
|
|
if ('Notification' in window && Notification.permission === 'granted') {
|
|
new Notification(notification.title, {
|
|
body: notification.message,
|
|
icon: '/static/images/kasico-logo.png'
|
|
});
|
|
}
|
|
|
|
// Toast notification
|
|
const toast = document.createElement('div');
|
|
toast.className = 'toast-notification';
|
|
toast.innerHTML = `
|
|
<div class="toast-header">
|
|
<strong>${notification.title}</strong>
|
|
<button type="button" class="toast-close">×</button>
|
|
</div>
|
|
<div class="toast-body">${notification.message}</div>
|
|
`;
|
|
|
|
document.body.appendChild(toast);
|
|
|
|
// Auto remove after 5 seconds
|
|
setTimeout(() => {
|
|
toast.remove();
|
|
}, 5000);
|
|
|
|
// Close button
|
|
toast.querySelector('.toast-close').addEventListener('click', () => {
|
|
toast.remove();
|
|
});
|
|
}
|
|
</script>
|
|
{% endblock %} |