Use RFM summaries for clients list
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m31s
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m31s
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Link, useOutletContext } from 'react-router-dom';
|
||||
import { Search, ChevronRight, Filter, ChevronLeft, Download } from 'lucide-react';
|
||||
import type { OrderData, DateRange, RfmAnalytics, RfmClient } from '../types';
|
||||
import type { DateRange, RfmAnalytics, RfmClient } from '../types';
|
||||
import { exportToCSV, fetchRfmAnalytics } from '../dataService';
|
||||
import DateRangePicker from '../components/DateRangePicker';
|
||||
import { buildClientsSummary, type ClientSortOption, type ClientSummary } from '../analytics/clients';
|
||||
import type { ClientSortOption, ClientSummary } from '../analytics/clients';
|
||||
|
||||
const clientTypeStyles: Record<string, string> = {
|
||||
'Campeão': 'border-emerald-500/30 bg-emerald-500/15 text-emerald-300',
|
||||
@@ -63,10 +63,9 @@ const sortClients = (clients: ClientSummary[], sortBy: ClientSortOption) => {
|
||||
};
|
||||
|
||||
const Clients = () => {
|
||||
const { dateRange, setDateRange, ordersData } = useOutletContext<{
|
||||
const { dateRange, setDateRange } = useOutletContext<{
|
||||
dateRange: DateRange,
|
||||
setDateRange: (range: DateRange) => void,
|
||||
ordersData: OrderData[]
|
||||
setDateRange: (range: DateRange) => void
|
||||
}>();
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const [sortBy, setSortBy] = useState<ClientSortOption>('recent');
|
||||
@@ -92,35 +91,30 @@ const Clients = () => {
|
||||
};
|
||||
}, [dateRange]);
|
||||
|
||||
const rfmClientsByIdentity = useMemo(() => {
|
||||
const map = new Map<string, RfmClient>();
|
||||
|
||||
(rfmAnalytics?.clients || []).forEach(client => {
|
||||
if (client.phone) map.set(`phone:${client.phone}`, client);
|
||||
map.set(`name:${client.name.toLowerCase()}`, client);
|
||||
});
|
||||
|
||||
return map;
|
||||
}, [rfmAnalytics]);
|
||||
|
||||
const allClientsData = useMemo(() => {
|
||||
const localClients = buildClientsSummary(ordersData, dateRange, searchTerm, sortBy);
|
||||
const enrichedClients = localClients.map(client => {
|
||||
const rfmClient = (client.phone && rfmClientsByIdentity.get(`phone:${client.phone}`)) ||
|
||||
rfmClientsByIdentity.get(`name:${client.name.toLowerCase()}`);
|
||||
const normalizedSearch = searchTerm.trim().toLowerCase();
|
||||
const clients = (rfmAnalytics?.clients || []).map((client): ClientSummary => ({
|
||||
name: client.name,
|
||||
phone: client.phone,
|
||||
totalSpent: client.monetary,
|
||||
averageTicket: client.frequency ? client.monetary / client.frequency : 0,
|
||||
totalItems: client.quantityPurchased,
|
||||
orderCount: client.frequency,
|
||||
lastPurchase: client.lastPurchaseDate ? new Date(client.lastPurchaseDate).getTime() : 0,
|
||||
clientType: backendSegmentToClientType[client.segmentKey] || client.segmentLabel,
|
||||
rfmScore: client.rfmScore,
|
||||
rfmPriority: getRfmPriority(client)
|
||||
}));
|
||||
|
||||
if (!rfmClient) return client;
|
||||
const filteredClients = normalizedSearch
|
||||
? clients.filter(client =>
|
||||
client.name.toLowerCase().includes(normalizedSearch) ||
|
||||
client.phone.toLowerCase().includes(normalizedSearch)
|
||||
)
|
||||
: clients;
|
||||
|
||||
return {
|
||||
...client,
|
||||
clientType: backendSegmentToClientType[rfmClient.segmentKey] || client.clientType,
|
||||
rfmScore: rfmClient.rfmScore,
|
||||
rfmPriority: getRfmPriority(rfmClient)
|
||||
};
|
||||
});
|
||||
|
||||
return sortClients(enrichedClients, sortBy);
|
||||
}, [searchTerm, sortBy, ordersData, dateRange, rfmClientsByIdentity]);
|
||||
return sortClients(filteredClients, sortBy);
|
||||
}, [searchTerm, sortBy, rfmAnalytics]);
|
||||
|
||||
const clientsData = useMemo(() => {
|
||||
if (clientTypeFilter === 'all') return allClientsData;
|
||||
|
||||
Reference in New Issue
Block a user