fitsblb's picture
Deploy advanced sentiment analyzer with 4-model ensemble system
82c705b
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sentiment Analysis Results | AI Sentiment Analyzer</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Inter', sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 20px;
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.container {
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
padding: 3rem 2rem;
border-radius: 20px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
max-width: 700px;
width: 100%;
text-align: center;
}
.header {
margin-bottom: 2rem;
}
.title {
font-size: 2rem;
font-weight: 700;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 1rem;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.input-display {
background: #f8fafc;
padding: 1.5rem;
border-radius: 15px;
margin-bottom: 2rem;
border-left: 4px solid #667eea;
}
.input-label {
color: #6b7280;
font-size: 0.9rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: 0.5rem;
}
.input-text {
color: #374151;
font-size: 1.1rem;
line-height: 1.6;
font-style: italic;
}
.results-card {
background: white;
padding: 2rem;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
margin-bottom: 2rem;
position: relative;
overflow: hidden;
}
.results-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(135deg, #667eea, #764ba2);
}
.sentiment-result {
margin-bottom: 1.5rem;
}
.sentiment-icon {
font-size: 4rem;
margin-bottom: 1rem;
animation: bounceIn 0.6s ease-out 0.2s both;
}
@keyframes bounceIn {
0% { transform: scale(0); opacity: 0; }
50% { transform: scale(1.1); opacity: 0.8; }
100% { transform: scale(1); opacity: 1; }
}
.sentiment-label {
font-size: 2rem;
font-weight: 700;
margin-bottom: 0.5rem;
text-transform: uppercase;
letter-spacing: 1px;
}
.positive {
color: #10b981;
}
.positive .sentiment-icon {
color: #10b981;
}
.neutral {
color: #f59e0b;
}
.neutral .sentiment-icon {
color: #f59e0b;
}
.negative {
color: #ef4444;
}
.negative .sentiment-icon {
color: #ef4444;
}
.confidence-section {
margin: 2rem 0;
}
.confidence-label {
color: #6b7280;
font-size: 1rem;
font-weight: 600;
margin-bottom: 1rem;
}
.confidence-container {
background: #e5e7eb;
height: 12px;
border-radius: 10px;
overflow: hidden;
margin-bottom: 0.5rem;
position: relative;
}
.confidence-bar {
height: 100%;
border-radius: 10px;
background: linear-gradient(90deg, #667eea, #764ba2);
transition: width 1s ease-out 0.5s;
position: relative;
overflow: hidden;
}
.confidence-bar::after {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.4), transparent);
animation: shimmer 2s infinite;
}
@keyframes shimmer {
0% { left: -100%; }
100% { left: 100%; }
}
.confidence-text {
font-size: 1.2rem;
font-weight: 600;
color: #374151;
margin-top: 0.5rem;
}
.confidence-percentage {
font-size: 2rem;
font-weight: 700;
background: linear-gradient(135deg, #667eea, #764ba2);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.actions {
display: flex;
gap: 1rem;
justify-content: center;
flex-wrap: wrap;
margin-top: 2rem;
}
.btn {
padding: 1rem 2rem;
border: none;
border-radius: 15px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 8px;
}
.btn-primary {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3);
}
.btn-secondary {
background: white;
color: #667eea;
border: 2px solid #667eea;
}
.btn-secondary:hover {
background: #667eea;
color: white;
transform: translateY(-2px);
}
.api-info {
background: #f0f9ff;
border: 1px solid #bae6fd;
padding: 1.5rem;
border-radius: 15px;
margin-top: 2rem;
}
.api-title {
color: #0369a1;
font-weight: 600;
margin-bottom: 1rem;
display: flex;
align-items: center;
gap: 8px;
justify-content: center;
}
.api-code {
background: #1e293b;
color: #e2e8f0;
padding: 1rem;
border-radius: 10px;
font-family: 'Courier New', monospace;
font-size: 0.9rem;
text-align: left;
overflow-x: auto;
margin-top: 1rem;
}
.copy-btn {
background: #0369a1;
color: white;
border: none;
padding: 0.5rem 1rem;
border-radius: 8px;
font-size: 0.8rem;
cursor: pointer;
margin-top: 0.5rem;
transition: all 0.3s ease;
}
.copy-btn:hover {
background: #0284c7;
}
@media (max-width: 768px) {
.container {
padding: 2rem 1.5rem;
margin: 10px;
}
.title {
font-size: 1.5rem;
}
.sentiment-label {
font-size: 1.5rem;
}
.sentiment-icon {
font-size: 3rem;
}
.actions {
flex-direction: column;
}
.btn {
width: 100%;
justify-content: center;
}
.api-code {
font-size: 0.8rem;
}
}
.success-animation {
animation: pulse 2s infinite;
}
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.05); }
100% { transform: scale(1); }
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1 class="title">
<i class="fas fa-chart-line"></i>
Analysis Results
</h1>
</div>
<div class="input-display">
<div class="input-label">Your Input</div>
<div class="input-text">"{{ input_text }}"</div>
</div>
<div class="results-card">
<div class="sentiment-result
{% if prediction == 'Positive' %}positive
{% elif prediction == 'Neutral' %}neutral
{% elif prediction == 'Negative' %}negative
{% endif %}">
<div class="sentiment-icon">
{% if prediction == 'Positive' %}
<i class="fas fa-smile-beam"></i>
{% elif prediction == 'Neutral' %}
<i class="fas fa-meh"></i>
{% elif prediction == 'Negative' %}
<i class="fas fa-frown"></i>
{% endif %}
</div>
<div class="sentiment-label">{{ prediction }}</div>
</div>
<div class="confidence-section">
<div class="confidence-label">
<i class="fas fa-gauge-high"></i> Confidence Level
</div>
<div class="confidence-container">
<div class="confidence-bar" style="width: {{ (confidence * 100)|round(1) }}%"></div>
</div>
<div class="confidence-text">
<span class="confidence-percentage">{{ (confidence * 100)|round(1) }}%</span>
confident in this prediction
</div>
</div>
</div>
<div class="actions">
<a href="/" class="btn btn-primary">
<i class="fas fa-redo"></i>
Analyze Another
</a>
<button class="btn btn-secondary" onclick="shareResult()">
<i class="fas fa-share"></i>
Share Result
</button>
</div>
<div class="api-info">
<div class="api-title">
<i class="fas fa-code"></i>
Use this via API
</div>
<p style="color: #0369a1; margin-bottom: 1rem;">Integrate this sentiment analysis into your applications:</p>
<div class="api-code" id="apiCode">curl -X POST http://your-domain.com/api/analyze \
-H "Content-Type: application/json" \
-d '{"text": "{{ input_text|replace('"', '\\"') }}"}'</div>
<button class="copy-btn" onclick="copyApiCode()">
<i class="fas fa-copy"></i> Copy Code
</button>
</div>
</div>
<script>
// Animate confidence bar on load
window.addEventListener('load', function() {
const confidenceBar = document.querySelector('.confidence-bar');
const width = confidenceBar.style.width;
confidenceBar.style.width = '0%';
setTimeout(() => {
confidenceBar.style.width = width;
}, 300);
});
// Share result function
function shareResult() {
if (navigator.share) {
navigator.share({
title: 'Sentiment Analysis Result',
text: `The sentiment of this text is {{ prediction }} with {{ (confidence * 100)|round(1) }}% confidence: "{{ input_text }}"`,
url: window.location.href
});
} else {
// Fallback for browsers that don't support Web Share API
const resultText = `The sentiment is {{ prediction }} ({{ (confidence * 100)|round(1) }}% confident): "{{ input_text }}"`;
if (navigator.clipboard) {
navigator.clipboard.writeText(resultText).then(() => {
alert('Result copied to clipboard!');
});
} else {
// Final fallback
const textArea = document.createElement('textarea');
textArea.value = resultText;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
alert('Result copied to clipboard!');
}
}
}
// Copy API code function
function copyApiCode() {
const apiCode = document.getElementById('apiCode').textContent;
if (navigator.clipboard) {
navigator.clipboard.writeText(apiCode).then(() => {
const btn = event.target.closest('.copy-btn');
const originalText = btn.innerHTML;
btn.innerHTML = '<i class="fas fa-check"></i> Copied!';
btn.style.background = '#10b981';
setTimeout(() => {
btn.innerHTML = originalText;
btn.style.background = '#0369a1';
}, 2000);
});
} else {
// Fallback for older browsers
const textArea = document.createElement('textarea');
textArea.value = apiCode;
document.body.appendChild(textArea);
textArea.select();
document.execCommand('copy');
document.body.removeChild(textArea);
const btn = event.target.closest('.copy-btn');
const originalText = btn.innerHTML;
btn.innerHTML = '<i class="fas fa-check"></i> Copied!';
btn.style.background = '#10b981';
setTimeout(() => {
btn.innerHTML = originalText;
btn.style.background = '#0369a1';
}, 2000);
}
}
// Add success animation to results card
document.querySelector('.results-card').classList.add('success-animation');
setTimeout(() => {
document.querySelector('.results-card').classList.remove('success-animation');
}, 3000);
</script>
</body>
</html>