|
|
@@ -0,0 +1,215 @@
|
|
|
+<script>
|
|
|
+ import { TrendingUp, Shield, DollarSign, CheckCircle, Heart, Activity } from 'lucide-svelte';
|
|
|
+ import { Chart, Svg, Axis, Line, Spline, Highlight } from 'layerchart';
|
|
|
+ import { format } from 'date-fns';
|
|
|
+ import { ptBR } from 'date-fns/locale';
|
|
|
+ import { mockEvolucaoSentimentosData, mockMonitoramentoPlaybooksData } from '$lib/core/models/mock-data.js';
|
|
|
+
|
|
|
+ // Mock Data for KPIs
|
|
|
+ const mockEvolucaoKpis = {
|
|
|
+ churnEvitado: '--',
|
|
|
+ roiUpsell: '--',
|
|
|
+ scoreMedio: '--',
|
|
|
+ taxaEvolucao: '--',
|
|
|
+ conversaoEmocao: '--'
|
|
|
+ };
|
|
|
+
|
|
|
+ function formatSentimentAxis(val) {
|
|
|
+ if (val === 1) return 'Pos.';
|
|
|
+ if (val === 0) return 'Neutro';
|
|
|
+ if (val === -1) return 'Neg.';
|
|
|
+ return val.toFixed(1);
|
|
|
+ }
|
|
|
+</script>
|
|
|
+
|
|
|
+<svelte:head>
|
|
|
+ <title>Evolução - Nettown Analytics</title>
|
|
|
+</svelte:head>
|
|
|
+
|
|
|
+<div class="mx-auto max-w-[1600px] space-y-6">
|
|
|
+ <!-- Top Section: Header, Filters, KPIs -->
|
|
|
+ <div class="rounded-xl border border-slate-200 bg-white p-5 md:p-8 shadow-sm transition-colors duration-200 dark:border-slate-800 dark:bg-[#161f30]">
|
|
|
+ <div class="flex items-center gap-3 mb-8">
|
|
|
+ <div class="h-8 w-8 shrink-0 rounded-lg bg-blue-500/20 text-blue-500 flex items-center justify-center">
|
|
|
+ <TrendingUp size={20} strokeWidth={2.5} />
|
|
|
+ </div>
|
|
|
+ <h1 class="text-xl font-bold text-slate-900 dark:text-white">Evolução: Observatório de Resultados</h1>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Filters -->
|
|
|
+ <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4 w-full text-sm mb-12">
|
|
|
+ <div class="flex flex-col gap-1.5">
|
|
|
+ <span class="text-xs font-semibold text-slate-500 dark:text-slate-400">Período</span>
|
|
|
+ <select class="rounded-md border border-slate-200 bg-white px-3 py-1.5 text-slate-900 focus:border-indigo-500 focus:outline-none dark:border-slate-700 dark:bg-[#0f172a] dark:text-slate-200">
|
|
|
+ <option>Últimos 7 dias</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ <div class="flex flex-col gap-1.5">
|
|
|
+ <span class="text-xs font-semibold text-slate-500 dark:text-slate-400">Unidade</span>
|
|
|
+ <select class="rounded-md border border-slate-200 bg-white px-3 py-1.5 text-slate-900 focus:border-indigo-500 focus:outline-none dark:border-slate-700 dark:bg-[#0f172a] dark:text-slate-200">
|
|
|
+ <option>Sem segmento</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ <div class="flex flex-col gap-1.5">
|
|
|
+ <span class="text-xs font-semibold text-slate-500 dark:text-slate-400">Área</span>
|
|
|
+ <select class="rounded-md border border-slate-200 bg-white px-3 py-1.5 text-slate-900 focus:border-indigo-500 focus:outline-none dark:border-slate-700 dark:bg-[#0f172a] dark:text-slate-200">
|
|
|
+ <option>Sem segmento de setor</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ <div class="flex flex-col gap-1.5">
|
|
|
+ <span class="text-xs font-semibold text-slate-500 dark:text-slate-400">Linha</span>
|
|
|
+ <select class="rounded-md border border-slate-200 bg-white px-3 py-1.5 text-slate-900 focus:border-indigo-500 focus:outline-none dark:border-slate-700 dark:bg-[#0f172a] dark:text-slate-200">
|
|
|
+ <option>Todas</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ <div class="flex flex-col gap-1.5">
|
|
|
+ <span class="text-xs font-semibold text-slate-500 dark:text-slate-400">Sentimento</span>
|
|
|
+ <select class="rounded-md border border-slate-200 bg-white px-3 py-1.5 text-slate-900 focus:border-indigo-500 focus:outline-none dark:border-slate-700 dark:bg-[#0f172a] dark:text-slate-200">
|
|
|
+ <option>Todos</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ <div class="flex flex-col gap-1.5">
|
|
|
+ <span class="text-xs font-semibold text-slate-500 dark:text-slate-400">Fonte</span>
|
|
|
+ <select class="rounded-md border border-slate-200 bg-white px-3 py-1.5 text-slate-900 focus:border-indigo-500 focus:outline-none dark:border-slate-700 dark:bg-[#0f172a] dark:text-slate-200">
|
|
|
+ <option>Todas</option>
|
|
|
+ </select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- KPIs -->
|
|
|
+ <div class="grid grid-cols-2 md:grid-cols-5 gap-6 w-full pb-4">
|
|
|
+ <div class="flex flex-col items-center justify-center text-center">
|
|
|
+ <Shield size={24} class="text-red-500 mb-3 mx-auto" />
|
|
|
+ <div class="text-3xl font-bold text-slate-900 dark:text-white mb-1">{mockEvolucaoKpis.churnEvitado}</div>
|
|
|
+ <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400">Churn Evitado (Valor)</div>
|
|
|
+ </div>
|
|
|
+ <div class="flex flex-col items-center justify-center text-center">
|
|
|
+ <DollarSign size={24} class="text-emerald-500 mb-3 mx-auto" />
|
|
|
+ <div class="text-3xl font-bold text-slate-900 dark:text-white mb-1">{mockEvolucaoKpis.roiUpsell}</div>
|
|
|
+ <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400">ROI de Upsell</div>
|
|
|
+ </div>
|
|
|
+ <div class="flex flex-col items-center justify-center text-center">
|
|
|
+ <CheckCircle size={24} class="text-amber-500 mb-3 mx-auto" />
|
|
|
+ <div class="text-3xl font-bold text-slate-900 dark:text-white mb-1">{mockEvolucaoKpis.scoreMedio}</div>
|
|
|
+ <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400">Score Médio Geral</div>
|
|
|
+ </div>
|
|
|
+ <div class="flex flex-col items-center justify-center text-center">
|
|
|
+ <TrendingUp size={24} class="text-blue-400 mb-3 mx-auto" />
|
|
|
+ <div class="text-3xl font-bold text-slate-900 dark:text-white mb-1">{mockEvolucaoKpis.taxaEvolucao}</div>
|
|
|
+ <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400">Taxa de Evolução</div>
|
|
|
+ </div>
|
|
|
+ <div class="flex flex-col items-center justify-center text-center">
|
|
|
+ <Heart size={24} class="text-pink-500 mb-3 mx-auto" />
|
|
|
+ <div class="text-3xl font-bold text-slate-900 dark:text-white mb-1">{mockEvolucaoKpis.conversaoEmocao}</div>
|
|
|
+ <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400">Conversão de Emoção</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Charts Area -->
|
|
|
+ <div class="grid grid-cols-1 gap-6">
|
|
|
+ <!-- Chart 1: Evolucao dos Sentimentos Geral -->
|
|
|
+ <div class="rounded-xl border border-slate-200 bg-white p-5 md:p-6 shadow-sm transition-colors duration-200 dark:border-slate-800 dark:bg-[#161f30] h-[360px] flex flex-col">
|
|
|
+ <h2 class="text-base font-bold text-slate-900 dark:text-white mb-4">Evolução dos Sentimentos Geral</h2>
|
|
|
+ <div class="h-full w-full flex-1">
|
|
|
+ <Chart
|
|
|
+ data={mockEvolucaoSentimentosData}
|
|
|
+ x={d => d.date}
|
|
|
+ y={d => d.value}
|
|
|
+ yDomain={[-1, 1]}
|
|
|
+ padding={{ top: 10, right: 10, bottom: 20, left: 40 }}
|
|
|
+ >
|
|
|
+ <Svg>
|
|
|
+ <Axis
|
|
|
+ placement="left"
|
|
|
+ grid={{ class: 'stroke-slate-200 dark:stroke-slate-700', strokeDasharray: '2 2' }}
|
|
|
+ class="fill-slate-500 text-xs dark:fill-slate-400"
|
|
|
+ format={formatSentimentAxis}
|
|
|
+ ticks={[-1, -0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1]}
|
|
|
+ />
|
|
|
+ <Axis
|
|
|
+ placement="bottom"
|
|
|
+ format={(d) => format(d, 'dd/MM')}
|
|
|
+ class="fill-slate-500 text-xs dark:fill-slate-400"
|
|
|
+ />
|
|
|
+ <Spline stroke="#6366f1" strokeWidth={3} />
|
|
|
+ <Highlight
|
|
|
+ points={{
|
|
|
+ fill: '#6366f1',
|
|
|
+ class: 'stroke-white dark:stroke-slate-900',
|
|
|
+ strokeWidth: 2
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </Svg>
|
|
|
+ </Chart>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- Chart 2: Monitoramento de Playbooks -->
|
|
|
+ <div class="rounded-xl border border-slate-200 bg-white p-5 md:p-6 shadow-sm transition-colors duration-200 dark:border-slate-800 dark:bg-[#161f30] h-[360px] flex flex-col">
|
|
|
+ <div class="flex items-center justify-between mb-4">
|
|
|
+ <div class="flex items-center gap-4">
|
|
|
+ <h2 class="text-base font-bold text-slate-900 dark:text-white">Monitoramento de Playbooks (Prospecção Anônima)</h2>
|
|
|
+ <div class="flex items-center text-sm font-medium">
|
|
|
+ <button class="px-3 py-1 text-slate-400 hover:text-white transition-colors">Gráfico</button>
|
|
|
+ <button class="px-3 py-1 text-slate-400 hover:text-white transition-colors">Lista</button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="flex items-center gap-6">
|
|
|
+ <div class="flex flex-col items-end">
|
|
|
+ <span class="text-[10px] font-bold text-slate-500 uppercase tracking-wider">Total do Período</span>
|
|
|
+ <div class="flex gap-1 text-sm font-bold">
|
|
|
+ <span class="text-indigo-400">148</span>
|
|
|
+ <span class="text-slate-500">/</span>
|
|
|
+ <span class="text-emerald-400">5</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="flex items-center gap-4 text-xs font-medium text-slate-400">
|
|
|
+ <div class="flex items-center gap-1.5">
|
|
|
+ <div class="w-3 h-3 rounded-sm bg-indigo-500"></div>
|
|
|
+ Novos Detectados
|
|
|
+ </div>
|
|
|
+ <div class="flex items-center gap-1.5">
|
|
|
+ <div class="w-3 h-3 rounded-sm bg-emerald-500"></div>
|
|
|
+ Cadastrados Convertidos
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="h-full w-full flex-1">
|
|
|
+ <Chart
|
|
|
+ data={mockMonitoramentoPlaybooksData}
|
|
|
+ x={d => d.date}
|
|
|
+ yDomain={[0, 60]}
|
|
|
+ padding={{ top: 10, right: 10, bottom: 20, left: 30 }}
|
|
|
+ >
|
|
|
+ <Svg>
|
|
|
+ <Axis
|
|
|
+ placement="left"
|
|
|
+ grid={{ class: 'stroke-slate-200 dark:stroke-slate-700', strokeDasharray: '2 2' }}
|
|
|
+ class="fill-slate-500 text-xs dark:fill-slate-400"
|
|
|
+ ticks={[0, 10, 20, 30, 40, 50, 60]}
|
|
|
+ />
|
|
|
+ <Axis
|
|
|
+ placement="bottom"
|
|
|
+ format={(d) => format(d, 'dd/MM')}
|
|
|
+ class="fill-slate-500 text-xs dark:fill-slate-400"
|
|
|
+ />
|
|
|
+
|
|
|
+ <Spline y={d => d.novos} stroke="#6366f1" strokeWidth={3} />
|
|
|
+ <Spline y={d => d.convertidos} stroke="#10b981" strokeWidth={3} />
|
|
|
+
|
|
|
+ <Highlight
|
|
|
+ points={{
|
|
|
+ fill: 'white',
|
|
|
+ class: 'stroke-slate-400 dark:stroke-slate-500',
|
|
|
+ strokeWidth: 2
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </Svg>
|
|
|
+ </Chart>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</div>
|