fix: Update sentCount on campaign sent for correct overview stats
This commit is contained in:
@@ -204,6 +204,7 @@ export async function createEmailWorker() {
|
||||
where: {id: email.campaignId},
|
||||
data: {
|
||||
status: CampaignStatus.SENT,
|
||||
sentCount,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -564,6 +564,7 @@ export class CampaignService {
|
||||
await prisma.campaign.update({
|
||||
where: {id: campaignId},
|
||||
data: {
|
||||
sentCount: sentEmails,
|
||||
deliveredCount: deliveredEmails,
|
||||
openedCount: openedEmails,
|
||||
clickedCount: clickedEmails,
|
||||
|
||||
@@ -503,6 +503,42 @@ export class EmailService {
|
||||
data: updateData,
|
||||
});
|
||||
|
||||
// Update campaign stats if applicable
|
||||
if (email.campaignId) {
|
||||
const campaignUpdate: Prisma.CampaignUpdateInput = {};
|
||||
|
||||
switch (eventType) {
|
||||
case 'delivered':
|
||||
campaignUpdate.deliveredCount = {increment: 1};
|
||||
break;
|
||||
|
||||
case 'opened':
|
||||
// Only increment unique opens to match getStats logic
|
||||
if (!email.openedAt) {
|
||||
campaignUpdate.openedCount = {increment: 1};
|
||||
}
|
||||
break;
|
||||
|
||||
case 'clicked':
|
||||
// Only increment unique clicks to match getStats logic
|
||||
if (!email.clickedAt) {
|
||||
campaignUpdate.clickedCount = {increment: 1};
|
||||
}
|
||||
break;
|
||||
|
||||
case 'bounced':
|
||||
campaignUpdate.bouncedCount = {increment: 1};
|
||||
break;
|
||||
}
|
||||
|
||||
if (Object.keys(campaignUpdate).length > 0) {
|
||||
await prisma.campaign.update({
|
||||
where: {id: email.campaignId},
|
||||
data: campaignUpdate,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Track event
|
||||
await prisma.event.create({
|
||||
data: {
|
||||
|
||||
@@ -25,7 +25,20 @@ import {TemplateSelectionDialog} from '../../components/TemplateSelectionDialog'
|
||||
import {CampaignSelectionDialog} from '../../components/CampaignSelectionDialog';
|
||||
import {network} from '../../lib/network';
|
||||
import {formatRelativeTime} from '../../lib/dateUtils';
|
||||
import {Calendar, ChevronDown, Copy, FileText, Info, Mail, Plus, RefreshCw, Trash2, Users} from 'lucide-react';
|
||||
import {
|
||||
AlertCircle,
|
||||
Calendar,
|
||||
ChevronDown,
|
||||
Copy,
|
||||
FileText,
|
||||
Info,
|
||||
Mail,
|
||||
MousePointerClick,
|
||||
Plus,
|
||||
RefreshCw,
|
||||
Trash2,
|
||||
Users,
|
||||
} from 'lucide-react';
|
||||
import {NextSeo} from 'next-seo';
|
||||
import Link from 'next/link';
|
||||
import {useRouter} from 'next/router';
|
||||
@@ -426,7 +439,7 @@ export default function CampaignsPage() {
|
||||
{campaign.clickedCount > 0 && (
|
||||
<div className="bg-orange-50 border border-orange-100 rounded-lg p-3">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<Mail className="h-3.5 w-3.5 text-orange-600" />
|
||||
<MousePointerClick className="h-3.5 w-3.5 text-orange-600" />
|
||||
<span className="text-xs font-medium text-orange-900">Clicks</span>
|
||||
</div>
|
||||
<p className="text-lg font-bold text-orange-900">{clickRate.toFixed(1)}%</p>
|
||||
@@ -436,6 +449,20 @@ export default function CampaignsPage() {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Bounced Rate */}
|
||||
{campaign.bouncedCount > 0 && campaign.sentCount > 0 && (
|
||||
<div className="bg-red-50 border border-red-100 rounded-lg p-3">
|
||||
<div className="flex items-center gap-2 mb-1">
|
||||
<AlertCircle className="h-3.5 w-3.5 text-red-600" />
|
||||
<span className="text-xs font-medium text-red-900">Bounced</span>
|
||||
</div>
|
||||
<p className="text-lg font-bold text-red-900">
|
||||
{((campaign.bouncedCount / campaign.sentCount) * 100).toFixed(1)}%
|
||||
</p>
|
||||
<p className="text-xs text-red-700 mt-1">{campaign.bouncedCount.toLocaleString()} bounced</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Scheduled For */}
|
||||
{campaign.scheduledFor && (
|
||||
<div className="bg-green-50 border border-green-100 rounded-lg p-3 md:col-span-2">
|
||||
|
||||
Reference in New Issue
Block a user