VibeCoderzVibeCoderz
Telegram
All Prompts
Marketing Analytics Dashboard with Chart.js preview
dashboardanalyticschartchart.jstailwindinteractiveresponsivestatstabs

Marketing Analytics Dashboard with Chart.js

Интерактивный дашборд маркетинговой аналитики с чартами Chart.js. Отображает KPI, каналы, статистику. Адаптивный дизайн, Tailwind CSS.

Prompt

<html lang="en"><head><meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Marketing Analytics Dashboard</title>
<!-- Inter font -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&amp;display=swap" rel="stylesheet">
<!-- Tailwind CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Chart.js -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
<!-- Lucide Icons -->
<script src="https://unpkg.com/lucide@latest"></script>
<link id="all-fonts-link-font-manrope" rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Manrope:wght@300;400;500;600;700;800&amp;display=swap"><style id="all-fonts-style-font-manrope">.font-manrope { font-family: 'Manrope', sans-serif !important; }</style></head>
<body class="min-h-screen antialiased selection:bg-emerald-400/20 selection:text-emerald-300 text-white font-[Inter] bg-gradient-to-br from-[#0f1419] via-[#1a1f29] to-[#0d1117]" style="background-image: radial-gradient(circle at 25% 25%, rgba(16, 185, 129, 0.05) 0%, transparent 50%), radial-gradient(circle at 75% 75%, rgba(59, 130, 246, 0.03) 0%, transparent 50%);">
  
  <!-- Ambient light effects -->
  <div class="fixed inset-0 overflow-hidden pointer-events-none">
    <div class="absolute -top-40 -right-40 w-80 h-80 bg-emerald-500/10 rounded-full blur-3xl animate-pulse" style="animation-duration: 4s;"></div>
    <div class="absolute -bottom-40 -left-40 w-80 h-80 bg-blue-500/8 rounded-full blur-3xl animate-pulse" style="animation-duration: 6s; animation-delay: 2s;"></div>
  </div>

  <main class="relative w-full pt-6 pr-6 pb-6 pl-6">
    <div class="max-w-7xl mr-auto ml-auto">
  
  <div class="shadow-black/50 ring-1 ring-white/[0.08] border-white/[0.05] overflow-hidden animate-[slideUp_0.8s_ease-out_0.2s_both] bg-gradient-to-b from-[#0f1419]/90 via-[#131a24]/95 to-[#0a0f14]/90 border rounded-3xl shadow-2xl backdrop-blur-xl">
    
    <!-- Enhanced Header -->
    <div class="sm:px-6 lg:px-6 pt-6 pr-6 pb-6 pl-6">
  <div class="flex items-center justify-between">
    <div class="flex items-center gap-4">
      <div class="h-10 w-10 rounded-xl bg-gradient-to-br from-emerald-500/20 to-emerald-600/10 flex items-center justify-center ring-1 ring-emerald-500/20 shadow-lg shadow-emerald-500/10">
        <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-lucide="trending-up" class="lucide lucide-trending-up h-5 w-5 text-emerald-400"><path d="M16 7h6v6"></path><path d="m22 7-8.5 8.5-5-5L2 17"></path></svg>
      </div>
      <div class="">
        <div class="text-lg font-semibold tracking-tight text-white font-sans" style="">Traffic Acquisition</div>
        <div class="text-sm text-white/50 font-sans" style="">Multi-channel performance overview</div>
      </div>
    </div>

    <div class="flex items-center gap-3">
      <div class="hidden sm:flex items-center gap-2 px-3 py-1.5 rounded-lg bg-emerald-500/10 ring-1 ring-emerald-500/20">
        <div class="h-2 w-2 rounded-full bg-emerald-400 animate-pulse"></div>
        <span class="text-sm text-emerald-300 font-medium font-sans" style="">Live</span>
      </div>
      
      <!-- Date Range Dropdown -->
      <div class="relative">
        <button id="dateRangeBtn" class="inline-flex items-center gap-2.5 h-9 px-4 rounded-xl bg-white/[0.06] hover:bg-white/[0.12] transition-all duration-200 ring-1 ring-white/10 hover:ring-white/20 text-sm text-white/90 hover:text-white shadow-lg backdrop-blur-sm">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-lucide="calendar" class="lucide lucide-calendar h-4 w-4"><path d="M8 2v4"></path><path d="M16 2v4"></path><rect width="18" height="18" x="3" y="4" rx="2"></rect><path d="M3 10h18"></path></svg>
          <span id="currentDateRange" class="font-sans">Last 30 Days</span>
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-lucide="chevron-down" class="lucide lucide-chevron-down h-4 w-4 opacity-70 transition-transform duration-200" id="dropdownArrow"><path d="m6 9 6 6 6-6"></path></svg>
        </button>
        
        <!-- Dropdown Menu -->
        <div id="dateRangeDropdown" class="hidden absolute right-0 mt-2 w-48 rounded-xl bg-[#0f1419]/95 backdrop-blur-xl ring-1 ring-white/10 shadow-2xl z-50">
          <div class="p-2">
            <button data-range="7" class="w-full text-left px-3 py-2 text-sm text-white/70 hover:text-white hover:bg-white/5 rounded-lg transition-colors">Last 7 Days</button>
            <button data-range="30" class="w-full text-left px-3 py-2 text-sm text-white/90 bg-white/5 rounded-lg">Last 30 Days</button>
            <button data-range="90" class="w-full text-left px-3 py-2 text-sm text-white/70 hover:text-white hover:bg-white/5 rounded-lg transition-colors">Last 90 Days</button>
            <button data-range="365" class="w-full text-left px-3 py-2 text-sm text-white/70 hover:text-white hover:bg-white/5 rounded-lg transition-colors">Last Year</button>
          </div>
        </div>
      </div>
      
      <!-- Menu Button -->
      <div class="relative">
        <button id="menuBtn" class="h-9 w-9 inline-flex items-center justify-center rounded-xl bg-white/[0.06] hover:bg-white/[0.12] transition-all duration-200 ring-1 ring-white/10 hover:ring-white/20 shadow-lg backdrop-blur-sm group">
          <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-lucide="more-horizontal" class="lucide lucide-more-horizontal h-4 w-4 text-white/70 group-hover:text-white/90"><circle cx="12" cy="12" r="1"></circle><circle cx="19" cy="12" r="1"></circle><circle cx="5" cy="12" r="1"></circle></svg>
        </button>
        
        <!-- Menu Dropdown -->
        <div id="menuDropdown" class="hidden absolute right-0 mt-2 w-52 rounded-xl bg-[#0f1419]/95 backdrop-blur-xl ring-1 ring-white/10 shadow-2xl z-50">
          <div class="p-2">
            <button class="w-full text-left px-3 py-2 text-sm text-white/70 hover:text-white hover:bg-white/5 rounded-lg transition-colors flex items-center gap-3">
              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7,10 12,15 17,10"></polyline><line x1="12" x2="12" y1="15" y2="3"></line></svg>
              Export Data
            </button>
            <button class="w-full text-left px-3 py-2 text-sm text-white/70 hover:text-white hover:bg-white/5 rounded-lg transition-colors flex items-center gap-3">
              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M12 20h9"></path><path d="M16.5 3.5a2.12 2.12 0 0 1 3 3L7 19l-4 1 1-4Z"></path></svg>
              Edit Report
            </button>
            <button class="w-full text-left px-3 py-2 text-sm text-white/70 hover:text-white hover:bg-white/5 rounded-lg transition-colors flex items-center gap-3">
              <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path></svg>
              Set Alerts
            </button>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

    <!-- Enhanced Tabs -->
    <div class="px-6 sm:px-8 lg:px-10 animate-[slideUp_0.8s_ease-out_0.4s_both]">
      <div class="flex items-center gap-8 text-sm" id="tabContainer">
        <button class="tab-btn active relative pb-4 font-medium transition-colors group" data-tab="performance">
          <span class="font-sans">Channel Performance</span>
          <span class="tab-indicator absolute -bottom-[1px] left-0 right-0 h-[2px] rounded-full bg-gradient-to-r from-emerald-400 to-emerald-500 shadow-lg shadow-emerald-500/50"></span>
        </button>
        <button class="tab-btn pb-4 text-white/50 hover:text-white/80 transition-colors relative group" data-tab="campaign">
          <span class="font-sans">Campaign Analysis</span>
          <span class="tab-indicator absolute -bottom-[1px] left-0 right-0 h-[2px] rounded-full bg-white/20 scale-x-0 group-hover:scale-x-100 transition-transform origin-left"></span>
        </button>
        <button class="tab-btn pb-4 text-white/50 hover:text-white/80 transition-colors relative group" data-tab="attribution">
          <span class="font-sans">Attribution Model</span>
          <span class="tab-indicator absolute -bottom-[1px] left-0 right-0 h-[2px] rounded-full bg-white/20 scale-x-0 group-hover:scale-x-100 transition-transform origin-left"></span>
        </button>
        <button class="tab-btn pb-4 text-white/50 hover:text-white/80 transition-colors relative group" data-tab="cohort">
          <span class="font-sans">Cohort Analysis</span>
          <span class="tab-indicator absolute -bottom-[1px] left-0 right-0 h-[2px] rounded-full bg-white/20 scale-x-0 group-hover:scale-x-100 transition-transform origin-left"></span>
        </button>
      </div>
    </div>

    <div class="h-px bg-gradient-to-r from-transparent via-white/10 to-transparent"></div>

    <!-- Enhanced Content -->
    <div class="sm:px-6 lg:px-6 pt-6 pr-6 pb-6 pl-6">
      <div class="flex flex-col xl:flex-row xl:items-start gap-6 xl:gap-6">
        
        <!-- Left: Enhanced Stats -->
        <div class="xl:w-[380px] flex-shrink-0 animate-[slideRight_0.8s_ease-out_0.6s_both]">
          <div class="space-y-6">
            <!-- Primary Metric -->
            <div class="relative">
              <div class="absolute -inset-2 bg-gradient-to-r from-emerald-500/10 via-transparent to-blue-500/10 rounded-2xl blur-xl"></div>
              <div class="relative">
                <div class="flex flex-col gap-2 text-center mb-3 items-start">
                  <div id="primaryMetric" class="md:text-8xl text-8xl font-light text-white tracking-tight font-manrope">+127%</div>
                </div>
                <div id="metricDescription" class="text-white/60 text-left mb-1">Total acquisition growth</div>
                <div id="metricDetails" class="text-sm text-white/40 font-sans">143,829 new users acquired</div>
              </div>
            </div>

            <!-- Real-time Stats Grid -->
            <div class="grid grid-cols-2 gap-6">
              <div class="p-4 rounded-xl bg-gradient-to-br from-white/[0.03] to-white/[0.01] ring-1 ring-white/[0.08]">
                <div class="text-2xl font-semibold text-white mb-1" id="ctrValue">3.42%</div>
                <div class="text-sm text-white/50">Avg CTR</div>
                <div class="flex items-center gap-1 mt-2">
                  <div class="h-1.5 w-1.5 rounded-full bg-emerald-400"></div>
                  <span class="text-xs text-emerald-400">+0.8%</span>
                </div>
              </div>
              <div class="p-4 rounded-xl bg-gradient-to-br from-white/[0.03] to-white/[0.01] ring-1 ring-white/[0.08]">
                <div class="text-2xl font-semibold text-white mb-1" id="cpcValue">$2.14</div>
                <div class="text-sm text-white/50">Avg CPC</div>
                <div class="flex items-center gap-1 mt-2">
                  <div class="h-1.5 w-1.5 rounded-full bg-rose-400"></div>
                  <span class="text-xs text-rose-400">+$0.23</span>
                </div>
              </div>
            </div>

            <!-- Interactive Insights Panel -->
            <div class="p-5 rounded-xl bg-gradient-to-br from-white/[0.03] to-white/[0.01] ring-1 ring-white/[0.08] backdrop-blur-sm">
              <div class="flex items-start gap-3 mb-4">
                <div class="h-8 w-8 rounded-lg bg-violet-500/15 flex items-center justify-center flex-shrink-0">
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" data-lucide="lightbulb" class="lucide lucide-lightbulb h-4 w-4 text-violet-400"><path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"></path><path d="M9 18h6"></path><path d="M10 22h4"></path></svg>
                </div>
                <div class="">
                  <h3 class="text-lg font-medium text-white mb-2">Strategic Insights</h3>
                  <div id="insightText" class="space-y-2.5 text-sm text-white/70 leading-relaxed"><p class="font-sans">Google Ads and LinkedIn are driving the highest quality leads with 2.3x better LTV. Consider reallocating 15% of Meta budget.</p></div>
                </div>
              </div>
              
              <div class="flex items-center gap-2 pt-3 border-t border-white/[0.06]">
                <button id="refreshInsights" class="text-xs text-violet-400 hover:text-violet-300 font-medium flex items-center gap-1 transition-colors">
                  <span class="font-sans">Refresh analysis</span>
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="h-3 w-3"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"></path><path d="M8 16H3v5"></path></svg>
                </button>
              </div>
            </div>
          </div>
        </div>

        <!-- Right: Interactive Chart -->
        <div class="flex-1 animate-[slideLeft_0.8s_ease-out_0.8s_both]">
  <div class="relative h-full">
    <div class="absolute -inset-1 bg-gradient-to-r from-emerald-500/5 via-blue-500/5 to-violet-500/5 rounded-2xl blur-sm"></div>
    <div class="relative h-full ring-1 ring-white/[0.08] flex flex-col bg-gradient-to-br from-white/[0.03] via-white/[0.01] to-transparent rounded-2xl pt-6 pr-6 pb-6 pl-6 backdrop-blur-sm">
      <div class="flex-1 h-full min-h-[400px]">
        <canvas id="trafficChart" class="h-full w-full" style="box-sizing: border-box; display: block; min-height: 400px; height: 400px; width: 778px;" width="1556" height="800"></canvas>
      </div>
    </div>
  </div>

  <!-- Dynamic date labels -->
  <div id="dateLabels" class="mt-6 grid grid-cols-7 gap-2 text-center">
          <div class="text-xs text-white/40 font-sans">
            Fri<span class="text-white/60 font-medium font-sans">Aug 15</span>
          </div>
        
          <div class="text-xs text-white/40 font-sans">
            Sat<span class="text-white/60 font-medium font-sans">Aug 16</span>
          </div>
        
          <div class="text-xs text-white/40 font-sans">
            Sun<span class="text-white/60 font-medium font-sans">Aug 17</span>
          </div>
        
          <div class="text-xs text-white/40 font-sans">
            Mon<span class="text-white/60 font-medium font-sans">Aug 18</span>
          </div>
        
          <div class="text-xs text-white/40 font-sans">
            Tue<span class="text-white/60 font-medium font-sans">Aug 19</span>
          </div>
        
          <div class="text-xs text-white/40 font-sans">
            Wed<span class="text-white/60 font-medium font-sans">Aug 20</span>
          </div>
        
          <div class="text-xs text-white/40 font-sans">
            Thu<span class="text-white/60 font-medium font-sans">Aug 21</span>
          </div>
        </div>
