apamplona2011's picture
i want to make a customer insights ai agent. This website will provide a simple dashboard that summarizes the customers sentiment for a particular company. it will look at twitters api aggregate key words and provide a simple social score that a company can understand. - Initial Deployment
5a6f448 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Customer Insights AI | Social Sentiment Analysis</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#4F46E5',
secondary: '#10B981',
danger: '#EF4444',
warning: '#F59E0B',
}
}
}
}
</script>
<style>
.sentiment-chart {
height: 300px;
position: relative;
}
.sentiment-bar {
position: absolute;
bottom: 0;
transition: all 0.5s ease;
}
.tooltip {
position: absolute;
background: rgba(0,0,0,0.8);
color: white;
padding: 5px 10px;
border-radius: 5px;
font-size: 12px;
pointer-events: none;
opacity: 0;
transition: opacity 0.3s;
}
.pulse-animation {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
</style>
</head>
<body class="bg-gray-50 min-h-screen">
<!-- Navigation -->
<nav class="bg-white shadow-sm">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16">
<div class="flex items-center">
<div class="flex-shrink-0 flex items-center">
<i class="fas fa-robot text-primary text-2xl mr-2"></i>
<span class="text-xl font-bold text-gray-900">Customer Insights AI</span>
</div>
</div>
<div class="hidden sm:ml-6 sm:flex sm:items-center">
<button class="bg-primary hover:bg-indigo-700 text-white px-4 py-2 rounded-md text-sm font-medium transition duration-150 ease-in-out">
<i class="fas fa-sign-in-alt mr-2"></i>Sign In
</button>
</div>
</div>
</div>
</nav>
<!-- Main Content -->
<main class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<div class="mb-8">
<h1 class="text-3xl font-bold text-gray-900 mb-2">Social Sentiment Dashboard</h1>
<p class="text-gray-600">Analyze customer sentiment from Twitter in real-time</p>
</div>
<!-- Search and Filters -->
<div class="bg-white rounded-lg shadow p-6 mb-8">
<div class="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
<div class="flex-1">
<label for="company-search" class="block text-sm font-medium text-gray-700 mb-1">Company Name</label>
<div class="relative">
<input type="text" id="company-search" placeholder="Search for a company (e.g. Apple, Tesla, Amazon)"
class="w-full pl-4 pr-10 py-2 border border-gray-300 rounded-md focus:ring-primary focus:border-primary">
<button class="absolute right-2 top-2 text-gray-400 hover:text-gray-600">
<i class="fas fa-search"></i>
</button>
</div>
</div>
<div>
<label for="time-range" class="block text-sm font-medium text-gray-700 mb-1">Time Range</label>
<select id="time-range" class="block w-full pl-3 pr-10 py-2 text-base border border-gray-300 focus:outline-none focus:ring-primary focus:border-primary rounded-md">
<option>Last 24 hours</option>
<option selected>Last 7 days</option>
<option>Last 30 days</option>
<option>Custom range</option>
</select>
</div>
<div class="flex items-end">
<button id="analyze-btn" class="bg-primary hover:bg-indigo-700 text-white px-6 py-2 rounded-md text-sm font-medium transition duration-150 ease-in-out flex items-center">
<i class="fas fa-chart-line mr-2"></i>Analyze
</button>
</div>
</div>
</div>
<!-- Dashboard Content -->
<div id="dashboard-content" class="hidden">
<!-- Summary Cards -->
<div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
<!-- Social Score Card -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-medium text-gray-900">Social Score</h3>
<div class="bg-primary bg-opacity-10 p-2 rounded-full">
<i class="fas fa-star text-primary"></i>
</div>
</div>
<div class="text-center">
<div class="text-5xl font-bold text-primary mb-2 pulse-animation" id="social-score">78</div>
<div class="text-sm text-gray-500">out of 100</div>
<div class="mt-4 h-2 bg-gray-200 rounded-full overflow-hidden">
<div class="h-full bg-primary rounded-full" style="width: 78%"></div>
</div>
</div>
</div>
<!-- Sentiment Distribution Card -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-medium text-gray-900">Sentiment</h3>
<div class="bg-secondary bg-opacity-10 p-2 rounded-full">
<i class="fas fa-smile text-secondary"></i>
</div>
</div>
<div class="flex justify-between items-center mb-2">
<span class="text-sm font-medium text-secondary">Positive</span>
<span class="text-sm font-medium" id="positive-percent">62%</span>
</div>
<div class="h-2 bg-gray-200 rounded-full overflow-hidden mb-3">
<div class="h-full bg-secondary rounded-full" style="width: 62%"></div>
</div>
<div class="flex justify-between items-center mb-2">
<span class="text-sm font-medium text-gray-500">Neutral</span>
<span class="text-sm font-medium" id="neutral-percent">24%</span>
</div>
<div class="h-2 bg-gray-200 rounded-full overflow-hidden mb-3">
<div class="h-full bg-gray-400 rounded-full" style="width: 24%"></div>
</div>
<div class="flex justify-between items-center mb-2">
<span class="text-sm font-medium text-danger">Negative</span>
<span class="text-sm font-medium" id="negative-percent">14%</span>
</div>
<div class="h-2 bg-gray-200 rounded-full overflow-hidden">
<div class="h-full bg-danger rounded-full" style="width: 14%"></div>
</div>
</div>
<!-- Volume Card -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-medium text-gray-900">Mentions</h3>
<div class="bg-warning bg-opacity-10 p-2 rounded-full">
<i class="fas fa-bullhorn text-warning"></i>
</div>
</div>
<div class="text-center">
<div class="text-5xl font-bold text-warning mb-2" id="mention-count">12,456</div>
<div class="text-sm text-gray-500">total mentions</div>
<div class="mt-4 flex justify-center">
<div class="text-sm bg-green-100 text-green-800 px-2 py-1 rounded-full">
<i class="fas fa-arrow-up mr-1"></i> 8.2% from last week
</div>
</div>
</div>
</div>
<!-- Top Topics Card -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-4">
<h3 class="text-lg font-medium text-gray-900">Top Topics</h3>
<div class="bg-indigo-100 p-2 rounded-full">
<i class="fas fa-hashtag text-indigo-600"></i>
</div>
</div>
<div class="space-y-3">
<div class="flex items-center">
<span class="bg-secondary bg-opacity-10 text-secondary px-2 py-1 rounded-full text-xs font-medium mr-2">Positive</span>
<span class="text-sm truncate">#NewProductLaunch</span>
</div>
<div class="flex items-center">
<span class="bg-danger bg-opacity-10 text-danger px-2 py-1 rounded-full text-xs font-medium mr-2">Negative</span>
<span class="text-sm truncate">#CustomerService</span>
</div>
<div class="flex items-center">
<span class="bg-secondary bg-opacity-10 text-secondary px-2 py-1 rounded-full text-xs font-medium mr-2">Positive</span>
<span class="text-sm truncate">#Sustainability</span>
</div>
<div class="flex items-center">
<span class="bg-gray-200 text-gray-600 px-2 py-1 rounded-full text-xs font-medium mr-2">Neutral</span>
<span class="text-sm truncate">#EarningsReport</span>
</div>
</div>
</div>
</div>
<!-- Charts Section -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
<!-- Sentiment Trend Chart -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-6">
<h3 class="text-lg font-medium text-gray-900">Sentiment Trend</h3>
<div class="flex space-x-2">
<button class="px-3 py-1 text-xs bg-gray-100 rounded-md">Daily</button>
<button class="px-3 py-1 text-xs bg-primary text-white rounded-md">Weekly</button>
<button class="px-3 py-1 text-xs bg-gray-100 rounded-md">Monthly</button>
</div>
</div>
<div class="sentiment-chart">
<div class="tooltip" id="sentiment-tooltip"></div>
<div class="flex h-full items-end space-x-1">
<!-- These bars would be generated dynamically in a real app -->
<div class="sentiment-bar bg-secondary w-8" style="height: 45%" data-date="Mon" data-value="45% positive"></div>
<div class="sentiment-bar bg-secondary w-8" style="height: 52%" data-date="Tue" data-value="52% positive"></div>
<div class="sentiment-bar bg-secondary w-8" style="height: 60%" data-date="Wed" data-value="60% positive"></div>
<div class="sentiment-bar bg-secondary w-8" style="height: 58%" data-date="Thu" data-value="58% positive"></div>
<div class="sentiment-bar bg-danger w-8" style="height: 30%" data-date="Fri" data-value="30% positive"></div>
<div class="sentiment-bar bg-secondary w-8" style="height: 65%" data-date="Sat" data-value="65% positive"></div>
<div class="sentiment-bar bg-secondary w-8" style="height: 70%" data-date="Sun" data-value="70% positive"></div>
</div>
<div class="flex justify-between mt-2 text-xs text-gray-500">
<span>Mon</span>
<span>Tue</span>
<span>Wed</span>
<span>Thu</span>
<span>Fri</span>
<span>Sat</span>
<span>Sun</span>
</div>
</div>
</div>
<!-- Word Cloud -->
<div class="bg-white rounded-lg shadow p-6">
<div class="flex items-center justify-between mb-6">
<h3 class="text-lg font-medium text-gray-900">Word Cloud</h3>
<div class="flex items-center text-sm text-gray-500">
<i class="fas fa-info-circle mr-1"></i>
<span>Size indicates frequency</span>
</div>
</div>
<div class="flex flex-wrap justify-center items-center h-64">
<span class="text-4xl font-bold text-primary m-1">innovation</span>
<span class="text-2xl font-bold text-secondary m-1">quality</span>
<span class="text-xl font-bold text-secondary m-1">fast</span>
<span class="text-3xl font-bold text-danger m-1">expensive</span>
<span class="text-lg font-bold text-secondary m-1">reliable</span>
<span class="text-2xl font-bold text-danger m-1">buggy</span>
<span class="text-xl font-bold text-secondary m-1">support</span>
<span class="text-lg font-bold text-gray-500 m-1">update</span>
<span class="text-xl font-bold text-secondary m-1">easy</span>
<span class="text-lg font-bold text-danger m-1">slow</span>
<span class="text-2xl font-bold text-secondary m-1">design</span>
<span class="text-lg font-bold text-gray-500 m-1">feature</span>
</div>
</div>
</div>
<!-- Sample Tweets Section -->
<div class="bg-white rounded-lg shadow overflow-hidden mb-8">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-medium text-gray-900">Recent Mentions</h3>
</div>
<div class="divide-y divide-gray-200">
<!-- Positive Tweet -->
<div class="p-6">
<div class="flex items-start">
<img class="h-10 w-10 rounded-full mr-4" src="https://randomuser.me/api/portraits/women/32.jpg" alt="User avatar">
<div class="flex-1">
<div class="flex items-center justify-between">
<span class="font-medium">Sarah Johnson</span>
<span class="text-xs text-gray-500">2 hours ago</span>
</div>
<div class="text-sm text-gray-700 mt-1 mb-2">
Just got the new product from @ExampleCompany and I'm blown away by the quality! The attention to detail is incredible. #HappyCustomer
</div>
<div class="flex items-center text-sm text-gray-500">
<span class="flex items-center mr-4">
<i class="far fa-heart mr-1"></i> 24
</span>
<span class="flex items-center mr-4">
<i class="far fa-comment mr-1"></i> 5
</span>
<span class="flex items-center">
<i class="far fa-share-square mr-1"></i> 3
</span>
<span class="ml-auto bg-green-100 text-green-800 px-2 py-1 rounded-full text-xs">
<i class="fas fa-smile mr-1"></i> Positive
</span>
</div>
</div>
</div>
</div>
<!-- Negative Tweet -->
<div class="p-6">
<div class="flex items-start">
<img class="h-10 w-10 rounded-full mr-4" src="https://randomuser.me/api/portraits/men/45.jpg" alt="User avatar">
<div class="flex-1">
<div class="flex items-center justify-between">
<span class="font-medium">Mike Thompson</span>
<span class="text-xs text-gray-500">5 hours ago</span>
</div>
<div class="text-sm text-gray-700 mt-1 mb-2">
Really disappointed with @ExampleCompany's customer service. Waited 45 mins on hold just to be transferred to the wrong department. #Frustrated
</div>
<div class="flex items-center text-sm text-gray-500">
<span class="flex items-center mr-4">
<i class="far fa-heart mr-1"></i> 8
</span>
<span class="flex items-center mr-4">
<i class="far fa-comment mr-1"></i> 12
</span>
<span class="flex items-center">
<i class="far fa-share-square mr-1"></i> 2
</span>
<span class="ml-auto bg-red-100 text-red-800 px-2 py-1 rounded-full text-xs">
<i class="fas fa-frown mr-1"></i> Negative
</span>
</div>
</div>
</div>
</div>
<!-- Neutral Tweet -->
<div class="p-6">
<div class="flex items-start">
<img class="h-10 w-10 rounded-full mr-4" src="https://randomuser.me/api/portraits/women/68.jpg" alt="User avatar">
<div class="flex-1">
<div class="flex items-center justify-between">
<span class="font-medium">Lisa Chen</span>
<span class="text-xs text-gray-500">1 day ago</span>
</div>
<div class="text-sm text-gray-700 mt-1 mb-2">
Reading @ExampleCompany's latest earnings report. Interesting numbers but waiting to see how the new strategy plays out in Q3.
</div>
<div class="flex items-center text-sm text-gray-500">
<span class="flex items-center mr-4">
<i class="far fa-heart mr-1"></i> 3
</span>
<span class="flex items-center mr-4">
<i class="far fa-comment mr-1"></i> 2
</span>
<span class="flex items-center">
<i class="far fa-share-square mr-1"></i> 1
</span>
<span class="ml-auto bg-gray-100 text-gray-800 px-2 py-1 rounded-full text-xs">
<i class="fas fa-meh mr-1"></i> Neutral
</span>
</div>
</div>
</div>
</div>
</div>
<div class="px-6 py-4 border-t border-gray-200 text-center">
<button class="text-primary hover:text-indigo-700 font-medium text-sm">
<i class="fas fa-arrow-down mr-1"></i> Load More
</button>
</div>
</div>
<!-- Recommendations Section -->
<div class="bg-white rounded-lg shadow overflow-hidden">
<div class="px-6 py-4 border-b border-gray-200">
<h3 class="text-lg font-medium text-gray-900">AI Recommendations</h3>
</div>
<div class="p-6">
<div class="space-y-4">
<div class="flex items-start">
<div class="flex-shrink-0 bg-primary bg-opacity-10 p-2 rounded-full mr-4">
<i class="fas fa-lightbulb text-primary"></i>
</div>
<div>
<h4 class="font-medium text-gray-900">Customer Service Improvement</h4>
<p class="text-sm text-gray-600 mt-1">
14% of negative mentions relate to customer service. Consider implementing a callback system to reduce hold times and improve customer satisfaction.
</p>
</div>
</div>
<div class="flex items-start">
<div class="flex-shrink-0 bg-secondary bg-opacity-10 p-2 rounded-full mr-4">
<i class="fas fa-bullhorn text-secondary"></i>
</div>
<div>
<h4 class="font-medium text-gray-900">Highlight Product Quality</h4>
<p class="text-sm text-gray-600 mt-1">
"Quality" is mentioned positively in 23% of tweets. Consider creating marketing campaigns that emphasize your product's quality and attention to detail.
</p>
</div>
</div>
<div class="flex items-start">
<div class="flex-shrink-0 bg-warning bg-opacity-10 p-2 rounded-full mr-4">
<i class="fas fa-exclamation-triangle text-warning"></i>
</div>
<div>
<h4 class="font-medium text-gray-900">Address Pricing Concerns</h4>
<p class="text-sm text-gray-600 mt-1">
"Expensive" is a recurring negative keyword. Consider communicating your value proposition more clearly or exploring pricing options.
</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Empty State -->
<div id="empty-state" class="bg-white rounded-lg shadow p-12 text-center">
<div class="mx-auto max-w-md">
<i class="fas fa-chart-pie text-5xl text-gray-300 mb-4"></i>
<h3 class="text-lg font-medium text-gray-900 mb-2">No data to display</h3>
<p class="text-gray-500 mb-6">
Search for a company to analyze its social media sentiment and get valuable customer insights.
</p>
<button class="bg-primary hover:bg-indigo-700 text-white px-6 py-2 rounded-md text-sm font-medium transition duration-150 ease-in-out">
<i class="fas fa-search mr-2"></i>Search for a company
</button>
</div>
</div>
</main>
<!-- Footer -->
<footer class="bg-white border-t border-gray-200 mt-12">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<div class="md:flex md:items-center md:justify-between">
<div class="flex justify-center md:order-2 space-x-6">
<a href="#" class="text-gray-400 hover:text-gray-500">
<i class="fab fa-twitter"></i>
</a>
<a href="#" class="text-gray-400 hover:text-gray-500">
<i class="fab fa-linkedin"></i>
</a>
<a href="#" class="text-gray-400 hover:text-gray-500">
<i class="fab fa-github"></i>
</a>
</div>
<div class="mt-8 md:mt-0 md:order-1">
<p class="text-center text-sm text-gray-500">
&copy; 2023 Customer Insights AI. All rights reserved.
</p>
</div>
</div>
</div>
</footer>
<script>
// DOM elements
const analyzeBtn = document.getElementById('analyze-btn');
const dashboardContent = document.getElementById('dashboard-content');
const emptyState = document.getElementById('empty-state');
const sentimentBars = document.querySelectorAll('.sentiment-bar');
const sentimentTooltip = document.getElementById('sentiment-tooltip');
// Simulate data loading
analyzeBtn.addEventListener('click', function() {
// Show loading state
analyzeBtn.innerHTML = '<i class="fas fa-spinner fa-spin mr-2"></i>Analyzing...';
analyzeBtn.disabled = true;
// Simulate API call delay
setTimeout(function() {
// Hide empty state and show dashboard
emptyState.classList.add('hidden');
dashboardContent.classList.remove('hidden');
// Reset button
analyzeBtn.innerHTML = '<i class="fas fa-chart-line mr-2"></i>Analyze';
analyzeBtn.disabled = false;
// Animate numbers
animateValue('social-score', 0, 78, 1500);
animateValue('mention-count', 0, 12456, 1500);
// Set sentiment percentages
document.getElementById('positive-percent').textContent = '62%';
document.getElementById('neutral-percent').textContent = '24%';
document.getElementById('negative-percent').textContent = '14%';
}, 1500);
});
// Number animation function
function animateValue(id, start, end, duration) {
const obj = document.getElementById(id);
let startTimestamp = null;
const step = (timestamp) => {
if (!startTimestamp) startTimestamp = timestamp;
const progress = Math.min((timestamp - startTimestamp) / duration, 1);
if (id === 'mention-count') {
obj.innerHTML = Math.floor(progress * (end - start) + start).toLocaleString();
} else {
obj.innerHTML = Math.floor(progress * (end - start) + start);
}
if (progress < 1) {
window.requestAnimationFrame(step);
}
};
window.requestAnimationFrame(step);
}
// Add hover effects to sentiment bars
sentimentBars.forEach(bar => {
bar.addEventListener('mouseover', function(e) {
const date = this.getAttribute('data-date');
const value = this.getAttribute('data-value');
// Position tooltip above the bar
const rect = this.getBoundingClientRect();
sentimentTooltip.style.left = `${rect.left + rect.width/2 - 50}px`;
sentimentTooltip.style.top = `${rect.top - 40}px`;
sentimentTooltip.style.opacity = '1';
// Set tooltip content
sentimentTooltip.innerHTML = `
<div class="font-bold">${date}</div>
<div>${value}</div>
`;
// Highlight the bar
this.style.opacity = '0.8';
this.style.transform = 'scale(1.05)';
});
bar.addEventListener('mouseout', function() {
sentimentTooltip.style.opacity = '0';
this.style.opacity = '1';
this.style.transform = 'scale(1)';
});
});
// Simulate real-time updates (in a real app, this would be from WebSockets)
setInterval(() => {
const scoreElement = document.getElementById('social-score');
let currentScore = parseInt(scoreElement.textContent);
const change = Math.floor(Math.random() * 3) - 1; // -1, 0, or 1
if (currentScore + change >= 0 && currentScore + change <= 100) {
scoreElement.textContent = currentScore + change;
// Update the progress bar
const progressBar = document.querySelector('#social-score ~ div > div');
progressBar.style.width = `${currentScore + change}%`;
// Add pulse animation if score increases
if (change > 0) {
scoreElement.classList.add('pulse-animation');
setTimeout(() => {
scoreElement.classList.remove('pulse-animation');
}, 2000);
}
}
}, 5000);
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=apamplona2011/customer-insights-project" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>