Spaces:
Running
Running
| <html lang="en" class="dark"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>TrackMail Pro - Email Tracking Dashboard</title> | |
| <link rel="icon" type="image/x-icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23a855f7'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'/%3E%3Cpath d='M22 6l-10 7L2 6'/%3E%3C/svg%3E"> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/animejs/lib/anime.iife.min.js"></script> | |
| <script src="https://unpkg.com/feather-icons"></script> | |
| <script> | |
| tailwind.config = { | |
| darkMode: 'class', | |
| theme: { | |
| extend: { | |
| colors: { | |
| primary: { | |
| 50: '#faf5ff', | |
| 100: '#f3e8ff', | |
| 200: '#e9d5ff', | |
| 300: '#d8b4fe', | |
| 400: '#c084fc', | |
| 500: '#a855f7', | |
| 600: '#9333ea', | |
| 700: '#7e22ce', | |
| 800: '#6b21a8', | |
| 900: '#581c87', | |
| }, | |
| secondary: { | |
| 50: '#f0f9ff', | |
| 100: '#e0f2fe', | |
| 200: '#bae6fd', | |
| 300: '#7dd3fc', | |
| 400: '#38bdf8', | |
| 500: '#0ea5e9', | |
| 600: '#0284c7', | |
| 700: '#0369a1', | |
| 800: '#075985', | |
| 900: '#0c4a6e', | |
| } | |
| } | |
| } | |
| } | |
| } | |
| </script> | |
| <style> | |
| .glassmorphism { | |
| background: rgba(30, 41, 59, 0.4); | |
| backdrop-filter: blur(10px); | |
| border: 1px solid rgba(168, 85, 247, 0.1); | |
| } | |
| .tracking-pixel { | |
| width: 1px; | |
| height: 1px; | |
| opacity: 0; | |
| position: absolute; | |
| } | |
| .pulse-ring { | |
| animation: pulse-ring 2s cubic-bezier(0.455, 0.03, 0.515, 0.955) infinite; | |
| } | |
| @keyframes pulse-ring { | |
| 0% { transform: scale(0.33); } | |
| 80%, 100% { opacity: 0; } | |
| } | |
| .slide-in { | |
| animation: slideIn 0.3s ease-out; | |
| } | |
| @keyframes slideIn { | |
| from { transform: translateX(-100%); opacity: 0; } | |
| to { transform: translateX(0); opacity: 1; } | |
| } | |
| </style> | |
| </head> | |
| <body class="bg-slate-900 text-white min-h-screen"> | |
| <!-- Background Animation --> | |
| <div class="fixed inset-0 overflow-hidden"> | |
| <div class="absolute -top-40 -right-40 w-80 h-80 bg-primary-500 rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-pulse"></div> | |
| <div class="absolute -bottom-40 -left-40 w-80 h-80 bg-secondary-500 rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-pulse animation-delay-2000"></div> | |
| </div> | |
| <!-- Navigation --> | |
| <nav class="relative z-10 glassmorphism border-b border-slate-700"> | |
| <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8"> | |
| <div class="flex justify-between items-center h-16"> | |
| <div class="flex items-center space-x-2"> | |
| <i data-feather="mail" class="text-primary-400 w-6 h-6"></i> | |
| <span class="text-xl font-bold bg-gradient-to-r from-primary-400 to-secondary-400 bg-clip-text text-transparent">TrackMail Pro</span> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <button class="p-2 rounded-lg glassmorphism hover:bg-slate-700 transition-colors"> | |
| <i data-feather="bell" class="w-5 h-5"></i> | |
| </button> | |
| <button class="p-2 rounded-lg glassmorphism hover:bg-slate-700 transition-colors"> | |
| <i data-feather="settings" class="w-5 h-5"></i> | |
| </button> | |
| </div> | |
| </div> | |
| </div> | |
| </nav> | |
| <!-- Main Content --> | |
| <main class="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> | |
| <!-- Stats Overview --> | |
| <div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8"> | |
| <div class="glassmorphism rounded-xl p-6"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <p class="text-sm text-slate-400">Total Emails</p> | |
| <p class="text-2xl font-bold text-white" id="totalEmails">0</p> | |
| </div> | |
| <div class="p-3 rounded-lg bg-primary-500/20"> | |
| <i data-feather="send" class="w-6 h-6 text-primary-400"></i> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="glassmorphism rounded-xl p-6"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <p class="text-sm text-slate-400">Opened</p> | |
| <p class="text-2xl font-bold text-white" id="openedEmails">0</p> | |
| </div> | |
| <div class="p-3 rounded-lg bg-green-500/20"> | |
| <i data-feather="eye" class="w-6 h-6 text-green-400"></i> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="glassmorphism rounded-xl p-6"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <p class="text-sm text-slate-400">Click Rate</p> | |
| <p class="text-2xl font-bold text-white" id="clickRate">0%</p> | |
| </div> | |
| <div class="p-3 rounded-lg bg-secondary-500/20"> | |
| <i data-feather="mouse-pointer" class="w-6 h-6 text-secondary-400"></i> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="glassmorphism rounded-xl p-6"> | |
| <div class="flex items-center justify-between"> | |
| <div> | |
| <p class="text-sm text-slate-400">Avg. Time</p> | |
| <p class="text-2xl font-bold text-white" id="avgTime">0s</p> | |
| </div> | |
| <div class="p-3 rounded-lg bg-orange-500/20"> | |
| <i data-feather="clock" class="w-6 h-6 text-orange-400"></i> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Email Composer --> | |
| <div class="glassmorphism rounded-xl p-6 mb-8"> | |
| <h2 class="text-xl font-semibold mb-4 flex items-center"> | |
| <i data-feather="edit-3" class="w-5 h-5 mr-2 text-primary-400"></i> | |
| Compose Tracking Email | |
| </h2> | |
| <form id="emailForm" class="space-y-4"> | |
| <div> | |
| <label class="block text-sm font-medium text-slate-300 mb-2">To</label> | |
| <input type="email" id="toEmail" required class="w-full px-4 py-2 bg-slate-800 border border-slate-600 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all" placeholder="recipient@example.com"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-slate-300 mb-2">Subject</label> | |
| <input type="text" id="subject" required class="w-full px-4 py-2 bg-slate-800 border border-slate-600 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all" placeholder="Your awesome subject"> | |
| </div> | |
| <div> | |
| <label class="block text-sm font-medium text-slate-300 mb-2">Message</label> | |
| <textarea id="message" rows="6" class="w-full px-4 py-2 bg-slate-800 border border-slate-600 rounded-lg focus:ring-2 focus:ring-primary-500 focus:border-transparent transition-all" placeholder="Write your message here..."></textarea> | |
| </div> | |
| <div class="flex items-center space-x-4"> | |
| <button type="submit" class="px-6 py-2 bg-primary-600 hover:bg-primary-700 rounded-lg font-medium transition-colors flex items-center"> | |
| <i data-feather="send" class="w-4 h-4 mr-2"></i> | |
| Send & Track | |
| </button> | |
| <label class="flex items-center space-x-2"> | |
| <input type="checkbox" id="enableTracking" checked class="rounded text-primary-600 focus:ring-primary-500"> | |
| <span class="text-sm text-slate-300">Enable tracking</span> | |
| </label> | |
| </div> | |
| </form> | |
| </div> | |
| <!-- Email List --> | |
| <div class="glassmorphism rounded-xl p-6"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h2 class="text-xl font-semibold flex items-center"> | |
| <i data-feather="inbox" class="w-5 h-5 mr-2 text-primary-400"></i> | |
| Tracked Emails | |
| </h2> | |
| <button class="text-sm text-primary-400 hover:text-primary-300 flex items-center"> | |
| <i data-feather="refresh-cw" class="w-4 h-4 mr-1"></i> | |
| Refresh | |
| </button> | |
| </div> | |
| <div id="emailList" class="space-y-3"> | |
| <!-- Email items will be dynamically added here --> | |
| </div> | |
| </div> | |
| </main> | |
| <!-- Toast Notification --> | |
| <div id="toast" class="fixed top-20 right-4 glassmorphism px-4 py-3 rounded-lg shadow-lg transform translate-x-full transition-transform duration-300 z-50"> | |
| <div class="flex items-center space-x-2"> | |
| <i data-feather="check-circle" class="w-5 h-5 text-green-400"></i> | |
| <span id="toastMessage">Email sent successfully!</span> | |
| </div> | |
| </div> | |
| <script> | |
| // Sample data | |
| let emails = []; | |
| let emailId = 1; | |
| // Initialize feather icons | |
| feather.replace(); | |
| // Form submission | |
| document.getElementById('emailForm').addEventListener('submit', function(e) { | |
| e.preventDefault(); | |
| const toEmail = document.getElementById('toEmail').value; | |
| const subject = document.getElementById('subject').value; | |
| const message = document.getElementById('message').value; | |
| const enableTracking = document.getElementById('enableTracking').checked; | |
| const email = { | |
| id: emailId++, | |
| to: toEmail, | |
| subject: subject, | |
| message: message, | |
| sentAt: new Date(), | |
| opened: false, | |
| openedAt: null, | |
| clicks: 0, | |
| timeSpent: 0, | |
| trackingEnabled: enableTracking | |
| }; | |
| emails.unshift(email); | |
| renderEmails(); | |
| updateStats(); | |
| showToast('Email sent and tracking enabled!'); | |
| // Reset form | |
| this.reset(); | |
| // Simulate email opening after random delay | |
| if (enableTracking) { | |
| setTimeout(() => simulateEmailOpen(email.id), Math.random() * 10000 + 5000); | |
| } | |
| }); | |
| function renderEmails() { | |
| const emailList = document.getElementById('emailList'); | |
| emailList.innerHTML = ''; | |
| emails.forEach(email => { | |
| const emailDiv = document.createElement('div'); | |
| emailDiv.className = 'slide-in'; | |
| emailDiv.innerHTML = ` | |
| <div class="flex items-center justify-between p-4 bg-slate-800/50 rounded-lg border border-slate-700"> | |
| <div class="flex-1"> | |
| <div class="flex items-center space-x-3"> | |
| <div class="w-2 h-2 rounded-full ${email.opened ? 'bg-green-400' : 'bg-slate-500'} ${email.opened ? 'pulse-ring' : ''}"></div> | |
| <div> | |
| <p class="font-medium">${email.to}</p> | |
| <p class="text-sm text-slate-400">${email.subject}</p> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="flex items-center space-x-4 text-sm"> | |
| <div class="text-center"> | |
| <p class="text-slate-400">Opened</p> | |
| <p class="font-medium">${email.opened ? 'Yes' : 'No'}</p> | |
| </div> | |
| <div class="text-center"> | |
| <p class="text-slate-400">Clicks</p> | |
| <p class="font-medium">${email.clicks}</p> | |
| </div> | |
| <div class="text-center"> | |
| <p class="text-slate-400">Time</p> | |
| <p class="font-medium">${email.timeSpent}s</p> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| emailList.appendChild(emailDiv); | |
| }); | |
| } | |
| function updateStats() { | |
| const total = emails.length; | |
| const opened = emails.filter(e => e.opened).length; | |
| const clicks = emails.reduce((sum, e) => sum + e.clicks, 0); | |
| const avgTime = emails.length > 0 ? Math.round(emails.reduce((sum, e) => sum + e.timeSpent, 0) / emails.length) : 0; | |
| document.getElementById('totalEmails').textContent = total; | |
| document.getElementById('openedEmails').textContent = opened; | |
| document.getElementById('clickRate').textContent = total > 0 ? Math.round((clicks / total) * 100) + '%' : '0%'; | |
| document.getElementById('avgTime').textContent = avgTime + 's'; | |
| } | |
| function simulateEmailOpen(emailId) { | |
| const email = emails.find(e => e.id === emailId); | |
| if (email && !email.opened) { | |
| email.opened = true; | |
| email.openedAt = new Date(); | |
| email.timeSpent = Math.floor(Math.random() * 120) + 10; | |
| email.clicks = Math.random() > 0.7 ? Math.floor(Math.random() * 5) + 1 : 0; | |
| renderEmails(); | |
| updateStats(); | |
| showToast(`Email to ${email.to} was opened!`); | |
| // Animate the stats update | |
| anime({ | |
| targets: '.glassmorphism', | |
| scale: [1, 1.02, 1], | |
| duration: 300, | |
| easing: 'easeInOutQuad' | |
| }); | |
| } | |
| } | |
| function showToast(message) { | |
| const toast = document.getElementById('toast'); | |
| const toastMessage = document.getElementById('toastMessage'); | |
| toastMessage.textContent = message; | |
| toast.classList.remove('translate-x-full'); | |
| setTimeout(() => { | |
| toast.classList.add('translate-x-full'); | |
| }, 3000); | |
| } | |
| // Initial render | |
| renderEmails(); | |
| updateStats(); | |
| </script> | |
| </body> | |
| </html> | |