fix: update activity item colors and backgrounds for improved visual distinction
This commit is contained in:
@@ -133,8 +133,8 @@ function getActivityConfig(activity: Activity): ActivityConfig {
|
|||||||
case 'event.triggered':
|
case 'event.triggered':
|
||||||
return {
|
return {
|
||||||
icon: Zap,
|
icon: Zap,
|
||||||
color: 'text-neutral-600',
|
color: 'text-amber-700',
|
||||||
bgColor: 'bg-neutral-100',
|
bgColor: 'bg-amber-50',
|
||||||
title: (typeof metadata.eventName === 'string' ? metadata.eventName : undefined) || 'Event triggered',
|
title: (typeof metadata.eventName === 'string' ? metadata.eventName : undefined) || 'Event triggered',
|
||||||
description: undefined,
|
description: undefined,
|
||||||
badge: {
|
badge: {
|
||||||
@@ -150,8 +150,8 @@ function getActivityConfig(activity: Activity): ActivityConfig {
|
|||||||
case 'email.sent':
|
case 'email.sent':
|
||||||
return {
|
return {
|
||||||
icon: Send,
|
icon: Send,
|
||||||
color: 'text-green-700',
|
color: 'text-neutral-700',
|
||||||
bgColor: 'bg-green-50',
|
bgColor: 'bg-neutral-100',
|
||||||
title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email sent',
|
title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email sent',
|
||||||
description: metadata.campaignName
|
description: metadata.campaignName
|
||||||
? `Campaign: ${String(metadata.campaignName)}`
|
? `Campaign: ${String(metadata.campaignName)}`
|
||||||
@@ -169,8 +169,8 @@ function getActivityConfig(activity: Activity): ActivityConfig {
|
|||||||
case 'email.delivered':
|
case 'email.delivered':
|
||||||
return {
|
return {
|
||||||
icon: CheckCircle,
|
icon: CheckCircle,
|
||||||
color: 'text-green-700',
|
color: 'text-emerald-700',
|
||||||
bgColor: 'bg-green-50',
|
bgColor: 'bg-emerald-50',
|
||||||
title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email delivered',
|
title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email delivered',
|
||||||
description: metadata.campaignName
|
description: metadata.campaignName
|
||||||
? `Campaign: ${String(metadata.campaignName)}`
|
? `Campaign: ${String(metadata.campaignName)}`
|
||||||
@@ -199,8 +199,8 @@ function getActivityConfig(activity: Activity): ActivityConfig {
|
|||||||
case 'email.opened':
|
case 'email.opened':
|
||||||
return {
|
return {
|
||||||
icon: Eye,
|
icon: Eye,
|
||||||
color: 'text-neutral-600',
|
color: 'text-emerald-700',
|
||||||
bgColor: 'bg-neutral-100',
|
bgColor: 'bg-emerald-50',
|
||||||
title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email opened',
|
title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email opened',
|
||||||
description:
|
description:
|
||||||
typeof metadata.totalOpens === 'number' && metadata.totalOpens > 1
|
typeof metadata.totalOpens === 'number' && metadata.totalOpens > 1
|
||||||
@@ -219,8 +219,8 @@ function getActivityConfig(activity: Activity): ActivityConfig {
|
|||||||
case 'email.clicked':
|
case 'email.clicked':
|
||||||
return {
|
return {
|
||||||
icon: MousePointerClick,
|
icon: MousePointerClick,
|
||||||
color: 'text-neutral-600',
|
color: 'text-sky-700',
|
||||||
bgColor: 'bg-neutral-100',
|
bgColor: 'bg-sky-50',
|
||||||
title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email clicked',
|
title: (typeof metadata.subject === 'string' ? metadata.subject : undefined) || 'Email clicked',
|
||||||
description:
|
description:
|
||||||
typeof metadata.totalClicks === 'number' && metadata.totalClicks > 1
|
typeof metadata.totalClicks === 'number' && metadata.totalClicks > 1
|
||||||
@@ -269,8 +269,8 @@ function getActivityConfig(activity: Activity): ActivityConfig {
|
|||||||
case 'workflow.started':
|
case 'workflow.started':
|
||||||
return {
|
return {
|
||||||
icon: Workflow,
|
icon: Workflow,
|
||||||
color: 'text-neutral-600',
|
color: 'text-amber-700',
|
||||||
bgColor: 'bg-neutral-100',
|
bgColor: 'bg-amber-50',
|
||||||
title: (typeof metadata.workflowName === 'string' ? metadata.workflowName : undefined) || 'Workflow started',
|
title: (typeof metadata.workflowName === 'string' ? metadata.workflowName : undefined) || 'Workflow started',
|
||||||
description: `Status: ${String(metadata.status || 'unknown')}`,
|
description: `Status: ${String(metadata.status || 'unknown')}`,
|
||||||
badge: {
|
badge: {
|
||||||
@@ -282,8 +282,8 @@ function getActivityConfig(activity: Activity): ActivityConfig {
|
|||||||
case 'workflow.completed':
|
case 'workflow.completed':
|
||||||
return {
|
return {
|
||||||
icon: CheckCheck,
|
icon: CheckCheck,
|
||||||
color: 'text-green-700',
|
color: 'text-amber-700',
|
||||||
bgColor: 'bg-green-50',
|
bgColor: 'bg-amber-50',
|
||||||
title: (typeof metadata.workflowName === 'string' ? metadata.workflowName : undefined) || 'Workflow completed',
|
title: (typeof metadata.workflowName === 'string' ? metadata.workflowName : undefined) || 'Workflow completed',
|
||||||
description: metadata.exitReason
|
description: metadata.exitReason
|
||||||
? `Exit: ${String(metadata.exitReason)}`
|
? `Exit: ${String(metadata.exitReason)}`
|
||||||
@@ -297,8 +297,8 @@ function getActivityConfig(activity: Activity): ActivityConfig {
|
|||||||
case 'campaign.scheduled':
|
case 'campaign.scheduled':
|
||||||
return {
|
return {
|
||||||
icon: Calendar,
|
icon: Calendar,
|
||||||
color: 'text-neutral-600',
|
color: 'text-sky-700',
|
||||||
bgColor: 'bg-neutral-100',
|
bgColor: 'bg-sky-50',
|
||||||
title: (typeof metadata.campaignName === 'string' ? metadata.campaignName : undefined) || 'Campaign scheduled',
|
title: (typeof metadata.campaignName === 'string' ? metadata.campaignName : undefined) || 'Campaign scheduled',
|
||||||
description: metadata.subject
|
description: metadata.subject
|
||||||
? `${String(metadata.subject)}${metadata.totalRecipients ? ` • ${metadata.totalRecipients} recipients` : ''}`
|
? `${String(metadata.subject)}${metadata.totalRecipients ? ` • ${metadata.totalRecipients} recipients` : ''}`
|
||||||
@@ -314,8 +314,8 @@ function getActivityConfig(activity: Activity): ActivityConfig {
|
|||||||
case 'workflow.email.scheduled':
|
case 'workflow.email.scheduled':
|
||||||
return {
|
return {
|
||||||
icon: Calendar,
|
icon: Calendar,
|
||||||
color: 'text-neutral-600',
|
color: 'text-amber-700',
|
||||||
bgColor: 'bg-neutral-100',
|
bgColor: 'bg-amber-50',
|
||||||
title: (typeof metadata.stepName === 'string' ? metadata.stepName : undefined) || 'Workflow email scheduled',
|
title: (typeof metadata.stepName === 'string' ? metadata.stepName : undefined) || 'Workflow email scheduled',
|
||||||
description: metadata.workflowName
|
description: metadata.workflowName
|
||||||
? `Workflow: ${String(metadata.workflowName)}${metadata.subject ? ` • ${String(metadata.subject)}` : ''}`
|
? `Workflow: ${String(metadata.workflowName)}${metadata.subject ? ` • ${String(metadata.subject)}` : ''}`
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import {
|
|||||||
MousePointerClick,
|
MousePointerClick,
|
||||||
Send,
|
Send,
|
||||||
ShieldCheck,
|
ShieldCheck,
|
||||||
Sparkles,
|
|
||||||
TrendingUp,
|
TrendingUp,
|
||||||
Users,
|
Users,
|
||||||
Workflow,
|
Workflow,
|
||||||
@@ -49,18 +48,6 @@ import {useConfig} from '../lib/hooks/useConfig';
|
|||||||
import {useUser} from '../lib/hooks/useUser';
|
import {useUser} from '../lib/hooks/useUser';
|
||||||
import {network} from '../lib/network';
|
import {network} from '../lib/network';
|
||||||
|
|
||||||
const MILESTONES = [100, 1_000, 10_000, 100_000, 1_000_000, 10_000_000];
|
|
||||||
|
|
||||||
function nextMilestone(value: number): number {
|
|
||||||
return MILESTONES.find(m => m > value) ?? value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatCompact(value: number): string {
|
|
||||||
if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(value % 1_000_000 === 0 ? 0 : 1)}M`;
|
|
||||||
if (value >= 1_000) return `${(value / 1_000).toFixed(value % 1_000 === 0 ? 0 : 1)}K`;
|
|
||||||
return value.toLocaleString();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getGreeting(): string {
|
function getGreeting(): string {
|
||||||
const hour = new Date().getHours();
|
const hour = new Date().getHours();
|
||||||
if (hour >= 23 || hour < 5) return 'Working late';
|
if (hour >= 23 || hour < 5) return 'Working late';
|
||||||
@@ -386,14 +373,6 @@ export default function Index() {
|
|||||||
const healthText =
|
const healthText =
|
||||||
!hasDelivData ? 'text-neutral-500' : worstLevel === 'healthy' ? 'text-emerald-700' : worstLevel === 'warning' ? 'text-amber-700' : 'text-red-700';
|
!hasDelivData ? 'text-neutral-500' : worstLevel === 'healthy' ? 'text-emerald-700' : worstLevel === 'warning' ? 'text-amber-700' : 'text-red-700';
|
||||||
|
|
||||||
const emailsTarget = nextMilestone(totalEmailsSent);
|
|
||||||
const prevMilestone = MILESTONES.filter(m => m <= totalEmailsSent).pop() ?? 0;
|
|
||||||
const milestoneProgress =
|
|
||||||
emailsTarget > prevMilestone
|
|
||||||
? Math.min(100, ((totalEmailsSent - prevMilestone) / (emailsTarget - prevMilestone)) * 100)
|
|
||||||
: 0;
|
|
||||||
const showMilestone = !isLoading && totalEmailsSent > 0 && emailsTarget > totalEmailsSent;
|
|
||||||
|
|
||||||
async function handleResendVerification() {
|
async function handleResendVerification() {
|
||||||
setIsResending(true);
|
setIsResending(true);
|
||||||
setResendMessage('');
|
setResendMessage('');
|
||||||
@@ -545,27 +524,6 @@ export default function Index() {
|
|||||||
{isEmails && !isLoading && previousStats && <TrendChip trend={emailsTrend} />}
|
{isEmails && !isLoading && previousStats && <TrendChip trend={emailsTrend} />}
|
||||||
{isOpenRate && !isLoading && previousStats && <TrendChip trend={openRateTrend} />}
|
{isOpenRate && !isLoading && previousStats && <TrendChip trend={openRateTrend} />}
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
{isEmails && showMilestone && (
|
|
||||||
<div className="px-6 pb-4 -mt-1">
|
|
||||||
<div className="flex items-center justify-between text-[11px] text-neutral-500 mb-1.5">
|
|
||||||
<span className="inline-flex items-center gap-1">
|
|
||||||
<Sparkles className="h-3 w-3 text-neutral-400" />
|
|
||||||
Next milestone
|
|
||||||
</span>
|
|
||||||
<span className="tabular-nums font-medium text-neutral-700">
|
|
||||||
{formatCompact(totalEmailsSent)} / {formatCompact(emailsTarget)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="h-1 w-full overflow-hidden rounded-full bg-neutral-100">
|
|
||||||
<motion.div
|
|
||||||
className="h-full rounded-full bg-neutral-900"
|
|
||||||
initial={{width: 0}}
|
|
||||||
animate={{width: `${milestoneProgress}%`}}
|
|
||||||
transition={{duration: 1.2, ease: [0.22, 1, 0.36, 1], delay: 0.4}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</Card>
|
</Card>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user