lead-qualification / templates /lead_analysis.html
sksameermujahid's picture
Upload 19 files
c061318 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lead Analysis Dashboard</title>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/date-fns@2.29.3/index.min.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: #333;
}
.container {
max-width: 1400px;
margin: 0 auto;
padding: 20px;
}
.header {
text-align: center;
color: white;
margin-bottom: 30px;
}
.header h1 {
font-size: 2.5em;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
}
.header p {
font-size: 1.1em;
opacity: 0.9;
}
.search-section {
background: white;
border-radius: 15px;
padding: 30px;
margin-bottom: 30px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.search-form {
display: flex;
gap: 15px;
align-items: end;
justify-content: center;
flex-wrap: wrap;
}
.input-group {
display: flex;
flex-direction: column;
min-width: 200px;
}
.input-group label {
font-weight: 600;
margin-bottom: 5px;
color: #555;
}
.input-group input {
padding: 12px 15px;
border: 2px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
transition: all 0.3s ease;
}
.input-group input:focus {
outline: none;
border-color: #667eea;
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
}
.btn {
padding: 12px 25px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
border-radius: 8px;
font-size: 16px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(102, 126, 234, 0.3);
}
.btn:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.loading {
text-align: center;
padding: 40px;
color: white;
font-size: 18px;
}
.error {
background: #ff6b6b;
color: white;
padding: 20px;
border-radius: 10px;
margin: 20px 0;
text-align: center;
}
.results-section {
display: none;
}
.lead-status {
background: white;
border-radius: 15px;
padding: 25px;
margin-bottom: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.status-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
flex-wrap: wrap;
gap: 15px;
}
.status-badge {
padding: 10px 20px;
border-radius: 25px;
font-weight: bold;
font-size: 16px;
text-transform: uppercase;
letter-spacing: 1px;
}
.lead-score {
text-align: center;
}
.score-circle {
width: 120px;
height: 120px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 10px;
font-size: 24px;
font-weight: bold;
color: white;
background: conic-gradient(#667eea 0deg, #764ba2 360deg);
}
.analytics-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
gap: 20px;
margin-bottom: 20px;
}
.analytics-card {
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.card-header {
display: flex;
align-items: center;
margin-bottom: 20px;
}
.card-icon {
width: 40px;
height: 40px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 15px;
font-size: 20px;
color: white;
}
.card-title {
font-size: 18px;
font-weight: 600;
color: #333;
}
.metric-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid #f0f0f0;
}
.metric-item:last-child {
border-bottom: none;
}
.metric-label {
color: #666;
font-weight: 500;
}
.metric-value {
font-weight: 600;
color: #333;
}
.properties-section {
background: white;
border-radius: 15px;
padding: 25px;
margin-bottom: 20px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.properties-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 15px;
margin-top: 20px;
}
.property-card {
border: 2px solid #f0f0f0;
border-radius: 10px;
padding: 20px;
transition: all 0.3s ease;
}
.property-card:hover {
border-color: #667eea;
transform: translateY(-2px);
box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}
.property-name {
font-weight: 600;
color: #333;
margin-bottom: 10px;
}
.property-price {
font-size: 18px;
font-weight: bold;
color: #667eea;
margin-bottom: 10px;
}
.property-stats {
display: flex;
justify-content: space-between;
font-size: 14px;
color: #666;
}
.recommendations {
background: white;
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
}
.recommendation-item {
background: #f8f9ff;
border-left: 4px solid #667eea;
padding: 15px;
margin-bottom: 10px;
border-radius: 5px;
}
.chart-container {
position: relative;
height: 300px;
margin-top: 20px;
}
@media (max-width: 768px) {
.search-form {
flex-direction: column;
align-items: stretch;
}
.input-group {
min-width: auto;
}
.status-header {
flex-direction: column;
text-align: center;
}
.analytics-grid {
grid-template-columns: 1fr;
}
}
.fade-in {
animation: fadeIn 0.6s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>๐ŸŽฏ Lead Analysis Dashboard</h1>
<p>Comprehensive Customer Behavior Analytics & Lead Qualification</p>
</div>
<div class="search-section">
<form class="search-form" id="searchForm">
<div class="input-group">
<label for="customerId">Customer ID</label>
<input type="number" id="customerId" name="customerId" placeholder="Enter Customer ID" required
value="{{ customer_id if customer_id else '' }}">
</div>
<button type="submit" class="btn" id="searchBtn">
๐Ÿ” Analyze Customer
</button>
</form>
</div>
<div id="loadingSection" class="loading" style="display: none;">
<div>๐Ÿ”„ Analyzing customer data...</div>
<div style="margin-top: 10px; font-size: 14px; opacity: 0.8;">
Fetching lead qualification and property analytics
</div>
</div>
<div id="errorSection" class="error" style="display: none;"></div>
<div id="resultsSection" class="results-section">
<!-- Lead Status Section -->
<div class="lead-status fade-in">
<div class="status-header">
<div>
<h2>Lead Qualification Status</h2>
<div id="statusBadge" class="status-badge"></div>
<p id="statusDescription" style="margin-top: 10px; color: #666;"></p>
</div>
<div class="lead-score">
<div id="scoreCircle" class="score-circle"></div>
<div>Lead Score</div>
</div>
</div>
</div>
<!-- Analytics Grid -->
<div class="analytics-grid fade-in">
<!-- Engagement Analytics -->
<div class="analytics-card">
<div class="card-header">
<div class="card-icon" style="background: #667eea;">๐Ÿ“Š</div>
<div class="card-title">Engagement Analytics</div>
</div>
<div id="engagementMetrics"></div>
<div class="chart-container">
<canvas id="engagementChart"></canvas>
</div>
</div>
<!-- Property Preferences -->
<div class="analytics-card">
<div class="card-header">
<div class="card-icon" style="background: #764ba2;">๐Ÿ </div>
<div class="card-title">Property Preferences</div>
</div>
<div id="propertyPreferences"></div>
<div class="chart-container">
<canvas id="propertyChart"></canvas>
</div>
</div>
<!-- Price Analysis -->
<div class="analytics-card">
<div class="card-header">
<div class="card-icon" style="background: #f39c12;">๐Ÿ’ฐ</div>
<div class="card-title">Price Analysis</div>
</div>
<div id="priceAnalysis"></div>
</div>
<!-- Conversion Probability -->
<div class="analytics-card">
<div class="card-header">
<div class="card-icon" style="background: #e74c3c;">๐ŸŽฏ</div>
<div class="card-title">Conversion Probability</div>
</div>
<div id="conversionAnalysis"></div>
<div class="chart-container">
<canvas id="conversionChart"></canvas>
</div>
</div>
</div>
<!-- Properties Section -->
<div class="properties-section fade-in">
<div class="card-header">
<div class="card-icon" style="background: #2ecc71;">๐Ÿ˜๏ธ</div>
<div class="card-title">Viewed Properties</div>
</div>
<div id="propertiesGrid" class="properties-grid"></div>
</div>
<!-- Recommendations Section -->
<div class="recommendations fade-in">
<div class="card-header">
<div class="card-icon" style="background: #9b59b6;">๐Ÿ’ก</div>
<div class="card-title">AI Recommendations</div>
</div>
<div id="recommendationsContent"></div>
</div>
</div>
</div>
<script>
// Global variables
let currentData = null;
let charts = {};
// Initialize
document.addEventListener('DOMContentLoaded', function() {
const customerId = document.getElementById('customerId').value;
if (customerId) {
fetchAnalysis(customerId);
}
});
// Form submission
document.getElementById('searchForm').addEventListener('submit', function(e) {
e.preventDefault();
const customerId = document.getElementById('customerId').value;
if (customerId) {
fetchAnalysis(customerId);
}
});
// Fetch analysis data
async function fetchAnalysis(customerId) {
showLoading();
hideError();
hideResults();
try {
const response = await fetch(`/api/customer/${customerId}`);
const data = await response.json();
if (data.success) {
currentData = data;
displayResults(data);
showResults();
} else {
showError(data.error || 'Failed to fetch analysis');
}
} catch (error) {
showError(`Error: ${error.message}`);
} finally {
hideLoading();
}
}
// Display results
function displayResults(data) {
const leadData = data.data.lead_qualification;
const analytics = data.data.analytics;
const properties = data.data.properties;
// Update lead status
updateLeadStatus(leadData);
// Update analytics cards
updateEngagementMetrics(analytics);
updatePropertyPreferences(analytics);
updatePriceAnalysis(analytics);
updateConversionAnalysis(analytics);
// Update properties
updatePropertiesGrid(properties);
// Update recommendations
updateRecommendations(analytics.recommendations);
// Create charts
createCharts(analytics);
}
// Update lead status
function updateLeadStatus(leadData) {
const statusBadge = document.getElementById('statusBadge');
const statusDescription = document.getElementById('statusDescription');
const scoreCircle = document.getElementById('scoreCircle');
statusBadge.textContent = leadData.lead_status;
statusBadge.style.backgroundColor = leadData.status_color;
statusDescription.textContent = leadData.status_description;
scoreCircle.textContent = `${Math.round(leadData.lead_score)}/100`;
}
// Update engagement metrics
function updateEngagementMetrics(analytics) {
const container = document.getElementById('engagementMetrics');
container.innerHTML = `
<div class="metric-item">
<span class="metric-label">Engagement Level</span>
<span class="metric-value">${analytics.engagement_level}</span>
</div>
<div class="metric-item">
<span class="metric-label">Total Views</span>
<span class="metric-value">${currentData.data.summary.total_views}</span>
</div>
<div class="metric-item">
<span class="metric-label">Total Duration</span>
<span class="metric-value">${formatDuration(currentData.data.summary.total_duration)}</span>
</div>
<div class="metric-item">
<span class="metric-label">Engagement Score</span>
<span class="metric-value">${Math.round(currentData.data.summary.engagement_score)}</span>
</div>
`;
}
// Update property preferences
function updatePropertyPreferences(analytics) {
const container = document.getElementById('propertyPreferences');
const preferredTypes = analytics.preferred_property_types || [];
container.innerHTML = preferredTypes.map((type, index) => `
<div class="metric-item">
<span class="metric-label">Preference ${index + 1}</span>
<span class="metric-value">${type}</span>
</div>
`).join('');
}
// Update price analysis
function updatePriceAnalysis(analytics) {
const container = document.getElementById('priceAnalysis');
const priceData = analytics.price_preferences || {};
container.innerHTML = `
<div class="metric-item">
<span class="metric-label">Average Price</span>
<span class="metric-value">${formatPrice(priceData.avg_price || 0)}</span>
</div>
<div class="metric-item">
<span class="metric-label">Min Price</span>
<span class="metric-value">${formatPrice(priceData.min_price || 0)}</span>
</div>
<div class="metric-item">
<span class="metric-label">Max Price</span>
<span class="metric-value">${formatPrice(priceData.max_price || 0)}</span>
</div>
<div class="metric-item">
<span class="metric-label">Price Range</span>
<span class="metric-value">${formatPrice(priceData.price_range || 0)}</span>
</div>
`;
}
// Update conversion analysis
function updateConversionAnalysis(analytics) {
const container = document.getElementById('conversionAnalysis');
const conversionData = analytics.conversion_probability || {};
container.innerHTML = `
<div class="metric-item">
<span class="metric-label">Conversion Probability</span>
<span class="metric-value">${Math.round(conversionData.final_probability || 0)}%</span>
</div>
<div class="metric-item">
<span class="metric-label">Confidence Level</span>
<span class="metric-value">${conversionData.confidence_level || 'Unknown'}</span>
</div>
<div class="metric-item">
<span class="metric-label">Opportunity Score</span>
<span class="metric-value">${Math.round(analytics.opportunity_score || 0)}</span>
</div>
<div class="metric-item">
<span class="metric-label">Risk Level</span>
<span class="metric-value">${analytics.risk_assessment?.risk_level || 'Unknown'}</span>
</div>
`;
}
// Update properties grid
function updatePropertiesGrid(properties) {
const container = document.getElementById('propertiesGrid');
container.innerHTML = properties.map(property => `
<div class="property-card">
<div class="property-name">${property.propertyName || 'Unknown Property'}</div>
<div class="property-price">${formatPrice(property.price || 0)}</div>
<div class="property-stats">
<span>Views: ${property.viewCount || 0}</span>
<span>Duration: ${formatDuration(property.totalDuration || 0)}</span>
<span>Type: ${property.propertyTypeName || 'Unknown'}</span>
</div>
</div>
`).join('');
}
// Update recommendations
function updateRecommendations(recommendations) {
const container = document.getElementById('recommendationsContent');
if (recommendations && recommendations.length > 0) {
container.innerHTML = recommendations.map(rec => `
<div class="recommendation-item">${rec}</div>
`).join('');
} else {
container.innerHTML = '<div class="recommendation-item">No specific recommendations available.</div>';
}
}
// Create charts
function createCharts(analytics) {
createEngagementChart(analytics);
createPropertyChart(analytics);
createConversionChart(analytics);
}
// Create engagement chart
function createEngagementChart(analytics) {
const ctx = document.getElementById('engagementChart').getContext('2d');
if (charts.engagement) {
charts.engagement.destroy();
}
charts.engagement = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['High Engagement', 'Medium Engagement', 'Low Engagement'],
datasets: [{
data: [40, 35, 25], // Sample data
backgroundColor: ['#667eea', '#764ba2', '#95a5a6']
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'bottom'
}
}
}
});
}
// Create property chart
function createPropertyChart(analytics) {
const ctx = document.getElementById('propertyChart').getContext('2d');
if (charts.property) {
charts.property.destroy();
}
const propertyTypes = analytics.preferred_property_types || [];
const labels = propertyTypes.slice(0, 5);
const data = labels.map((_, i) => Math.max(1, 5 - i));
charts.property = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Interest Level',
data: data,
backgroundColor: '#667eea'
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
}
},
scales: {
y: {
beginAtZero: true
}
}
}
});
}
// Create conversion chart
function createConversionChart(analytics) {
const ctx = document.getElementById('conversionChart').getContext('2d');
if (charts.conversion) {
charts.conversion.destroy();
}
const conversionProb = analytics.conversion_probability?.final_probability || 0;
charts.conversion = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Conversion Probability', 'Remaining'],
datasets: [{
data: [conversionProb, 100 - conversionProb],
backgroundColor: ['#e74c3c', '#ecf0f1'],
borderWidth: 0
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
cutout: '70%',
plugins: {
legend: {
display: false
}
}
}
});
}
// Utility functions
function formatPrice(price) {
return `โ‚น${price.toLocaleString('en-IN')}`;
}
function formatDuration(seconds) {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
return `${hours}h ${minutes}m`;
}
function showLoading() {
document.getElementById('loadingSection').style.display = 'block';
document.getElementById('searchBtn').disabled = true;
document.getElementById('searchBtn').textContent = '๐Ÿ”„ Analyzing...';
}
function hideLoading() {
document.getElementById('loadingSection').style.display = 'none';
document.getElementById('searchBtn').disabled = false;
document.getElementById('searchBtn').textContent = '๐Ÿ” Analyze Customer';
}
function showError(message) {
const errorSection = document.getElementById('errorSection');
errorSection.textContent = message;
errorSection.style.display = 'block';
}
function hideError() {
document.getElementById('errorSection').style.display = 'none';
}
function showResults() {
document.getElementById('resultsSection').style.display = 'block';
}
function hideResults() {
document.getElementById('resultsSection').style.display = 'none';
}
</script>
</body>
</html>