Calibrate RFV customer lifecycle segments
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 2m30s

This commit is contained in:
Cauê Faleiros
2026-06-18 15:51:35 -03:00
parent ca90a6e94b
commit 1af624aa77
3 changed files with 219 additions and 81 deletions

View File

@@ -34,14 +34,14 @@ const rfmSegmentDefinitions: Array<Pick<RfmSegment, 'key' | 'label'>> = [
const segmentDescriptions: Record<string, string> = {
champions: 'Recentes, frequentes e valiosos',
potential_loyalists: 'Recentes com bom potencial',
new_customers: 'Primeira compra recente',
loyal_customers: 'Valiosos, mas menos recentes',
need_attention: 'Base intermediária para nutrir',
about_to_sleep: 'Baixo valor começando a esfriar',
at_risk: 'Valiosos sem compra recente',
hibernating: 'Sem compra recente e valor médio',
lost: 'Baixa atividade e distante'
potential_loyalists: 'Recentes e em evolução',
new_customers: 'Primeiro pedido nos últimos 60 dias',
loyal_customers: 'Bom histórico, compra entre 61 e 180 dias',
need_attention: 'Perfil médio, compra entre 61 e 180 dias',
about_to_sleep: 'Perfil baixo, compra entre 61 e 180 dias',
at_risk: 'Histórico forte, sem compra entre 181 e 365 dias',
hibernating: 'Sem compra entre 181 e 365 dias',
lost: 'Sem compra há 366 dias ou mais'
};
const segmentActions: Record<string, string> = {
@@ -312,7 +312,7 @@ const Rfm = () => {
<div className="mb-4 flex flex-col gap-3 lg:flex-row lg:items-end lg:justify-between">
<div>
<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 pelo RFV histórico até a data final.</p>
<p className="text-sm font-medium text-dark-muted">Compradores do período agrupados por recência fixa e perfil histórico de frequência e valor.</p>
</div>
<div className="flex items-center gap-2 text-xs font-semibold text-dark-muted">
<span>Menor prioridade</span>
@@ -326,12 +326,12 @@ const Rfm = () => {
<div className="flex items-center justify-center rounded-xl border border-dark-border bg-dark-input/60 px-3 py-2.5 text-center">
<div>
<p className="text-[10px] font-bold uppercase tracking-wider text-dark-muted">Eixos</p>
<p className="text-xs font-semibold text-dark-text">Recência / Valor</p>
<p className="text-xs font-semibold text-dark-text">Recência / Perfil</p>
</div>
</div>
{[1, 2, 3].map(valueScore => (
<div key={valueScore} className="rounded-xl border border-dark-border bg-dark-input/70 px-3 py-2.5 text-center">
<p className="text-[10px] font-bold uppercase tracking-wider text-dark-muted">Valor {valueScore}</p>
<p className="text-[10px] font-bold uppercase tracking-wider text-dark-muted">Perfil {valueScore}</p>
<p className="text-xs font-bold text-dark-text">{scoreLabel(valueScore)}</p>
</div>
))}
@@ -343,7 +343,7 @@ const Rfm = () => {
<p className="text-[10px] font-bold uppercase tracking-wider text-dark-muted">Rec. {recencyScore}</p>
<p className="text-xs font-bold text-dark-text">{scoreLabel(recencyScore)}</p>
<p className="mt-1 text-[10px] font-semibold text-dark-muted">
{recencyScore === 3 ? 'Compra recente' : recencyScore === 2 ? 'Intermediário' : 'Distante'}
{recencyScore === 3 ? '0 a 60 dias' : recencyScore === 2 ? '61 a 180 dias' : '181+ dias'}
</p>
</div>
</div>
@@ -371,7 +371,7 @@ const Rfm = () => {
<div className="mb-2 flex items-start justify-between gap-2">
<span className={`h-2 w-8 rounded-full ${style.accent}`} />
<span className="rounded-md border border-dark-border bg-black/10 px-1.5 py-0.5 text-[10px] font-bold text-dark-muted">
R{recencyScore} V{valueScore}
R{recencyScore} P{valueScore}
</span>
</div>
<p className="text-sm font-bold text-dark-text">{segment?.label}</p>