| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- <script>
- import { Users, AlertTriangle, DollarSign, Compass, UserRound, TrendingUp, HeartHandshake } from 'lucide-svelte';
- import { mockPersonasKpis, mockPersonas } from '$lib/core/models/mock-data.js';
- let selectedPersona = $state(null);
- function openPersonaDetails(persona) {
- selectedPersona = persona;
- }
- function closePersonaDetails() {
- selectedPersona = null;
- }
- </script>
- <svelte:head>
- <title>Laboratório de Personas - 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-amber-500/20 text-amber-500 flex items-center justify-center">
- <Compass size={20} strokeWidth={2.5} />
- </div>
- <h1 class="text-xl font-bold text-slate-900 dark:text-white">Expansão: Laboratório de Personas</h1>
- </div>
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 w-full text-sm mb-12">
- <div class="flex items-center justify-center gap-2">
- <span class="text-slate-500 dark:text-slate-400 whitespace-nowrap">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 items-center justify-center gap-2">
- <span class="text-slate-500 dark:text-slate-400 whitespace-nowrap">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 items-center justify-center gap-2">
- <span class="text-slate-500 dark:text-slate-400 whitespace-nowrap">Á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 items-center justify-center gap-2">
- <span class="text-slate-500 dark:text-slate-400 whitespace-nowrap">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>
- <!-- KPIs -->
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 w-full pb-4">
- <div class="flex flex-col items-center justify-center text-center">
- <UserRound size={24} class="text-amber-500 mb-3 mx-auto" />
- <div class="text-3xl font-bold text-slate-900 dark:text-white mb-1">{mockPersonasKpis.ativas}</div>
- <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400">Personas Ativas</div>
- </div>
- <div class="flex flex-col items-center justify-center text-center">
- <AlertTriangle size={24} class="text-red-500 mb-3 mx-auto" />
- <div class="text-3xl font-bold text-slate-900 dark:text-white mb-1">{mockPersonasKpis.riscoChurn}</div>
- <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400">Risco de Churn</div>
- </div>
- <div class="flex flex-col items-center justify-center text-center">
- <DollarSign size={24} class="text-red-500 mb-3 mx-auto" />
- <div class="text-3xl font-bold text-slate-900 dark:text-white mb-1">{mockPersonasKpis.perdaMensalEst}</div>
- <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400">Perda Mensal Est.</div>
- </div>
- <div class="flex flex-col items-center justify-center text-center">
- <DollarSign size={24} class="text-amber-500 mb-3 mx-auto" />
- <div class="text-3xl font-bold text-slate-900 dark:text-white mb-1">{mockPersonasKpis.potencialExpansao}</div>
- <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400">Potencial de Expansão</div>
- </div>
- </div>
- </div>
- <!-- Personas Grid & Details -->
- <div class="grid grid-cols-1 xl:grid-cols-3 gap-6">
- <div class="xl:col-span-2 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]">
-
- <div class="flex flex-wrap items-center justify-between gap-4 mb-8">
- <div class="flex items-center gap-3">
- <div class="flex items-center justify-center text-slate-700 dark:text-slate-300">
- <UserRound size={20} />
- </div>
- <h2 class="text-lg font-bold text-slate-900 dark:text-white">Minhas Personas</h2>
- <span class="text-sm text-slate-500 dark:text-slate-400">Conheça sua base de forma humana</span>
- </div>
- <button class="rounded-lg bg-indigo-600 px-5 py-2 text-sm font-semibold text-white transition-colors hover:bg-indigo-700 shadow-sm whitespace-nowrap">
- Meus Clientes
- </button>
- </div>
- <!-- Header Stats -->
- <div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8 pb-8 border-b border-slate-100 dark:border-slate-800/60">
- <div class="flex flex-col items-start text-left">
- <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400 mb-2">
- Personas Identificadas
- </div>
- <div class="text-3xl font-bold text-slate-900 dark:text-white">0</div>
- </div>
- <div class="flex flex-col items-start text-left">
- <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400 mb-2">
- Volume Total de Mensagens Analisadas
- </div>
- <div class="text-3xl font-bold text-slate-900 dark:text-white">0</div>
- </div>
- <div class="flex flex-col items-start text-left">
- <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400 mb-2">
- Aspectos Únicos
- </div>
- <div class="text-3xl font-bold text-slate-900 dark:text-white">0</div>
- </div>
- <div class="flex flex-col items-start text-left">
- <div class="text-[11px] font-semibold tracking-wider text-slate-500 uppercase dark:text-slate-400 mb-2">
- Subaspectos Únicos
- </div>
- <div class="text-3xl font-bold text-slate-900 dark:text-white">0</div>
- </div>
- </div>
- <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
- {#each mockPersonas as persona}
- <button
- type="button"
- onclick={() => openPersonaDetails(persona)}
- class={`flex flex-col items-center justify-start rounded-xl border p-6 text-center transition-all duration-200 ${
- selectedPersona?.id === persona.id
- ? 'border-indigo-400 bg-indigo-50/50 shadow-[0_0_15px_rgba(99,102,241,0.15)] dark:border-indigo-500/80 dark:bg-[#1e293b] dark:shadow-[0_0_20px_rgba(99,102,241,0.1)]'
- : 'border-slate-200 bg-white hover:border-slate-300 dark:border-slate-700/60 dark:bg-[#1e293b]/40 dark:hover:border-slate-600 dark:hover:bg-[#1e293b]/60'
- }`}
- >
- <span class="inline-block rounded-full bg-indigo-100 px-4 py-1 text-[10px] font-bold text-indigo-700 dark:bg-indigo-500/20 dark:text-indigo-400 mb-6 tracking-wider">
- {persona.tipo}
- </span>
- <UserRound size={36} strokeWidth={1.5} class="text-slate-400 dark:text-slate-500 mb-4 mx-auto" />
- <h3 class="text-sm font-bold text-slate-900 dark:text-white mb-2 leading-snug text-center">{persona.nome}</h3>
- <p class="text-xs text-slate-500 dark:text-slate-400 leading-relaxed font-medium text-center">{persona.descricao}</p>
- </button>
- {/each}
- </div>
- </div>
- <!-- Next Best Action Panel -->
- <div class="rounded-xl border border-slate-200 bg-white p-5 shadow-sm transition-colors duration-200 dark:border-slate-800 dark:bg-[#1e293b] flex flex-col h-[600px]">
- <div class="mb-4">
- <h2 class="text-lg font-bold text-slate-900 dark:text-white">Next Best Action</h2>
- <p class="text-sm text-slate-500 dark:text-slate-400">Recomendações estratégicas por persona</p>
- </div>
-
- <div class="flex-1 overflow-y-auto custom-scrollbar pr-2">
- {#if selectedPersona}
- <div class="space-y-6">
- <div>
- <div class="flex items-center gap-2 mb-2">
- <UserRound size={18} class="text-indigo-500" />
- <h3 class="font-bold text-slate-900 dark:text-white">{selectedPersona.nome}</h3>
- </div>
- <p class="text-sm text-slate-600 dark:text-slate-300 bg-slate-50 dark:bg-slate-800 p-3 rounded-lg border border-slate-100 dark:border-slate-700">
- {selectedPersona.detalhes}
- </p>
- </div>
- <div class="space-y-4">
- <div class="rounded-lg border border-emerald-200 bg-emerald-50 p-4 dark:border-emerald-500/20 dark:bg-emerald-500/5">
- <h4 class="font-bold text-emerald-800 dark:text-emerald-400 mb-2 flex items-center gap-2">
- <TrendingUp size={16} />
- Expansão
- </h4>
- <p class="text-sm text-emerald-700 dark:text-emerald-300">
- {selectedPersona.expansao}
- </p>
- </div>
- <div class="rounded-lg border border-red-200 bg-red-50 p-4 dark:border-red-500/20 dark:bg-red-500/5">
- <h4 class="font-bold text-red-800 dark:text-red-400 mb-2 flex items-center gap-2">
- <HeartHandshake size={16} />
- Engajamento (Salvar Churn)
- </h4>
- <p class="text-sm text-red-700 dark:text-red-300">
- {selectedPersona.engajamento}
- </p>
- </div>
- </div>
- </div>
- {:else}
- <div class="flex h-full flex-col items-center justify-center text-center text-slate-500 dark:text-slate-400">
- <UserRound size={48} class="mb-4 opacity-20" />
- <p>Selecione uma persona ao lado para ver o Next Best Action.</p>
- </div>
- {/if}
- </div>
- </div>
- </div>
- </div>
|