mirror of
https://github.com/thecyberlearn/quantum-ai.git
synced 2026-08-18 10:52:58 +00:00
- Remove duplicate updateWalletBalance and showToast functions from individual agents - Standardize all agents to use AgentUtils.functionName() pattern consistently - Update Five Whys Analyzer to use shared utility functions - Maintain agent-specific functions only where necessary for unique workflows - Ensure consistent function call patterns across Data Analyzer, Job Posting Generator, and Five Whys Analyzer 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
633 lines
26 KiB
HTML
633 lines
26 KiB
HTML
{% extends "base.html" %}
|
|
{% csrf_token %}
|
|
|
|
{% block title %}5 Whys Analysis Agent - NetCop AI Hub{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container" style="max-width: 1280px; margin: 0 auto; padding: clamp(20px, 5vw, 40px) clamp(16px, 4vw, 24px);">
|
|
<!-- Main Content Grid -->
|
|
<div class="main-grid" style="display: grid; grid-template-columns: repeat(auto-fit, minmax(min(350px, 100%), 1fr)); gap: clamp(16px, 4vw, 24px); align-items: start;">
|
|
<!-- Chat Interface -->
|
|
<div>
|
|
<!-- Agent Header -->
|
|
<div class="card" style="background: rgba(255, 255, 255, 0.9); border-radius: clamp(12px, 3vw, 16px); padding: clamp(16px, 4vw, 24px); border: 1px solid rgba(255, 255, 255, 0.3); backdrop-filter: blur(20px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); margin-bottom: clamp(16px, 4vw, 24px);">
|
|
<h1 style="font-size: clamp(20px, 5vw, 24px); font-weight: 700; color: #1f2937; margin: 0 0 8px 0; display: flex; align-items: center; gap: 12px;">
|
|
🔍 {{ agent.name }}
|
|
</h1>
|
|
<p style="font-size: clamp(14px, 3.5vw, 16px); color: #6b7280; margin: 0;">
|
|
{{ agent.description }}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Chat Messages Container -->
|
|
<div class="card" id="chatContainer" style="background: rgba(255, 255, 255, 0.9); border-radius: clamp(12px, 3vw, 16px); padding: clamp(16px, 4vw, 24px); border: 1px solid rgba(255, 255, 255, 0.3); backdrop-filter: blur(20px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); margin-bottom: clamp(16px, 4vw, 24px); min-height: 400px; max-height: 600px; overflow-y: auto;">
|
|
<h3 style="font-size: clamp(16px, 4vw, 18px); font-weight: 600; color: #1f2937; margin: 0 0 16px 0;">💬 Chat with 5 Whys Analyst</h3>
|
|
|
|
<!-- Welcome Message -->
|
|
<div class="message assistant-message" style="margin-bottom: 16px; padding: 12px 16px; background: #f8fafc; border-radius: 12px; border-left: 4px solid #6366f1;">
|
|
<div style="font-weight: 600; color: #4338ca; margin-bottom: 4px;">5 Whys Analyst</div>
|
|
<div style="color: #374151; line-height: 1.5;">
|
|
Hello! I'm here to help you with root cause analysis using the 5 Whys methodology.
|
|
|
|
You can ask me questions, describe your problem, and I'll guide you through the analysis process. When you're ready, I can generate a comprehensive report for 8.00 AED.
|
|
|
|
How can I help you today?
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Chat messages will be dynamically added here -->
|
|
<div id="chatMessages"></div>
|
|
</div>
|
|
|
|
<!-- Chat Input -->
|
|
<div class="card" style="background: rgba(255, 255, 255, 0.9); border-radius: clamp(12px, 3vw, 16px); padding: clamp(16px, 4vw, 24px); border: 1px solid rgba(255, 255, 255, 0.3); backdrop-filter: blur(20px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); margin-bottom: clamp(16px, 4vw, 24px);">
|
|
<div style="display: flex; gap: 12px; align-items: flex-end;">
|
|
<textarea
|
|
id="chatInput"
|
|
placeholder="Ask me about your problem or describe what you'd like to analyze..."
|
|
style="flex: 1; padding: 12px 16px; border: 2px solid #e5e7eb; border-radius: 12px; font-size: 14px; resize: vertical; min-height: 48px; max-height: 120px; font-family: inherit;"
|
|
rows="2"
|
|
></textarea>
|
|
<button
|
|
id="sendChatBtn"
|
|
onclick="sendChatMessage()"
|
|
style="padding: 12px 20px; background: linear-gradient(135deg, #6366f1 0%, #4338ca 100%); color: white; border: none; border-radius: 12px; font-weight: 600; cursor: pointer; min-height: 48px; transition: transform 0.1s ease;"
|
|
>
|
|
Send
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Report Generation Form -->
|
|
<div class="card" id="reportForm" style="background: rgba(255, 255, 255, 0.9); border-radius: clamp(12px, 3vw, 16px); padding: clamp(16px, 4vw, 24px); border: 1px solid rgba(255, 255, 255, 0.3); backdrop-filter: blur(20px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); margin-bottom: clamp(16px, 4vw, 24px);">
|
|
<h3 style="font-size: clamp(16px, 4vw, 18px); font-weight: 600; color: #1f2937; margin: 0 0 16px 0;">📋 Generate Final Report</h3>
|
|
|
|
<div id="reportNotReady" style="padding: 16px; background: #f3f4f6; border-radius: 12px; text-align: center; color: #6b7280; font-size: 14px; margin-bottom: 16px;">
|
|
💬 Ask 2-3 questions about your problem first, then I'll generate a comprehensive report
|
|
</div>
|
|
|
|
<div id="reportReady" style="display: none; padding: 16px; background: #ecfdf5; border-radius: 12px; text-align: center; color: #059669; font-size: 14px; margin-bottom: 16px;">
|
|
✅ Ready! I can now generate a detailed 5 Whys analysis report based on our conversation
|
|
</div>
|
|
|
|
<button
|
|
id="generateReportBtn"
|
|
onclick="generateReport()"
|
|
disabled
|
|
style="width: 100%; padding: 16px 20px; background: #9ca3af; color: white; border: none; border-radius: 12px; font-weight: 600; cursor: not-allowed; font-size: 16px; transition: all 0.3s ease;"
|
|
>
|
|
🔍 Generate Report ({{ agent.price }} AED)
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Generated Report Display -->
|
|
<div id="reportResults" class="card" style="background: rgba(255, 255, 255, 0.9); border-radius: 16px; padding: 24px; border: 1px solid rgba(255, 255, 255, 0.3); backdrop-filter: blur(20px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); margin-top: 24px; display: none;">
|
|
<div style="display: flex; align-items: center; gap: 12px; margin-bottom: 20px;">
|
|
<div style="font-size: 24px;">✅</div>
|
|
<h3 style="font-size: 20px; font-weight: 600; color: #1f2937; margin: 0;">5 Whys Analysis Report</h3>
|
|
<div style="background: #6366f1; color: white; padding: 6px 12px; border-radius: 6px; font-size: 14px; font-weight: 600; margin-left: auto;">
|
|
✅ Complete
|
|
</div>
|
|
</div>
|
|
|
|
<div id="reportContent" style="background: white; border: 1px solid #e2e8f0; border-radius: 12px; padding: 32px; margin-bottom: 20px; line-height: 1.7; color: #374151; font-size: 15px; box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.05);">
|
|
<!-- Report content will be displayed here -->
|
|
</div>
|
|
|
|
<div style="display: flex; gap: 12px; flex-wrap: wrap;">
|
|
<button onclick="copyReport()" style="padding: 12px 20px; background: linear-gradient(135deg, #6366f1 0%, #4338ca 100%); color: white; border: none; border-radius: 12px; font-weight: 600; cursor: pointer; transition: transform 0.1s ease;">
|
|
📋 Copy Report
|
|
</button>
|
|
<button onclick="downloadReport()" style="padding: 12px 20px; background: white; color: #374151; border: 2px solid #e5e7eb; border-radius: 12px; font-weight: 600; cursor: pointer; transition: transform 0.1s ease;">
|
|
💾 Download Report
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Wallet Sidebar -->
|
|
<div style="position: sticky; top: 20px;">
|
|
<div class="card" style="background: rgba(255, 255, 255, 0.9); border-radius: clamp(12px, 3vw, 16px); padding: clamp(16px, 4vw, 24px); border: 1px solid rgba(255, 255, 255, 0.3); backdrop-filter: blur(20px); box-shadow: 0 8px 25px rgba(0, 0, 0, 0.1); margin-bottom: clamp(16px, 4vw, 24px);">
|
|
<h3 style="font-size: clamp(16px, 4vw, 18px); font-weight: 600; color: #1f2937; margin: 0 0 16px 0;">💳 Your Wallet</h3>
|
|
|
|
<div style="font-size: clamp(24px, 6vw, 28px); font-weight: 700; color: #1f2937; margin-bottom: 8px;" data-wallet-balance>
|
|
{{ user.wallet_balance|floatformat:2 }} AED
|
|
</div>
|
|
<div style="font-size: clamp(14px, 3.5vw, 16px); color: #6b7280; margin-bottom: 20px;">
|
|
Available Balance
|
|
</div>
|
|
|
|
<a href="{% url 'core:wallet_topup' %}" style="display: block; width: 100%; padding: 16px 20px; background: linear-gradient(135deg, #10b981 0%, #059669 100%); color: white; border: none; border-radius: 12px; font-weight: 600; text-decoration: none; text-align: center; margin-bottom: 12px;">
|
|
💳 Top Up Wallet
|
|
</a>
|
|
</div>
|
|
|
|
<div style="padding: 16px; background: rgba(99, 102, 241, 0.1); border-radius: 12px; border: 1px solid rgba(99, 102, 241, 0.2);">
|
|
<h4 style="margin: 0 0 8px 0; font-size: 14px; font-weight: 600; color: #4338ca;">💡 How it works</h4>
|
|
<ul style="margin: 0; font-size: 12px; color: #374151; line-height: 1.4; list-style: none; padding-left: 0;">
|
|
<li style="margin: 4px 0; padding-left: 16px; position: relative;">
|
|
<span style="position: absolute; left: 0; color: #6366f1;">•</span>
|
|
Chat freely to explore your problem
|
|
</li>
|
|
<li style="margin: 4px 0; padding-left: 16px; position: relative;">
|
|
<span style="position: absolute; left: 0; color: #6366f1;">•</span>
|
|
Get guidance and ask questions
|
|
</li>
|
|
<li style="margin: 4px 0; padding-left: 16px; position: relative;">
|
|
<span style="position: absolute; left: 0; color: #6366f1;">•</span>
|
|
Generate final report when ready
|
|
</li>
|
|
<li style="margin: 4px 0; padding-left: 16px; position: relative;">
|
|
<span style="position: absolute; left: 0; color: #6366f1;">•</span>
|
|
Pay only for the final report
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
.container {
|
|
background: linear-gradient(135deg, #f6f8ff 0%, #e8f0fe 50%, #f0f7ff 100%);
|
|
min-height: 100vh;
|
|
color: #1f2937;
|
|
}
|
|
|
|
.card:hover {
|
|
transform: translateY(-1px);
|
|
transition: transform 0.2s ease;
|
|
}
|
|
|
|
button:hover {
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
button:disabled {
|
|
background: #9ca3af !important;
|
|
cursor: not-allowed !important;
|
|
transform: none !important;
|
|
}
|
|
|
|
.message {
|
|
margin-bottom: 16px;
|
|
animation: fadeIn 0.3s ease;
|
|
}
|
|
|
|
.user-message {
|
|
margin-left: 20%;
|
|
padding: 12px 16px;
|
|
background: #6366f1;
|
|
color: white;
|
|
border-radius: 16px 16px 4px 16px;
|
|
}
|
|
|
|
.assistant-message {
|
|
margin-right: 20%;
|
|
padding: 16px 20px;
|
|
background: #f8fafc;
|
|
border-radius: 16px 16px 16px 4px;
|
|
border-left: 4px solid #6366f1;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.assistant-message .message-content {
|
|
color: #374151;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.assistant-message .message-content h3 {
|
|
color: #1f2937;
|
|
font-size: 16px;
|
|
font-weight: 600;
|
|
margin: 16px 0 8px 0;
|
|
}
|
|
|
|
.assistant-message .message-content h3:first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.assistant-message .message-content ul {
|
|
margin: 8px 0;
|
|
padding-left: 20px;
|
|
}
|
|
|
|
.assistant-message .message-content li {
|
|
margin: 4px 0;
|
|
}
|
|
|
|
.assistant-message .message-content p {
|
|
margin: 8px 0;
|
|
}
|
|
|
|
.assistant-message .message-content p:first-child {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.assistant-message .message-content p:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.assistant-message .message-content strong {
|
|
color: #1f2937;
|
|
font-weight: 600;
|
|
}
|
|
|
|
@keyframes fadeIn {
|
|
from { opacity: 0; transform: translateY(10px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
.typing-dots {
|
|
display: flex;
|
|
gap: 4px;
|
|
align-items: center;
|
|
}
|
|
|
|
.typing-dots span {
|
|
width: 6px;
|
|
height: 6px;
|
|
border-radius: 50%;
|
|
background: #6366f1;
|
|
animation: typingDots 1.4s infinite ease-in-out;
|
|
}
|
|
|
|
.typing-dots span:nth-child(1) {
|
|
animation-delay: 0s;
|
|
}
|
|
|
|
.typing-dots span:nth-child(2) {
|
|
animation-delay: 0.2s;
|
|
}
|
|
|
|
.typing-dots span:nth-child(3) {
|
|
animation-delay: 0.4s;
|
|
}
|
|
|
|
@keyframes typingDots {
|
|
0%, 80%, 100% {
|
|
transform: scale(0);
|
|
opacity: 0.5;
|
|
}
|
|
40% {
|
|
transform: scale(1);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.main-grid {
|
|
grid-template-columns: 1fr !important;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
let currentSessionId = null;
|
|
let isProcessing = false;
|
|
let messageCount = 0;
|
|
|
|
// Initialize session
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Generate new session ID
|
|
currentSessionId = generateSessionId();
|
|
|
|
// Add Enter key support for chat input
|
|
document.getElementById('chatInput').addEventListener('keypress', function(e) {
|
|
if (e.key === 'Enter' && !e.shiftKey) {
|
|
e.preventDefault();
|
|
sendChatMessage();
|
|
}
|
|
});
|
|
});
|
|
|
|
function generateSessionId() {
|
|
return 'session_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
|
|
}
|
|
|
|
function sendChatMessage() {
|
|
if (isProcessing) return;
|
|
|
|
const input = document.getElementById('chatInput');
|
|
const message = input.value.trim();
|
|
|
|
if (!message) {
|
|
AgentUtils.showToast('Please enter a message', 'error');
|
|
return;
|
|
}
|
|
|
|
isProcessing = true;
|
|
document.getElementById('sendChatBtn').disabled = true;
|
|
document.getElementById('sendChatBtn').textContent = 'Sending...';
|
|
|
|
// Add user message to chat
|
|
addMessageToChat(message, 'user');
|
|
input.value = '';
|
|
messageCount++;
|
|
|
|
// Show typing indicator
|
|
showTypingIndicator();
|
|
|
|
// Send chat message to backend
|
|
fetch("{% url 'five_whys_analyzer:chat' %}", {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
session_id: currentSessionId,
|
|
message: message
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
// Hide typing indicator
|
|
hideTypingIndicator();
|
|
|
|
if (data.success) {
|
|
// Add assistant response to chat
|
|
addMessageToChat(data.response, 'assistant');
|
|
currentSessionId = data.session_id;
|
|
|
|
// Check if report button should be enabled
|
|
checkReportReadiness();
|
|
} else {
|
|
AgentUtils.showToast(data.error || 'Failed to send message', 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
// Hide typing indicator on error
|
|
hideTypingIndicator();
|
|
console.error('Error:', error);
|
|
AgentUtils.showToast('Network error occurred', 'error');
|
|
})
|
|
.finally(() => {
|
|
isProcessing = false;
|
|
document.getElementById('sendChatBtn').disabled = false;
|
|
document.getElementById('sendChatBtn').textContent = 'Send';
|
|
});
|
|
}
|
|
|
|
function addMessageToChat(message, role) {
|
|
const messagesContainer = document.getElementById('chatMessages');
|
|
const messageDiv = document.createElement('div');
|
|
|
|
if (role === 'user') {
|
|
messageDiv.className = 'message user-message';
|
|
messageDiv.innerHTML = `
|
|
<div style="font-weight: 600; margin-bottom: 4px;">You</div>
|
|
<div style="line-height: 1.5;">${escapeHtml(message)}</div>
|
|
`;
|
|
} else {
|
|
messageDiv.className = 'message assistant-message';
|
|
const formattedMessage = formatAssistantMessage(message);
|
|
messageDiv.innerHTML = `
|
|
<div style="font-weight: 600; color: #4338ca; margin-bottom: 8px;">🔍 5 Whys Analyst</div>
|
|
<div class="message-content">${formattedMessage}</div>
|
|
`;
|
|
}
|
|
|
|
messagesContainer.appendChild(messageDiv);
|
|
|
|
// Scroll to bottom
|
|
const chatContainer = document.getElementById('chatContainer');
|
|
chatContainer.scrollTop = chatContainer.scrollHeight;
|
|
}
|
|
|
|
function formatAssistantMessage(message) {
|
|
// Trim and clean up the message
|
|
let cleaned = message.trim();
|
|
|
|
// Remove excessive spacing and normalize line breaks
|
|
cleaned = cleaned.replace(/\n\s*\n\s*\n/g, '\n\n'); // Max 2 line breaks
|
|
|
|
// Escape HTML first
|
|
let formatted = escapeHtml(cleaned);
|
|
|
|
// Convert markdown-style formatting to HTML
|
|
// Convert ### headers to h3
|
|
formatted = formatted.replace(/### (.*?)(?=\n|$)/g, '<h3>$1</h3>');
|
|
|
|
// Convert ** bold ** to <strong>
|
|
formatted = formatted.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
|
|
|
|
// Convert - bullet points to proper lists
|
|
const lines = formatted.split('\n');
|
|
let inList = false;
|
|
let result = [];
|
|
|
|
for (let i = 0; i < lines.length; i++) {
|
|
const line = lines[i].trim();
|
|
|
|
if (line.startsWith('- ')) {
|
|
if (!inList) {
|
|
result.push('<ul>');
|
|
inList = true;
|
|
}
|
|
result.push(`<li>${line.substring(2)}</li>`);
|
|
} else {
|
|
if (inList) {
|
|
result.push('</ul>');
|
|
inList = false;
|
|
}
|
|
if (line) {
|
|
// Split long paragraphs for better readability
|
|
if (line.length > 200) {
|
|
const sentences = line.split('. ');
|
|
let currentParagraph = '';
|
|
for (const sentence of sentences) {
|
|
if (currentParagraph.length + sentence.length > 200 && currentParagraph) {
|
|
result.push(`<p>${currentParagraph.trim()}.</p>`);
|
|
currentParagraph = sentence;
|
|
} else {
|
|
currentParagraph += (currentParagraph ? '. ' : '') + sentence;
|
|
}
|
|
}
|
|
if (currentParagraph) {
|
|
result.push(`<p>${currentParagraph}</p>`);
|
|
}
|
|
} else {
|
|
result.push(`<p>${line}</p>`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (inList) {
|
|
result.push('</ul>');
|
|
}
|
|
|
|
return result.join('');
|
|
}
|
|
|
|
function escapeHtml(text) {
|
|
const div = document.createElement('div');
|
|
div.textContent = text;
|
|
return div.innerHTML;
|
|
}
|
|
|
|
function showTypingIndicator() {
|
|
const messagesContainer = document.getElementById('chatMessages');
|
|
const typingDiv = document.createElement('div');
|
|
typingDiv.id = 'typingIndicator';
|
|
typingDiv.className = 'message assistant-message';
|
|
typingDiv.innerHTML = `
|
|
<div style="font-weight: 600; color: #4338ca; margin-bottom: 8px;">🔍 5 Whys Analyst</div>
|
|
<div class="message-content">
|
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
<div class="typing-dots">
|
|
<span></span>
|
|
<span></span>
|
|
<span></span>
|
|
</div>
|
|
<span style="color: #6b7280; font-style: italic;">Analyzing your problem...</span>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
messagesContainer.appendChild(typingDiv);
|
|
|
|
// Scroll to bottom
|
|
const chatContainer = document.getElementById('chatContainer');
|
|
chatContainer.scrollTop = chatContainer.scrollHeight;
|
|
}
|
|
|
|
function hideTypingIndicator() {
|
|
const typingIndicator = document.getElementById('typingIndicator');
|
|
if (typingIndicator) {
|
|
typingIndicator.remove();
|
|
}
|
|
}
|
|
|
|
function checkReportReadiness() {
|
|
if (messageCount >= 2) {
|
|
// Enable report generation
|
|
document.getElementById('reportNotReady').style.display = 'none';
|
|
document.getElementById('reportReady').style.display = 'block';
|
|
|
|
const btn = document.getElementById('generateReportBtn');
|
|
btn.disabled = false;
|
|
btn.style.background = 'linear-gradient(135deg, #10b981 0%, #059669 100%)';
|
|
btn.style.cursor = 'pointer';
|
|
}
|
|
}
|
|
|
|
function generateReport() {
|
|
if (isProcessing) return;
|
|
|
|
if (!currentSessionId) {
|
|
AgentUtils.showToast('Please start a chat session first', 'error');
|
|
return;
|
|
}
|
|
|
|
if (messageCount < 2) {
|
|
AgentUtils.showToast('Please ask at least 2 questions before generating a report', 'error');
|
|
return;
|
|
}
|
|
|
|
isProcessing = true;
|
|
const btn = document.getElementById('generateReportBtn');
|
|
btn.disabled = true;
|
|
btn.textContent = '🔍 Generating Report...';
|
|
|
|
// Extract problem statement from first user message in chat
|
|
const chatMessages = document.querySelectorAll('.user-message');
|
|
let problemStatement = 'Problem analysis based on chat conversation';
|
|
if (chatMessages.length > 0) {
|
|
const firstMessage = chatMessages[0].querySelector('div:last-child');
|
|
if (firstMessage) {
|
|
problemStatement = firstMessage.textContent.trim();
|
|
}
|
|
}
|
|
|
|
// Send report generation request using chat history
|
|
fetch("{% url 'five_whys_analyzer:report' %}", {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
session_id: currentSessionId,
|
|
problem_statement: problemStatement,
|
|
context_info: 'Generated from chat conversation',
|
|
analysis_depth: 'comprehensive'
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
// Display the generated report
|
|
displayReport(data.report);
|
|
|
|
// Update wallet balance
|
|
AgentUtils.updateWalletBalance(data.wallet_balance);
|
|
|
|
AgentUtils.showToast('✅ Report generated and payment processed!', 'success');
|
|
} else {
|
|
AgentUtils.showToast(data.error || 'Failed to generate report', 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error:', error);
|
|
AgentUtils.showToast('Network error occurred', 'error');
|
|
})
|
|
.finally(() => {
|
|
isProcessing = false;
|
|
btn.disabled = false;
|
|
btn.textContent = '🔍 Generate Report ({{ agent.price }} AED)';
|
|
});
|
|
}
|
|
|
|
function displayReport(reportContent) {
|
|
const formattedReport = formatReportContent(reportContent);
|
|
document.getElementById('reportContent').innerHTML = formattedReport;
|
|
document.getElementById('reportResults').style.display = 'block';
|
|
|
|
// Scroll to report
|
|
document.getElementById('reportResults').scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
|
|
function formatReportContent(content) {
|
|
// Basic formatting for better readability
|
|
let formatted = content;
|
|
|
|
// Escape HTML first
|
|
const div = document.createElement('div');
|
|
div.textContent = formatted;
|
|
formatted = div.innerHTML;
|
|
|
|
// Format main headers
|
|
formatted = formatted.replace(/^# (.*?)$/gm, '<h1 style="font-size: 24px; font-weight: bold; margin: 20px 0 16px 0; color: #1f2937; border-bottom: 2px solid #6366f1; padding-bottom: 8px;">$1</h1>');
|
|
|
|
// Format section headers
|
|
formatted = formatted.replace(/^## (.*?)$/gm, '<h2 style="font-size: 18px; font-weight: 600; margin: 24px 0 12px 0; color: #374151;">$1</h2>');
|
|
|
|
// Format bold text
|
|
formatted = formatted.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
|
|
|
|
// Format bullet points
|
|
formatted = formatted.replace(/^- (.*?)$/gm, '<div style="margin: 6px 0; padding-left: 16px;">• $1</div>');
|
|
|
|
// Format numbered lists
|
|
formatted = formatted.replace(/^\d+\.\s+(.*?)$/gm, '<div style="margin: 6px 0;">$&</div>');
|
|
|
|
// Add line breaks for paragraphs
|
|
formatted = formatted.replace(/\n\n/g, '<br><br>');
|
|
formatted = formatted.replace(/\n/g, '<br>');
|
|
|
|
return formatted;
|
|
}
|
|
|
|
|
|
function copyReport() {
|
|
const reportText = AgentUtils.generateTextForExport('reportContent');
|
|
AgentUtils.copyToClipboard(reportText, '📋 Report copied to clipboard!');
|
|
}
|
|
|
|
function downloadReport() {
|
|
const reportText = AgentUtils.generateTextForExport('reportContent');
|
|
AgentUtils.downloadAsFile(reportText, `five-whys-analysis-${Date.now()}.txt`, '💾 Report downloaded!');
|
|
}
|
|
|
|
</script>
|
|
{% endblock %} |