</div>
      </div>

      <!-- Interactive Channel Legend -->
      <div class="mt-6 animate-[fadeIn_0.8s_ease-out_1s_both]">
        <div class="grid grid-cols-2 md:grid-cols-5 gap-6" id="channelLegend">
          <div class="flex items-center gap-3 p-3 rounded-lg bg-gradient-to-br from-emerald-500/20 to-transparent ring-1 ring-white/5 hover:ring-white/10 transition-all duration-200 cursor-pointer group">
            <div class="h-3 w-3 rounded-full bg-gradient-to-r from-emerald-400 to-emerald-500"></div>
            <div class="flex-1 min-w-0">
              <div class="text-sm font-medium text-white group-hover:text-white transition-colors">Google Ads</div>
              <div class="text-xs text-white/50">43K users • 25.3%</div>
            </div>
          </div>
        
          <div class="flex items-center gap-3 p-3 rounded-lg bg-gradient-to-br from-amber-500/20 to-transparent ring-1 ring-white/5 hover:ring-white/10 transition-all duration-200 cursor-pointer group">
            <div class="h-3 w-3 rounded-full bg-gradient-to-r from-amber-400 to-amber-500"></div>
            <div class="flex-1 min-w-0">
              <div class="text-sm font-medium text-white group-hover:text-white transition-colors">Organic Search</div>
              <div class="text-xs text-white/50">32K users • 18.8%</div>
            </div>
          </div>
        
          <div class="flex items-center gap-3 p-3 rounded-lg bg-gradient-to-br from-rose-500/20 to-transparent ring-1 ring-white/5 hover:ring-white/10 transition-all duration-200 cursor-pointer group">
            <div class="h-3 w-3 rounded-full bg-gradient-to-r from-rose-400 to-rose-500"></div>
            <div class="flex-1 min-w-0">
              <div class="text-sm font-medium text-white group-hover:text-white transition-colors">Meta Ads</div>
              <div class="text-xs text-white/50">24K users • 14.1%</div>
            </div>
          </div>
        
          <div class="flex items-center gap-3 p-3 rounded-lg bg-gradient-to-br from-blue-500/20 to-transparent ring-1 ring-white/5 hover:ring-white/10 transition-all duration-200 cursor-pointer group">
            <div class="h-3 w-3 rounded-full bg-gradient-to-r from-blue-400 to-blue-500"></div>
            <div class="flex-1 min-w-0">
              <div class="text-sm font-medium text-white group-hover:text-white transition-colors">LinkedIn Ads</div>
              <div class="text-xs text-white/50">19K users • 11.2%</div>
            </div>
          </div>
        
          <div class="flex items-center gap-3 p-3 rounded-lg bg-gradient-to-br from-violet-500/20 to-transparent ring-1 ring-white/5 hover:ring-white/10 transition-all duration-200 cursor-pointer group">
            <div class="h-3 w-3 rounded-full bg-gradient-to-r from-violet-400 to-violet-500"></div>
            <div class="flex-1 min-w-0">
              <div class="text-sm font-medium text-white group-hover:text-white transition-colors">Direct/Email</div>
              <div class="text-xs text-white/50">25K users • 14.7%</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>
  </main>

  <style>
    @keyframes fadeIn {
      from { opacity: 0; }
      to { opacity: 1; }
    }
    @keyframes slideUp {
      from { opacity: 0; transform: translateY(20px); }
      to { opacity: 1; transform: translateY(0); }
    }
    @keyframes slideRight {
      from { opacity: 0; transform: translateX(-30px); }
      to { opacity: 1; transform: translateX(0); }
    }
    @keyframes slideLeft {
      from { opacity: 0; transform: translateX(30px); }
      to { opacity: 1; transform: translateX(0); }
    }

    .tab-btn.active {
      color: white;
    }
    .tab-btn.active .tab-indicator {
      background: linear-gradient(to right, #10b981, #059669);
      box-shadow: 0 0 10px rgba(16, 185, 129, 0.5);
      transform: scaleX(1);
    }
    .tab-btn:not(.active) .tab-indicator {
      background: rgba(255, 255, 255, 0.2);
      transform: scaleX(0);
      transition: transform 0.2s ease;
    }
    .tab-btn:not(.active):hover .tab-indicator {
      transform: scaleX(1);
    }
  </style>

  <script>
    // Initialize Lucide icons
    window.addEventListener('DOMContentLoaded', () => {
      lucide.createIcons();
    });

    // Data store
    const dataStore = {
      performance: {
        7: { data: [12, 19, 15, 8, 12, 7, 5], growth: '+89%', users: '45,231', insights: 'Short-term campaigns are performing well. Google Ads leading with strong weekend performance.' },
        30: { data: [43, 32, 24, 19, 25, 15, 12], growth: '+127%', users: '143,829', insights: 'Google Ads and LinkedIn are driving the highest quality leads with 2.3x better LTV. Consider reallocating 15% of Meta budget.' },
        90: { data: [65, 48, 38, 42, 35, 28, 22], growth: '+156%', users: '287,446', insights: 'Seasonal trends show strong Q4 performance. Organic search gaining momentum with improved SEO efforts.' },
        365: { data: [120, 95, 78, 85, 72, 58, 45], growth: '+203%', users: '1,247,832', insights: 'Year-over-year growth accelerating. Direct traffic and email campaigns showing excellent retention rates.' }
      },
      campaign: {
        7: { data: [8, 12, 9, 6, 10, 5, 4], growth: '+67%', users: '28,445', insights: 'Campaign optimization showing early results. A/B tests indicate 23% improvement in conversion rates.' },
        30: { data: [32, 28, 22, 18, 21, 14, 11], growth: '+94%', users: '98,234', insights: 'Top-performing campaigns identified. Creative refresh needed for underperforming ad sets in Meta platform.' },
        90: { data: [58, 44, 35, 38, 32, 26, 20], growth: '+134%', users: '215,678', insights: 'Campaign lifecycle analysis complete. Seasonal adjustments recommended for holiday performance boost.' },
        365: { data: [98, 78, 65, 72, 58, 48, 38], growth: '+178%', users: '892,445', insights: 'Annual campaign performance exceeding targets. Budget reallocation towards high-intent keywords recommended.' }
      },
      attribution: {
        7: { data: [15, 22, 18, 12, 16, 9, 7], growth: '+76%', users: '38,992', insights: 'Multi-touch attribution showing YouTube and email as key assist channels in conversion path.' },
        30: { data: [48, 38, 28, 23, 29, 18, 14], growth: '+112%', users: '156,772', insights: 'Attribution modeling reveals 40% of conversions involve 3+ touchpoints. Social proof crucial in final stage.' },
        90: { data: [72, 56, 42, 48, 38, 32, 25], growth: '+145%', users: '298,883', insights: 'Cross-device attribution patterns emerging. Mobile discovery to desktop conversion path most valuable.' },
        365: { data: [135, 108, 88, 95, 78, 65, 52], growth: '+189%', users: '1,189,223', insights: 'First-click attribution showing content marketing driving 60% more qualified leads than previously measured.' }
      },
      cohort: {
        7: { data: [10, 16, 13, 9, 11, 6, 5], growth: '+72%', users: '32,187', insights: 'Weekly cohorts showing improved day-7 retention. Onboarding flow changes having positive impact.' },
        30: { data: [38, 30, 21, 17, 23, 13, 10], growth: '+103%', users: '124,556', insights: 'Monthly cohort analysis reveals strong product-market fit signals. 30-day retention up 28% vs last period.' },
        90: { data: [68, 52, 39, 44, 34, 29, 23], growth: '+149%', users: '267,889', insights: 'Quarterly cohorts demonstrate sustainable growth. User lifetime value increasing across all acquisition channels.' },
        365: { data: [125, 98, 82, 89, 72, 61, 48], growth: '+195%', users: '1,098,776', insights: 'Annual cohorts show exceptional retention patterns. Premium feature adoption correlating with 3x higher LTV.' }
      }
    };

    const channels = [
      { name: 'Google Ads', color: 'emerald', bgColor: 'from-emerald-500/20', textColor: 'text-emerald-400' },
      { name: 'Organic Search', color: 'amber', bgColor: 'from-amber-500/20', textColor: 'text-amber-400' },
      { name: 'Meta Ads', color: 'rose', bgColor: 'from-rose-500/20', textColor: 'text-rose-400' },
      { name: 'LinkedIn Ads', color: 'blue', bgColor: 'from-blue-500/20', textColor: 'text-blue-400' },
      { name: 'Direct/Email', color: 'violet', bgColor: 'from-violet-500/20', textColor: 'text-violet-400' }
    ];

    let currentTab = 'performance';
    let currentDateRange = 30;
    let chart;

    // Initialize app
    function initializeApp() {
      setupEventListeners();
      updateChart();
      updateDateLabels();
      updateLegend();
      updateStats();
      startLiveUpdates();
    }

    function setupEventListeners() {
      // Date range dropdown
      const dateRangeBtn = document.getElementById('dateRangeBtn');
      const dateRangeDropdown = document.getElementById('dateRangeDropdown');
      const dropdownArrow = document.getElementById('dropdownArrow');

      dateRangeBtn.addEventListener('click', (e) => {
        e.stopPropagation();
        dateRangeDropdown.classList.toggle('hidden');
        dropdownArrow.style.transform = dateRangeDropdown.classList.contains('hidden') ? 'rotate(0deg)' : 'rotate(180deg)';
      });

      // Date range options
      dateRangeDropdown.querySelectorAll('button[data-range]').forEach(btn => {
        btn.addEventListener('click', (e) => {
          const range = parseInt(e.target.dataset.range);
          currentDateRange = range;
          document.getElementById('currentDateRange').textContent = `Last ${range === 365 ? 'Year' : range + ' Days'}`;
          
          // Update active state
          dateRangeDropdown.querySelectorAll('button').forEach(b => {
            b.className = 'w-full text-left px-3 py-2 text-sm text-white/70 hover:text-white hover:bg-white/5 rounded-lg transition-colors';
          });
          e.target.className = 'w-full text-left px-3 py-2 text-sm text-white/90 bg-white/5 rounded-lg';
          
          dateRangeDropdown.classList.add('hidden');
          dropdownArrow.style.transform = 'rotate(0deg)';
          
          updateChart();
          updateDateLabels();
          updateStats();
        });
      });

      // Menu dropdown
      const menuBtn = document.getElementById('menuBtn');
      const menuDropdown = document.getElementById('menuDropdown');

      menuBtn.addEventListener('click', (e) => {
        e.stopPropagation();
        menuDropdown.classList.toggle('hidden');
      });

      // Tab switching
      document.querySelectorAll('.tab-btn').forEach(btn => {
        btn.addEventListener('click', (e) => {
          const tabName = e.target.closest('.tab-btn').dataset.tab;
          switchTab(tabName);
        });
      });

      // Refresh insights
      document.getElementById('refreshInsights').addEventListener('click', refreshInsights);

      // Close dropdowns when clicking outside
      document.addEventListener('click', () => {
        dateRangeDropdown.classList.add('hidden');
        menuDropdown.classList.add('hidden');
        dropdownArrow.style.transform = 'rotate(0deg)';
      });
    }

    function switchTab(tabName) {
      currentTab = tabName;
      
      // Update tab appearance
      document.querySelectorAll('.tab-btn').forEach(btn => {
        btn.classList.remove('active');
        btn.classList.add('text-white/50');
        btn.classList.remove('text-white');
      });
      
      document.querySelector(`[data-tab="${tabName}"]`).classList.add('active');
      document.querySelector(`[data-tab="${tabName}"]`).classList.remove('text-white/50');
      document.querySelector(`[data-tab="${tabName}"]`).classList.add('text-white');

      updateChart();
      updateStats();
    }

    function updateChart() {
      const canvas = document.getElementById('trafficChart');
      const ctx = canvas.getContext('2d');
      const currentData = dataStore[currentTab][currentDateRange];

      function createGradient(color1, color2, opacity1 = 0.9, opacity2 = 0.1) {
        const { height } = canvas.getBoundingClientRect();
        const gradient = ctx.createLinearGradient(0, 0, 0, height);
        gradient.addColorStop(0, color1.replace('1)', `${opacity1})`));
        gradient.addColorStop(1, color2.replace('1)', `${opacity2})`));
        return gradient;
      }

      const emeraldGrad = createGradient('rgba(16,185,129,1)', 'rgba(16,185,129,1)', 0.95, 0.08);
      const amberGrad = createGradient('rgba(245,158,11,1)', 'rgba(245,158,11,1)', 0.95, 0.08);
      const roseGrad = createGradient('rgba(244,63,94,1)', 'rgba(244,63,94,1)', 0.95, 0.08);
      const blueGrad = createGradient('rgba(59,130,246,1)', 'rgba(59,130,246,1)', 0.95, 0.08);
      const violetGrad = createGradient('rgba(139,92,246,1)', 'rgba(139,92,246,1)', 0.95, 0.08);

      const data = {
        labels: channels.map(c => c.name.split(' ')[0]),
        datasets: [{
          data: currentData.data,
          backgroundColor: [emeraldGrad, amberGrad, roseGrad, blueGrad, violetGrad],
          borderColor: [
            'rgba(16,185,129,0.8)', 'rgba(245,158,11,0.8)', 'rgba(244,63,94,0.8)', 
            'rgba(59,130,246,0.8)', 'rgba(139,92,246,0.8)'
          ],
          borderWidth: 2,
          borderRadius: 16,
          borderSkipped: false,
          barPercentage: 0.7,
          categoryPercentage: 0.8
        }]
      };

      const options = {
        responsive: true,
        maintainAspectRatio: false,
        animation: { duration: 750, easing: 'easeInOutQuart' },
        plugins: {
          legend: { display: false },
          tooltip: {
            backgroundColor: 'rgba(15,20,25,0.95)',
            titleColor: '#fff',
            bodyColor: 'rgba(255,255,255,0.9)',
            padding: 16,
            displayColors: true,
            borderColor: 'rgba(255,255,255,0.1)',
            borderWidth: 1,
            cornerRadius: 12,
            titleFont: { family: 'Inter', size: 14, weight: '600' },
            bodyFont: { family: 'Inter', size: 13 },
            callbacks: {
              title: function(context) {
                return channels[context[0].dataIndex].name;
              },
              label: function(context) {
                return `${context.parsed.y}K visitors`;
              },
              afterBody: function(context) {
                const percentage = ((context[0].parsed.y / currentData.data.reduce((a, b) => a + b, 0)) * 100).toFixed(1);
                return `${percentage}% of total traffic`;
              }
            }
          }
        },
        layout: { padding: { top: 20, right: 20, bottom: 20, left: 20 } },
        scales: {
          x: {
            grid: { display: false, drawBorder: false },
            ticks: { 
              color: 'rgba(255,255,255,0.4)', 
              font: { family: 'Inter', size: 12, weight: '500' },
              padding: 12
            },
            border: { display: false }
          },
          y: {
            grid: { color: 'rgba(255,255,255,0.05)', drawBorder: false },
            ticks: { 
              color: 'rgba(255,255,255,0.4)',
              font: { family: 'Inter', size: 11 },
              padding: 16,
              callback: function(value) { return value + 'K'; }
            },
            border: { display: false }
          }
        },
        interaction: { intersect: false, mode: 'index' }
      };

      if (chart) chart.destroy();
      chart = new Chart(ctx, { type: 'bar', data, options });
    }

    function updateDateLabels() {
      const dateLabels = document.getElementById('dateLabels');
      const baseDate = new Date();
      const labels = [];

      for (let i = 6; i >= 0; i--) {
        const date = new Date(baseDate);
        date.setDate(date.getDate() - i);
        
        const dayName = date.toLocaleDateString('en-US', { weekday: 'short' });
        const monthDay = date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
        
        labels.push(`
          <div class="text-xs text-white/40 font-sans">
            ${dayName}<span class="text-white/60 font-medium font-sans">${monthDay}</span>
          </div>
        `);
      }

      dateLabels.innerHTML = labels.join('');
    }

    function updateLegend() {
      const legend = document.getElementById('channelLegend');
      const currentData = dataStore[currentTab][currentDateRange];
      
      legend.innerHTML = channels.map((channel, index) => {
        const value = currentData.data[index];
        const percentage = ((value / currentData.data.reduce((a, b) => a + b, 0)) * 100).toFixed(1);
        
        return `
          <div class="flex items-center gap-3 p-3 rounded-lg bg-gradient-to-br ${channel.bgColor} to-transparent ring-1 ring-white/5 hover:ring-white/10 transition-all duration-200 cursor-pointer group">
            <div class="h-3 w-3 rounded-full bg-gradient-to-r from-${channel.color}-400 to-${channel.color}-500"></div>
            <div class="flex-1 min-w-0">
              <div class="text-sm font-medium text-white group-hover:text-white transition-colors">${channel.name}</div>
              <div class="text-xs text-white/50">${value}K users • ${percentage}%</div>
            </div>
          </div>
        `;
      }).join('');
    }

    function updateStats() {
      const currentData = dataStore[currentTab][currentDateRange];
      
      document.getElementById('primaryMetric').textContent = currentData.growth;
      document.getElementById('metricDescription').textContent = getMetricDescription(currentTab);
      document.getElementById('metricDetails').textContent = `${currentData.users} new users acquired`;
      
      // Update insight text
      document.getElementById('insightText').innerHTML = `<p class="font-sans">${currentData.insights}</p>`;
    }

    function getMetricDescription(tab) {
      const descriptions = {
        performance: 'Total acquisition growth',
        campaign: 'Campaign performance improvement',
        attribution: 'Attribution model effectiveness',
        cohort: 'Cohort retention improvement'
      };
      return descriptions[tab] || 'Total acquisition growth';
    }

    function refreshInsights() {
      const btn = document.getElementById('refreshInsights');
      const icon = btn.querySelector('svg');
      
      // Animate refresh button
      icon.style.transform = 'rotate(360deg)';
      icon.style.transition = 'transform 0.5s ease';
      
      setTimeout(() => {
        icon.style.transform = 'rotate(0deg)';
        updateStats();
      }, 500);
    }

    function startLiveUpdates() {
      // Simulate live CTR and CPC updates
      setInterval(() => {
        const ctr = (3.2 + Math.random() * 0.5).toFixed(2);
        const cpc = (2.0 + Math.random() * 0.4).toFixed(2);
        
        document.getElementById('ctrValue').textContent = ctr + '%';
        document.getElementById('cpcValue').textContent = '$' + cpc;
      }, 5000);

      // Simulate chart data updates every 30 seconds
      setInterval(() => {
        const currentData = dataStore[currentTab][currentDateRange];
        const variation = 0.1; // 10% variation
        
        currentData.data = currentData.data.map(value => {
          const change = (Math.random() - 0.5) * variation * value;
          return Math.max(1, Math.round(value + change));
        });
        
        updateChart();
        updateLegend();
      }, 30000);
    }

    // Initialize when DOM is loaded
    document.addEventListener('DOMContentLoaded', initializeApp);
  </script>

</body></html>
All Prompts