Rename visible RFM labels to RFV
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m26s

This commit is contained in:
Cauê Faleiros
2026-06-15 16:44:25 -03:00
parent 9a58b2a271
commit f811d3c0ab
3 changed files with 16 additions and 16 deletions

View File

@@ -82,7 +82,7 @@ const Layout = () => {
{ name: 'Dashboard', href: '/graph', icon: LayoutDashboard }, { name: 'Dashboard', href: '/graph', icon: LayoutDashboard },
{ name: 'Produtos', href: '/products', icon: Package }, { name: 'Produtos', href: '/products', icon: Package },
{ name: 'Clientes', href: '/clients', icon: Users }, { name: 'Clientes', href: '/clients', icon: Users },
{ name: 'RFM', href: '/rfm', icon: Grid3X3 }, { name: 'RFV', href: '/rfm', icon: Grid3X3 },
{ name: 'Campanhas', href: '/campaigns', icon: Megaphone }, { name: 'Campanhas', href: '/campaigns', icon: Megaphone },
]; ];

View File

@@ -174,7 +174,7 @@ const Clients = () => {
<option value="spent_asc">Menor Gasto</option> <option value="spent_asc">Menor Gasto</option>
<option value="ticket_desc">Maior Ticket Médio</option> <option value="ticket_desc">Maior Ticket Médio</option>
<option value="ticket_asc">Menor Ticket Médio</option> <option value="ticket_asc">Menor Ticket Médio</option>
<option value="rfm_priority">Prioridade RFM</option> <option value="rfm_priority">Prioridade RFV</option>
<option value="items_desc">Mais Produtos</option> <option value="items_desc">Mais Produtos</option>
<option value="items_asc">Menos Produtos</option> <option value="items_asc">Menos Produtos</option>
</select> </select>
@@ -200,7 +200,7 @@ const Clients = () => {
'Nome do Cliente': client.name, 'Nome do Cliente': client.name,
'Telefone/WhatsApp': client.phone || 'N/A', 'Telefone/WhatsApp': client.phone || 'N/A',
'Tipo de Cliente': client.clientType, 'Tipo de Cliente': client.clientType,
'RFM': client.rfmScore, 'RFV': client.rfmScore,
'Total Gasto (R$)': client.totalSpent.toFixed(2).replace('.', ','), 'Total Gasto (R$)': client.totalSpent.toFixed(2).replace('.', ','),
'Ticket Médio (R$)': client.averageTicket.toFixed(2).replace('.', ','), 'Ticket Médio (R$)': client.averageTicket.toFixed(2).replace('.', ','),
'Produtos Comprados': client.totalItems, 'Produtos Comprados': client.totalItems,
@@ -223,7 +223,7 @@ const Clients = () => {
<div> <div>
<h2 className="text-sm font-bold text-zinc-900 dark:text-dark-text">Tipos de Clientes</h2> <h2 className="text-sm font-bold text-zinc-900 dark:text-dark-text">Tipos de Clientes</h2>
<p className="text-xs font-semibold text-zinc-500 dark:text-dark-muted"> <p className="text-xs font-semibold text-zinc-500 dark:text-dark-muted">
Classificação RFM sincronizada com a página RFM quando disponível. Classificação RFV sincronizada com a página RFV quando disponível.
</p> </p>
</div> </div>
</div> </div>
@@ -255,7 +255,7 @@ const Clients = () => {
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Posição</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Posição</th>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Nome do Cliente</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Nome do Cliente</th>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Tipo</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Tipo</th>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">RFM</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">RFV</th>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Total Gasto</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Total Gasto</th>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Ticket Médio</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Ticket Médio</th>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Produtos Comprados</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Produtos Comprados</th>

View File

@@ -143,7 +143,7 @@ const Rfm = () => {
}, []); }, []);
useEffect(() => { useEffect(() => {
// RFM is calculated server-side from the selected date range. // RFV is calculated server-side from the selected date range.
// eslint-disable-next-line react-hooks/set-state-in-effect // eslint-disable-next-line react-hooks/set-state-in-effect
void loadRfm(dateRange); void loadRfm(dateRange);
}, [dateRange, loadRfm]); }, [dateRange, loadRfm]);
@@ -248,10 +248,10 @@ const Rfm = () => {
Cliente: client.name, Cliente: client.name,
Telefone: client.phone, Telefone: client.phone,
Segmento: client.segmentLabel, Segmento: client.segmentLabel,
RFM: client.rfmScore, RFV: client.rfmScore,
Recencia: client.recencyScore, Recencia: client.recencyScore,
Frequencia: client.frequencyScore, Frequencia: client.frequencyScore,
Monetario: client.monetaryScore, Valor: client.monetaryScore,
'Compra no periodo': formatPeriodRecency(client.lastPurchaseDate), 'Compra no periodo': formatPeriodRecency(client.lastPurchaseDate),
'Pedidos no periodo': client.frequency, 'Pedidos no periodo': client.frequency,
'Ticket medio no periodo (R$)': (client.frequency ? client.monetary / client.frequency : 0).toFixed(2).replace('.', ','), 'Ticket medio no periodo (R$)': (client.frequency ? client.monetary / client.frequency : 0).toFixed(2).replace('.', ','),
@@ -259,15 +259,15 @@ const Rfm = () => {
'Ultima compra': formatDate(client.lastPurchaseDate) 'Ultima compra': formatDate(client.lastPurchaseDate)
})); }));
exportToCSV(exportData, `rfm_${new Date().toISOString().split('T')[0]}.csv`); exportToCSV(exportData, `rfv_${new Date().toISOString().split('T')[0]}.csv`);
}; };
return ( return (
<div className="space-y-6"> <div className="space-y-6">
<div className="flex flex-col xl:flex-row xl:items-center justify-between gap-4"> <div className="flex flex-col xl:flex-row xl:items-center justify-between gap-4">
<div> <div>
<h1 className="text-2xl font-bold mb-2 text-dark-text">RFM</h1> <h1 className="text-2xl font-bold mb-2 text-dark-text">RFV</h1>
<p className="text-dark-muted font-medium">Segmentação de clientes por recência, frequência e valor monetário.</p> <p className="text-dark-muted font-medium">Segmentação de clientes por recência, frequência e valor.</p>
</div> </div>
<div className="flex flex-col sm:flex-row flex-wrap gap-3 items-start sm:items-center"> <div className="flex flex-col sm:flex-row flex-wrap gap-3 items-start sm:items-center">
@@ -284,7 +284,7 @@ const Rfm = () => {
{isLoading && ( {isLoading && (
<div className="inline-flex items-center gap-2 rounded-xl border border-dark-border bg-dark-card px-3 py-2 text-sm font-semibold text-dark-muted"> <div className="inline-flex items-center gap-2 rounded-xl border border-dark-border bg-dark-card px-3 py-2 text-sm font-semibold text-dark-muted">
<Loader2 className="h-4 w-4 animate-spin text-brand-primary" /> <Loader2 className="h-4 w-4 animate-spin text-brand-primary" />
Atualizando RFM Atualizando RFV
</div> </div>
)} )}
@@ -292,7 +292,7 @@ const Rfm = () => {
<div className="bg-dark-card p-6 rounded-2xl border border-dark-border shadow-sm"> <div className="bg-dark-card p-6 rounded-2xl border border-dark-border shadow-sm">
<p className="text-dark-muted text-sm font-medium mb-1">Clientes no Período</p> <p className="text-dark-muted text-sm font-medium mb-1">Clientes no Período</p>
<h3 className="text-3xl font-bold text-dark-text">{clients.length}</h3> <h3 className="text-3xl font-bold text-dark-text">{clients.length}</h3>
<p className="mt-1 text-xs font-semibold text-dark-muted">Agrupados pela tag RFM anterior</p> <p className="mt-1 text-xs font-semibold text-dark-muted">Agrupados pela tag RFV anterior</p>
</div> </div>
<div className="bg-dark-card p-6 rounded-2xl border border-dark-border shadow-sm"> <div className="bg-dark-card p-6 rounded-2xl border border-dark-border shadow-sm">
<p className="text-dark-muted text-sm font-medium mb-1">Receita no Período</p> <p className="text-dark-muted text-sm font-medium mb-1">Receita no Período</p>
@@ -311,8 +311,8 @@ const Rfm = () => {
<section className="bg-dark-card p-5 rounded-2xl border border-dark-border shadow-sm"> <section className="bg-dark-card p-5 rounded-2xl border border-dark-border shadow-sm">
<div className="mb-4 flex flex-col gap-3 lg:flex-row lg:items-end lg:justify-between"> <div className="mb-4 flex flex-col gap-3 lg:flex-row lg:items-end lg:justify-between">
<div> <div>
<h2 className="text-lg font-bold text-dark-text">Matriz RFM</h2> <h2 className="text-lg font-bold text-dark-text">Matriz RFV</h2>
<p className="text-sm font-medium text-dark-muted">Compradores do período agrupados pela tag RFM anterior ao período.</p> <p className="text-sm font-medium text-dark-muted">Compradores do período agrupados pela tag RFV anterior ao período.</p>
</div> </div>
<div className="flex items-center gap-2 text-xs font-semibold text-dark-muted"> <div className="flex items-center gap-2 text-xs font-semibold text-dark-muted">
<span>Menor prioridade</span> <span>Menor prioridade</span>
@@ -520,7 +520,7 @@ const Rfm = () => {
<tr> <tr>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Cliente</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Cliente</th>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Segmento</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Segmento</th>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">RFM</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">RFV</th>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Última Compra</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Última Compra</th>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Pedidos no Período</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Pedidos no Período</th>
<th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Ticket no Período</th> <th className="px-6 py-4 font-bold uppercase tracking-wider text-[10px]">Ticket no Período</th>