2026-03-09 16:10:24 +03:00

209 lines
9.0 KiB
HTML

{% load i18n %}
{% load hospital_filters %}
<section class="bg-white rounded-2xl p-6 shadow-sm border border-slate-100">
<h3 class="text-xl font-bold text-navy mb-6 flex items-center gap-2">
<i data-lucide="bot" class="w-6 h-6"></i> {% trans "AI Analysis" %}
</h3>
{% if complaint.emotion %}
<div class="bg-gradient-to-r from-light to-blue-50 border border-blue-200 rounded-2xl p-6 mb-6">
<h4 class="font-bold text-navy mb-4 flex items-center gap-2">
<i data-lucide="cpu" class="w-5 h-5"></i> {% trans "Emotion Analysis" %}
</h4>
<div class="flex items-center justify-between mb-4">
<span class="px-4 py-2 bg-navy text-white rounded-xl font-bold flex items-center gap-2">
<i data-lucide="frown" class="w-5 h-5"></i> {{ complaint.get_emotion_display }}
</span>
<span class="text-slate">{% trans "Confidence" %}: {{ complaint.emotion_confidence_percent|floatformat:0 }}%</span>
</div>
<div>
<div class="flex justify-between text-sm mb-1">
<span class="text-slate">{% trans "Intensity" %}</span>
<span class="font-semibold">{{ complaint.emotion_intensity|floatformat:2 }} / 1.0</span>
</div>
<div class="h-2 bg-slate-200 rounded-full overflow-hidden">
<div class="h-full bg-gradient-to-r from-navy to-blue rounded-full" style="width: {{ complaint.emotion_intensity_percent }}%"></div>
</div>
</div>
</div>
{% endif %}
{% if complaint.short_description_en %}
<div class="bg-light/50 border border-slate-200 rounded-2xl p-6 mb-6">
<h4 class="font-bold text-navy mb-3">{% trans "AI Summary (English)" %}</h4>
<p class="text-slate">{{ complaint.short_description_en }}</p>
</div>
{% endif %}
{% if complaint.short_description_ar %}
<div class="bg-light/50 border border-slate-200 rounded-2xl p-6 mb-6">
<h4 class="font-bold text-navy mb-3">{% trans "AI Summary (Arabic)" %}</h4>
<p class="text-slate" dir="rtl">{{ complaint.short_description_ar }}</p>
</div>
{% endif %}
{% if complaint.suggested_actions %}
<div class="space-y-4">
<h4 class="font-bold text-navy flex items-center gap-2">
<i data-lucide="lightbulb" class="w-5 h-5 text-blue-600"></i>
{% trans "Suggested Actions" %}
</h4>
{% for action in complaint.suggested_actions %}
<div class="bg-blue-50 border border-blue-200 rounded-xl p-4">
<div class="flex items-start justify-between gap-4">
<div class="flex-1">
<div class="flex items-center gap-2 mb-2 flex-wrap">
<span class="px-2 py-1
{% if action.priority == 'high' %}bg-red-100 text-red-700
{% elif action.priority == 'medium' %}bg-orange-100 text-orange-700
{% else %}bg-green-100 text-green-700{% endif %}
rounded-lg text-xs font-bold uppercase">
<i data-lucide="flag" class="w-3 h-3 inline mr-1"></i>
{{ action.priority }}
</span>
<span class="px-2 py-1 bg-blue-100 text-blue-700 rounded-lg text-xs font-bold">
<i data-lucide="folder" class="w-3 h-3 inline mr-1"></i>
{{ action.category|replace:"_: "|title }}
</span>
</div>
<p class="text-slate font-medium">{{ action.action_en }}</p>
{% if action.action_ar %}
<p class="text-slate text-sm mt-2" dir="rtl">{{ action.action_ar }}</p>
{% endif %}
</div>
{% if user.is_px_admin or user.is_hospital_admin %}
<button onclick="createAction('{{ action.action_en|escapejs }}', '{{ action.priority }}', '{{ action.category }}')"
class="inline-flex items-center gap-2 px-4 py-2 bg-gradient-to-r from-blue to-navy text-white rounded-lg font-semibold hover:from-navy hover:to-blue transition text-sm shadow-lg shadow-blue-200 whitespace-nowrap">
<i data-lucide="plus-circle" class="w-4 h-4"></i>
{% trans "Create Action" %}
</button>
{% endif %}
</div>
</div>
{% endfor %}
</div>
{% elif complaint.suggested_action_en %}
<!-- Fallback for old single-action format -->
<div class="bg-blue-50 border border-blue-200 rounded-2xl p-6">
<div class="flex items-start justify-between gap-4 mb-3">
<h4 class="font-bold text-navy flex items-center gap-2">
<i data-lucide="lightbulb" class="w-5 h-5 text-blue-600"></i>
{% trans "Suggested Action" %}
</h4>
{% if user.is_px_admin or user.is_hospital_admin %}
<button onclick="createAction('{{ complaint.suggested_action_en|escapejs }}', 'medium', 'process_improvement')"
class="inline-flex items-center gap-2 px-4 py-2 bg-gradient-to-r from-blue to-navy text-white rounded-lg font-semibold hover:from-navy hover:to-blue transition text-sm shadow-lg shadow-blue-200">
<i data-lucide="plus-circle" class="w-4 h-4"></i>
{% trans "Create Action" %}
</button>
{% endif %}
</div>
<p class="text-slate">{{ complaint.suggested_action_en }}</p>
</div>
{% endif %}
{% if not complaint.emotion and not complaint.short_description_en and not complaint.suggested_actions %}
<div class="text-center py-12">
<i data-lucide="bot" class="w-16 h-16 mx-auto text-slate-300 mb-4"></i>
<p class="text-slate">{% trans "No AI analysis available for this complaint" %}</p>
</div>
{% endif %}
</section>
<script>
function createAction(actionText, priority, category) {
// Show confirmation
if (!confirm('{% trans "Are you sure you want to create a PX Action from this suggestion?" %}')) {
return;
}
// Get CSRF token from meta tag (more reliable)
function getCSRFToken() {
const metaTag = document.querySelector('[name=csrfmiddlewaretoken]');
if (metaTag) {
return metaTag.value;
}
// Fallback to cookie
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
// Create action via AJAX
const csrftoken = getCSRFToken();
if (!csrftoken) {
showAlert('error', '{% trans "CSRF token not found. Please refresh the page." %}');
return;
}
fetch('{% url "actions:action_create_from_ai" complaint.id %}', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': csrftoken,
},
body: new URLSearchParams({
'csrfmiddlewaretoken': csrftoken,
'action': actionText,
'priority': priority,
'category': category
})
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Show success message
showAlert('success', '{% trans "PX Action created successfully!" %}');
// Reload page after short delay to show new action
setTimeout(() => {
window.location.reload();
}, 1500);
} else {
// Show error
showAlert('error', data.error || '{% trans "Failed to create action" %}');
}
})
.catch(error => {
console.error('Error:', error);
showAlert('error', '{% trans "An error occurred while creating the action" %}');
});
}
function showAlert(type, message) {
const alert = document.createElement('div');
const bgColor = type === 'success' ? 'bg-emerald-500' : 'bg-red-500';
const icon = type === 'success' ? 'check-circle' : 'alert-circle';
alert.className = `${bgColor} text-white px-6 py-4 rounded-xl shadow-xl z-50 flex items-center gap-3 fixed top-4 right-4`;
alert.innerHTML = `
<i data-lucide="${icon}" class="w-5 h-5"></i>
<span class="font-semibold">${message}</span>
<button type="button" onclick="this.parentElement.remove()" class="text-white/80 hover:text-white">
<i data-lucide="x" class="w-4 h-4"></i>
</button>
`;
document.body.appendChild(alert);
lucide.createIcons();
setTimeout(() => {
alert.remove();
}, 5000);
}
</script>