// ============================================================
// JuFlow — Clients List
// ============================================================
const { useState: useStCL, useMemo: useMemosCL } = React;
const UCL = window.JFUtils;
const Clientes = ({ appointments, onViewClient, onNewAppt }) => {
const [search, setSearch] = useStCL('');
const [statusF, setStatusF] = useStCL('all');
const [sortBy, setSortBy] = useStCL('name');
const [sortDir, setSortDir] = useStCL('asc');
const [showNew, setShowNew] = useStCL(false);
const clients = useMemosCL(() => {
let list = window.JF.CLIENTS;
if (search) {
const q = search.toLowerCase();
list = list.filter(c =>
c.name.toLowerCase().includes(q) ||
c.phone.includes(q) ||
c.email.toLowerCase().includes(q)
);
}
if (statusF !== 'all') list = list.filter(c => c.status === statusF);
list = [...list].sort((a, b) => {
let av, bv;
if (sortBy === 'name') { av = a.name; bv = b.name; }
else if (sortBy === 'spent') { av = a.totalSpent; bv = b.totalSpent; }
else if (sortBy === 'visits'){ av = a.visits; bv = b.visits; }
else if (sortBy === 'last') { av = a.lastVisit || ''; bv = b.lastVisit || ''; }
else { av = a.name; bv = b.name; }
if (sortDir === 'asc') return av > bv ? 1 : -1;
return av < bv ? 1 : -1;
});
return list;
}, [search, statusF, sortBy, sortDir]);
const toggleSort = (col) => {
if (sortBy === col) setSortDir(d => d === 'asc' ? 'desc' : 'asc');
else { setSortBy(col); setSortDir('asc'); }
};
const SortIcon = ({ col }) => {
if (sortBy !== col) return
| h.col && toggleSort(h.col)}
>
{h.label} {h.col && |
))}
||||||
|---|---|---|---|---|---|---|
|
{client.name}
{client.email}
|
{client.phone} |
{client.tags.map(tag =>
|
60 ? '#EF4444' : '#374151', fontWeight: daysSince > 60 ? 600 : 400 }}>
{client.lastVisit ? UCL.formatDate(client.lastVisit) : '—'}
{daysSince > 60 && (
{daysSince}d atrás
)}
|
{UCL.formatCurrency(client.totalSpent)}
{client.visits} sessões
|
{freq.label} | e.stopPropagation()}>
|