// Grape Elevate — Dashboard (home) screen
const Sparkline = ({ data, color = '#8B5CF6', height = 40, width = 110, fillOpacity = 0.18 }) => {
if (!data.length) return null;
const max = Math.max(...data), min = Math.min(...data);
const span = Math.max(1, max - min);
const pts = data.map((v, i) => [
(i / (data.length - 1)) * width,
height - ((v - min) / span) * (height - 6) - 3,
]);
// Catmull-rom-ish smoothing for a friendly curve.
const path = pts.map(([x, y], i) => {
if (i === 0) return `M ${x},${y}`;
const [px, py] = pts[i - 1];
const cx = (px + x) / 2;
return `C ${cx},${py} ${cx},${y} ${x},${y}`;
}).join(' ');
const area = `${path} L ${width},${height} L 0,${height} Z`;
return (
);
};
const StatCard = ({ icon, label, value, delta, color, series }) => (
{value.toLocaleString('pt-BR')}
= 0 ? 'var(--green)' : 'var(--coral)' }}>
{delta >= 0 ? : }
{Math.abs(delta)}%
);
// Friendly illustrated template tile — simple geometric scene.
const TemplateTile = ({ illust, title, desc, popular, onUse, t }) => (
{illust}
{title}
{popular && ★ {t('home.popular')}}
{desc}
);
const ActivityIcon = ({ kind }) => {
const map = {
dm: { c: 'var(--cyan)', i: },
lead: { c: 'var(--grape)', i: },
reply: { c: 'var(--coral)', i: },
follow: { c: 'var(--sun)', i: },
};
const m = map[kind] || map.dm;
return (
{m.i}
);
};
function Dashboard({ t, lang, automations, activity, recent, onNav, onCreateFromTemplate }) {
const totals = {
followers: activity.followers.reduce((s, x) => s + x, 0),
dms: activity.dms.reduce((s, x) => s + x, 0),
replies: activity.replies.reduce((s, x) => s + x, 0),
leads: activity.leads.reduce((s, x) => s + x, 0),
};
const top = automations.filter((a) => a.status === 'live').sort((a, b) => b.runs - a.runs).slice(0, 4);
return (
<>
{t('home.hello')}, Fabiano 👋
{t('home.subtitle')}
} label={t('home.stat.followers')} value={totals.followers} delta={18} color="#8B5CF6" series={activity.followers} />
} label={t('home.stat.dms')} value={totals.dms} delta={24} color="#06B6D4" series={activity.dms} />
} label={t('home.stat.replies')} value={totals.replies} delta={32} color="#FB7185" series={activity.replies} />
} label={t('home.stat.leads')} value={totals.leads} delta={-6} color="#F59E0B" series={activity.leads} />
{t('home.quick.title')}
{t('home.quick.subtitle')}
}
title={t('home.quick.tpl1.title')} desc={t('home.quick.tpl1.desc')} popular
onUse={() => onCreateFromTemplate('comment')} />
}
title={t('home.quick.tpl2.title')} desc={t('home.quick.tpl2.desc')}
onUse={() => onCreateFromTemplate('story')} />
}
title={t('home.quick.tpl3.title')} desc={t('home.quick.tpl3.desc')}
onUse={() => onCreateFromTemplate('follow')} />
{t('home.activities.title')}
{recent.map((r, i) => (
{r.who} {r.what}
{r.auto} · {r.when}
))}
{t('home.top.title')}
{top.map((a) => (
{a.trigger === 'comment' ? '💬' : a.trigger === 'story' ? '📸' : a.trigger === 'follow' ? '➕' : '✉️'}
{a.name}
{a.runs.toLocaleString('pt-BR')} execuções · {a.conv}% conversão
{t('auto.status.live')}
))}
>
);
}
// Tiny friendly illustrations — geometric shapes only.
const IllustComment = () => (
);
const IllustStory = () => (
);
const IllustWelcome = () => (
);
const dashStyles = `
.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
@media (max-width: 1100px) { .stat-grid { grid-template-columns: repeat(2, 1fr); } }
.stat-card { display: flex; flex-direction: column; gap: 8px; position: relative; overflow: hidden; }
.stat-head { display: flex; align-items: center; gap: 10px; }
.stat-ic { width: 32px; height: 32px; border-radius: 10px; display: inline-flex; align-items: center; justify-content: center; }
.stat-body { display: flex; align-items: baseline; justify-content: space-between; }
.stat-val { font-size: 28px; font-weight: 800; letter-spacing: -0.02em; }
.stat-delta { display: inline-flex; align-items: center; gap: 2px; font-size: 12.5px; font-weight: 700; }
.dash-row { display: grid; grid-template-columns: 2fr 1fr; gap: 14px; }
@media (max-width: 1100px) { .dash-row { grid-template-columns: 1fr; } }
.section-title { margin: 2px 0 0; font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.tpl-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
@media (max-width: 900px) { .tpl-grid { grid-template-columns: 1fr; } }
.tpl-card {
border: 1px solid var(--line);
border-radius: var(--radius);
background: var(--surface-2);
overflow: hidden;
display: flex; flex-direction: column;
transition: transform 150ms cubic-bezier(.2,.9,.3,1.1), box-shadow 150ms, border-color 150ms;
}
.tpl-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-pop); border-color: color-mix(in oklch, var(--grape) 30%, var(--line)); }
.tpl-illust { height: 110px; background: linear-gradient(135deg, color-mix(in oklch, var(--grape) 14%, var(--surface)) 0%, color-mix(in oklch, var(--cyan) 12%, var(--surface)) 100%); display: flex; align-items: center; justify-content: center; padding: 10px; }
.tpl-illust svg { max-height: 100%; }
.tpl-body { padding: 14px; display: flex; flex-direction: column; gap: 8px; }
.tpl-title { margin: 0; font-size: 14px; font-weight: 700; letter-spacing: -0.01em; }
.tpl-desc { margin: 0; font-size: 12.5px; color: var(--text-soft); line-height: 1.45; }
.tpl-body .btn { align-self: flex-start; }
.act-card { display: flex; flex-direction: column; }
.act-list { display: flex; flex-direction: column; gap: 12px; }
.act-item { display: flex; gap: 10px; align-items: flex-start; }
.act-ic { width: 28px; height: 28px; border-radius: 9px; display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0; }
.act-text { font-size: 13px; line-height: 1.4; min-width: 0; }
.top-list { display: flex; flex-direction: column; gap: 8px; }
.top-row { display: grid; grid-template-columns: 1.5fr 1fr 110px; gap: 14px; align-items: center; padding: 10px 6px; border-radius: 10px; }
.top-row:hover { background: var(--surface-2); }
.top-name { display: flex; align-items: center; gap: 12px; min-width: 0; }
.top-emoji { width: 36px; height: 36px; border-radius: 10px; background: var(--surface-3); display: flex; align-items: center; justify-content: center; font-size: 18px; }
.top-bar { height: 6px; background: var(--surface-3); border-radius: 999px; overflow: hidden; }
.top-bar i { display: block; height: 100%; background: linear-gradient(90deg, var(--grape), var(--cyan)); border-radius: 999px; }
.pill-live .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 3px color-mix(in oklch, var(--green) 25%, transparent); }
`;
window.Dashboard = Dashboard;