|
{% extends "base.html" %} |
|
|
|
{% block title %}Conversation History - PatChat{% endblock %} |
|
|
|
{% block content %} |
|
<div class="row"> |
|
<div class="col-12"> |
|
<div class="d-flex justify-content-between align-items-center mb-4"> |
|
<h2> |
|
<i class="bi bi-clock-history"></i> Conversation History |
|
</h2> |
|
<a href="{{ url_for('index') }}" class="btn btn-primary"> |
|
<i class="bi bi-plus-circle"></i> New Chat |
|
</a> |
|
</div> |
|
|
|
{% if conversations %} |
|
<div class="row"> |
|
{% for conversation in conversations %} |
|
<div class="col-md-6 col-lg-4 mb-3"> |
|
<div class="card conversation-item h-100"> |
|
<div class="card-body"> |
|
<div class="d-flex justify-content-between align-items-start mb-2"> |
|
<h6 class="card-title mb-0">{{ conversation.title }}</h6> |
|
<div class="dropdown"> |
|
<button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-label="Conversation options"> |
|
<i class="bi bi-three-dots"></i> |
|
</button> |
|
<ul class="dropdown-menu"> |
|
<li><a class="dropdown-item" href="{{ url_for('view_conversation', conversation_id=conversation.id) }}"> |
|
<i class="bi bi-eye"></i> View |
|
</a></li> |
|
<li><hr class="dropdown-divider"></li> |
|
<li><a class="dropdown-item text-danger delete-conversation" href="#" data-id="{{ conversation.id }}"> |
|
<i class="bi bi-trash"></i> Delete |
|
</a></li> |
|
</ul> |
|
</div> |
|
</div> |
|
|
|
<p class="card-text small text-muted mb-2"> |
|
<i class="bi bi-robot"></i> {{ conversation.model_type }} |
|
</p> |
|
|
|
<p class="card-text small text-muted mb-2"> |
|
<i class="bi bi-chat"></i> {{ conversation.messages|length }} messages |
|
</p> |
|
|
|
<p class="card-text small text-muted"> |
|
<i class="bi bi-calendar"></i> {{ conversation.updated_at.strftime('%Y-%m-%d %H:%M') }} |
|
</p> |
|
</div> |
|
|
|
<div class="card-footer bg-transparent"> |
|
<a href="{{ url_for('view_conversation', conversation_id=conversation.id) }}" class="btn btn-primary btn-sm w-100"> |
|
<i class="bi bi-chat"></i> Continue Chat |
|
</a> |
|
</div> |
|
</div> |
|
</div> |
|
{% endfor %} |
|
</div> |
|
{% else %} |
|
<div class="text-center py-5"> |
|
<i class="bi bi-chat-dots text-muted" style="font-size: 4rem;"></i> |
|
<h4 class="mt-3 text-muted">No conversations yet</h4> |
|
<p class="text-muted">Start your first conversation with AI</p> |
|
<a href="{{ url_for('index') }}" class="btn btn-primary"> |
|
<i class="bi bi-plus-circle"></i> Start Chatting |
|
</a> |
|
</div> |
|
{% endif %} |
|
</div> |
|
</div> |
|
{% endblock %} |
|
|
|
{% block extra_js %} |
|
<script> |
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
const deleteButtons = document.querySelectorAll('.delete-conversation'); |
|
|
|
deleteButtons.forEach(button => { |
|
button.addEventListener('click', async function(e) { |
|
e.preventDefault(); |
|
|
|
const conversationId = this.getAttribute('data-id'); |
|
|
|
if (confirm('Are you sure you want to delete this conversation? This action cannot be undone.')) { |
|
try { |
|
const response = await fetch(`/conversation/${conversationId}`, { |
|
method: 'DELETE', |
|
headers: { |
|
'Content-Type': 'application/json', |
|
} |
|
}); |
|
|
|
const data = await response.json(); |
|
|
|
if (data.success) { |
|
|
|
const card = this.closest('.col-md-6'); |
|
card.remove(); |
|
|
|
|
|
showAlert('Conversation deleted successfully', 'success'); |
|
} else { |
|
throw new Error(data.error || 'Failed to delete conversation'); |
|
} |
|
} catch (error) { |
|
console.error('Error:', error); |
|
showAlert('Failed to delete conversation. Please try again.', 'danger'); |
|
} |
|
} |
|
}); |
|
}); |
|
}); |
|
|
|
|
|
function showAlert(message, type) { |
|
const alertDiv = document.createElement('div'); |
|
alertDiv.className = `alert alert-${type} alert-dismissible fade show`; |
|
alertDiv.innerHTML = ` |
|
${message} |
|
<button type="button" class="btn-close" data-bs-dismiss="alert"></button> |
|
`; |
|
|
|
|
|
const main = document.querySelector('main'); |
|
main.insertBefore(alertDiv, main.firstChild); |
|
|
|
|
|
setTimeout(() => { |
|
if (alertDiv.parentNode) { |
|
alertDiv.remove(); |
|
} |
|
}, 5000); |
|
} |
|
</script> |
|
{% endblock %} |