quantum-ai-v3/data_analyzer/templates/data_analyzer/detail.html
Claude f6ba431514 Simplify Data Analyzer frontend for beginners
- Reduce JavaScript from 744 lines to ~150 lines
- Remove complex drag/drop functionality (use simple file input)
- Eliminate elaborate markdown parser (use simple text formatting)
- Replace complex polling with simplified version
- Remove multiple CSS themes, use single clean theme
- Maintain ALL core functionality:
   File upload (PDF, CSV, Excel)
   Analysis type selection
   Wallet balance checking
   N8N webhook integration
   Polling for results
   Copy/download functionality
   Error handling

Benefits:
- Beginner-friendly code structure
- Fast page loads (no external fonts/CSS)
- Easy to understand and modify
- All business logic preserved
2025-07-16 22:44:50 +05:30

413 lines
12 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block title %}Data Analyzer - NetCop AI Hub{% endblock %}
{% block extra_css %}
<style>
/* Simple, beginner-friendly styling */
.simple-container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
}
.simple-card {
background: white;
border: 1px solid #e5e7eb;
border-radius: 8px;
padding: 24px;
margin-bottom: 20px;
box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.simple-form-group {
margin-bottom: 20px;
}
.simple-label {
display: block;
margin-bottom: 8px;
font-weight: 600;
color: #374151;
}
.simple-file-input {
width: 100%;
padding: 12px;
border: 2px dashed #d1d5db;
border-radius: 6px;
text-align: center;
cursor: pointer;
background: #f9fafb;
}
.simple-file-input:hover {
border-color: #3b82f6;
background: #f0f9ff;
}
.simple-radio-group {
display: flex;
gap: 16px;
flex-wrap: wrap;
}
.simple-radio-option {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 16px;
border: 1px solid #d1d5db;
border-radius: 6px;
cursor: pointer;
background: white;
}
.simple-radio-option:hover {
border-color: #3b82f6;
background: #f0f9ff;
}
.simple-radio-option input[type="radio"]:checked + label {
border-color: #3b82f6;
background: #f0f9ff;
}
.simple-btn {
padding: 12px 24px;
border: none;
border-radius: 6px;
font-weight: 600;
cursor: pointer;
text-decoration: none;
display: inline-block;
}
.simple-btn-primary {
background: #3b82f6;
color: white;
}
.simple-btn-primary:hover {
background: #2563eb;
}
.simple-btn-secondary {
background: #6b7280;
color: white;
}
.simple-wallet-info {
background: #f3f4f6;
padding: 16px;
border-radius: 6px;
margin-bottom: 20px;
}
.simple-loading {
text-align: center;
padding: 20px;
background: #fef3c7;
border-radius: 6px;
display: none;
}
.simple-results {
background: #f0f9ff;
border: 1px solid #3b82f6;
border-radius: 6px;
padding: 20px;
margin-top: 20px;
display: none;
}
.simple-error {
background: #fef2f2;
border: 1px solid #ef4444;
color: #dc2626;
padding: 12px;
border-radius: 6px;
margin-bottom: 16px;
}
.simple-success {
background: #f0fdf4;
border: 1px solid #22c55e;
color: #16a34a;
padding: 12px;
border-radius: 6px;
margin-bottom: 16px;
}
.simple-grid {
display: grid;
grid-template-columns: 1fr 300px;
gap: 20px;
align-items: start;
}
@media (max-width: 768px) {
.simple-grid {
grid-template-columns: 1fr;
}
}
</style>
{% endblock %}
{% block content %}
<div class="simple-container">
<div class="simple-grid">
<!-- Main Content -->
<div>
<div class="simple-card">
<h2>📊 Data Analyzer</h2>
<p>Upload your data file and get AI-powered analysis</p>
<form id="simpleForm" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<!-- File Upload -->
<div class="simple-form-group">
<label class="simple-label">📁 Upload Data File</label>
<input type="file" id="dataFile" name="file" accept=".pdf,.csv,.xlsx,.xls"
class="simple-file-input" required>
<small>Supports: PDF, CSV, Excel files</small>
</div>
<!-- Analysis Type -->
<div class="simple-form-group">
<label class="simple-label">🔍 Analysis Type</label>
<div class="simple-radio-group">
<div class="simple-radio-option">
<input type="radio" id="summary" name="analysisType" value="summary" checked>
<label for="summary">📋 Summary</label>
</div>
<div class="simple-radio-option">
<input type="radio" id="detailed" name="analysisType" value="detailed">
<label for="detailed">📈 Detailed</label>
</div>
<div class="simple-radio-option">
<input type="radio" id="statistical" name="analysisType" value="statistical">
<label for="statistical">📊 Statistical</label>
</div>
</div>
</div>
</form>
</div>
<!-- Loading -->
<div id="loadingDiv" class="simple-loading">
<div>⏳ Analyzing your data...</div>
<div id="loadingText">Processing file...</div>
</div>
<!-- Results -->
<div id="resultsDiv" class="simple-results">
<h3>✅ Analysis Complete</h3>
<div id="resultsContent"></div>
<div style="margin-top: 16px;">
<button onclick="copyResults()" class="simple-btn simple-btn-secondary">📋 Copy</button>
<button onclick="downloadResults()" class="simple-btn simple-btn-secondary">💾 Download</button>
</div>
</div>
</div>
<!-- Wallet Sidebar -->
<div>
<div class="simple-card">
<h3>💳 Your Wallet</h3>
<div class="simple-wallet-info">
<div style="font-size: 24px; font-weight: bold;">
<span id="walletBalance">{{ user.wallet_balance|floatformat:2 }}</span> AED
</div>
<div style="color: #6b7280;">Available Balance</div>
</div>
{% if user.is_authenticated %}
{% if user.wallet_balance >= 5.00 %}
<button type="submit" form="simpleForm" class="simple-btn simple-btn-primary"
id="analyzeBtn" style="width: 100%;">
📊 Analyze Data (5.00 AED)
</button>
{% else %}
<div class="simple-error">
Insufficient balance! You need 5.00 AED.
</div>
<a href="{% url 'core:wallet' %}" class="simple-btn simple-btn-primary"
style="width: 100%; text-decoration: none;">
💰 Top Up Wallet
</a>
{% endif %}
{% else %}
<a href="{% url 'authentication:login' %}" class="simple-btn simple-btn-primary"
style="width: 100%; text-decoration: none;">
🔑 Login to Continue
</a>
{% endif %}
</div>
<div class="simple-card">
<h4>💡 How it works</h4>
<ol>
<li>Upload your data file</li>
<li>Choose analysis type</li>
<li>Get AI-powered insights</li>
<li>Copy or download results</li>
</ol>
</div>
</div>
</div>
</div>
<script>
// Simple JavaScript - beginner friendly
let currentResults = '';
// Form submission
document.getElementById('simpleForm').addEventListener('submit', function(e) {
e.preventDefault();
// Check if file is selected
const fileInput = document.getElementById('dataFile');
if (!fileInput.files || fileInput.files.length === 0) {
alert('Please select a data file');
return;
}
// Check authentication
{% if not user.is_authenticated %}
window.location.href = "{% url 'authentication:login' %}";
return;
{% endif %}
// Check wallet balance
const balance = {{ user.wallet_balance|default:0 }};
if (balance < 5.00) {
alert('Insufficient balance! You need 5.00 AED.');
window.location.href = "{% url 'core:wallet' %}";
return;
}
// Show loading
document.getElementById('loadingDiv').style.display = 'block';
document.getElementById('resultsDiv').style.display = 'none';
document.getElementById('analyzeBtn').disabled = true;
document.getElementById('analyzeBtn').textContent = '⏳ Processing...';
// Submit form
const formData = new FormData(this);
fetch(window.location.href, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(result => {
if (result.success && result.request_id) {
// Start checking for results
checkResults(result.request_id);
} else {
showError(result.error || 'Processing failed');
}
})
.catch(error => {
console.error('Error:', error);
showError('Network error - please try again');
});
});
// Check results (simplified polling)
function checkResults(requestId) {
fetch(`/agents/data-analyzer/status/${requestId}/`)
.then(response => response.json())
.then(result => {
if (result.status === 'completed') {
hideLoading();
if (result.success) {
showResults(result);
updateWalletBalance(result.wallet_balance);
} else {
showError('Analysis failed');
}
} else if (result.status === 'failed') {
hideLoading();
showError('Analysis failed');
} else {
// Still processing, check again in 2 seconds
setTimeout(() => checkResults(requestId), 2000);
}
})
.catch(error => {
console.error('Error checking results:', error);
hideLoading();
showError('Error checking results');
});
}
// Show results
function showResults(result) {
// Get content from different possible fields
let content = result.report_text || result.insights_summary ||
(result.raw_response && result.raw_response.analysis) ||
'Analysis completed successfully!';
// Simple text formatting (no complex markdown)
content = content.replace(/\*\*/g, '').replace(/\n/g, '<br>');
currentResults = content;
document.getElementById('resultsContent').innerHTML = content;
document.getElementById('resultsDiv').style.display = 'block';
// Show success message
showMessage('✅ Analysis completed and payment processed!', 'success');
}
// Helper functions
function hideLoading() {
document.getElementById('loadingDiv').style.display = 'none';
document.getElementById('analyzeBtn').disabled = false;
document.getElementById('analyzeBtn').textContent = '📊 Analyze Data (5.00 AED)';
}
function showError(message) {
hideLoading();
showMessage('❌ ' + message, 'error');
}
function showMessage(message, type) {
// Simple alert for now (can be improved later)
alert(message);
}
function updateWalletBalance(newBalance) {
if (newBalance !== undefined) {
document.getElementById('walletBalance').textContent = newBalance.toFixed(2);
}
}
function copyResults() {
if (currentResults) {
navigator.clipboard.writeText(currentResults.replace(/<br>/g, '\n'))
.then(() => alert('📋 Results copied to clipboard!'))
.catch(() => alert('Failed to copy results'));
}
}
function downloadResults() {
if (currentResults) {
const blob = new Blob([currentResults.replace(/<br>/g, '\n')], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `data-analysis-${Date.now()}.txt`;
a.click();
URL.revokeObjectURL(url);
alert('💾 Results downloaded!');
}
}
</script>
{% endblock %}