Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions analytics/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ def weekly_analytics(request):
campaigns = Campaign.objects.filter(user=request.user, id=campaign_id)
else:
campaigns = Campaign.objects.filter(user=request.user)

selected_campaign = campaigns.first() if campaign_id else None
subscriber_list = selected_campaign.subscriber_list if selected_campaign else None

# Calculate date range for the past 7 days
end_date = timezone.now()
Expand All @@ -107,6 +110,7 @@ def weekly_analytics(request):
'delivery_rate': 0,
'open_rate': 0,
'click_rate': 0,
'subscriber_count': 0,
}

# Get all email events for user's campaigns in the past 7 days
Expand Down Expand Up @@ -151,6 +155,13 @@ def weekly_analytics(request):
if delivered > 0:
data['open_rate'] = round((opened / delivered) * 100, 2)
data['click_rate'] = round((clicked / delivered) * 100, 2)

if subscriber_list:
date_obj = datetime.strptime(date_str, '%Y-%m-%d').date()
day_end = timezone.make_aware(datetime.combine(date_obj, datetime.max.time()))
data['subscriber_count'] = subscriber_list.subscribers.filter(
created_at__lte=day_end
).count()

# Convert to sorted list
result = sorted(daily_data.values(), key=lambda x: x['date'])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ What DripEmails.org offers:
- Gmail + IMAP auto-engagement workflows
- Multi-step drip campaigns with flexible timing
- AI-assisted drafting and revision for campaign emails
- Personalized templates with merge fields like {{first_name}}, {{last_name}}, and {{email}}
- Personalized templates with merge fields like {{first_name}} and {{email}}
- Campaign analytics (opens, clicks, and engagement tracking)

If useful, I can share:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Product highlights:
- Gmail + IMAP integration for inbox-aware automation
- Configurable multi-step drip sequences
- AI-assisted writing and message revision
- Merge-field personalization including {{first_name}}, {{last_name}}, and {{email}}
- Merge-field personalization including {{first_name}}, and {{email}}
- Engagement analytics for optimization over time

Happy to provide anything useful for coverage:
Expand Down
94 changes: 87 additions & 7 deletions templates/campaigns/campaign_analysis.html
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ <h2 class="text-lg font-semibold text-gray-900">{% trans "Campaign Statistics" %
<div class="mb-6">
<h2 class="text-lg font-medium mb-2">{% trans "Past 7 Days Trends" %}</h2>
<!-- Rate charts with data -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
<div class="p-4 bg-white rounded border">
<h3 class="text-sm text-gray-600 mb-2">{% trans "Delivery Rate" %}</h3>
<div style="height: 150px; position: relative;">
Expand All @@ -109,6 +109,18 @@ <h3 class="text-sm text-gray-600 mb-2">{% trans "Click-Through Rate" %}</h3>
<canvas id="clickRateChart"></canvas>
</div>
</div>
<div class="p-4 bg-white rounded border">
<h3 class="text-sm text-gray-600 mb-2">{% trans "Subscribers" %}</h3>
<div style="height: 150px; position: relative;">
{% if campaign.subscriber_list %}
<canvas id="subscriberTrendChart"></canvas>
{% else %}
<div class="h-full flex items-center justify-center text-center px-3">
<p class="text-sm text-gray-500 font-medium">{% trans "No subscribers found for this campaign" %}</p>
</div>
{% endif %}
</div>
</div>
</div>
</div>

Expand Down Expand Up @@ -200,6 +212,7 @@ <h2 class="text-lg font-semibold text-gray-900 mb-2">{% trans "Per-email breakdo
let deliveryChart = null;
let openChart = null;
let clickChart = null;
let subscriberChart = null;

// Wait for DOM to be ready
document.addEventListener('DOMContentLoaded', function() {
Expand Down Expand Up @@ -253,11 +266,12 @@ <h2 class="text-lg font-semibold text-gray-900 mb-2">{% trans "Per-email breakdo
const deliveryRates = weeklyData.map(d => d.delivery_rate);
const openRates = weeklyData.map(d => d.open_rate);
const clickRates = weeklyData.map(d => d.click_rate);
const subscriberCounts = weeklyData.map(d => d.subscriber_count || 0);

console.log('Chart data:', { dates, deliveryRates, openRates, clickRates });
console.log('Chart data:', { dates, deliveryRates, openRates, clickRates, subscriberCounts });

// Common chart options
const commonOptions = {
// Common chart options for percentage-based charts
const rateChartOptions = {
responsive: true,
maintainAspectRatio: false,
plugins: {
Expand Down Expand Up @@ -297,6 +311,45 @@ <h2 class="text-lg font-semibold text-gray-900 mb-2">{% trans "Per-email breakdo
}
}
};

// Common chart options for raw subscriber count chart
const subscriberChartOptions = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: false
},
tooltip: {
mode: 'index',
intersect: false
}
},
scales: {
y: {
beginAtZero: true,
ticks: {
precision: 0,
font: {
size: 10
}
},
grid: {
display: true
}
},
x: {
ticks: {
font: {
size: 10
}
},
grid: {
display: false
}
}
}
};

// Delivery Rate Chart
const deliveryRateCtx = document.getElementById('deliveryRateChart');
Expand All @@ -320,7 +373,7 @@ <h2 class="text-lg font-semibold text-gray-900 mb-2">{% trans "Per-email breakdo
tension: 0.4
}]
},
options: commonOptions
options: rateChartOptions
});
console.log('Delivery chart created:', deliveryChart);
} else {
Expand Down Expand Up @@ -349,7 +402,7 @@ <h2 class="text-lg font-semibold text-gray-900 mb-2">{% trans "Per-email breakdo
tension: 0.4
}]
},
options: commonOptions
options: rateChartOptions
});
console.log('Open chart created:', openChart);
} else {
Expand Down Expand Up @@ -378,12 +431,39 @@ <h2 class="text-lg font-semibold text-gray-900 mb-2">{% trans "Per-email breakdo
tension: 0.4
}]
},
options: commonOptions
options: rateChartOptions
});
console.log('Click chart created:', clickChart);
} else {
console.error('Click Rate Canvas not found!');
}

// Subscriber Trend Chart
const subscriberTrendCtx = document.getElementById('subscriberTrendChart');
console.log('Subscriber Trend Canvas:', subscriberTrendCtx);
if (subscriberTrendCtx) {
if (subscriberChart) {
subscriberChart.destroy();
}
console.log('Creating subscriber trend chart...');
subscriberChart = new Chart(subscriberTrendCtx.getContext('2d'), {
type: 'line',
data: {
labels: dates,
datasets: [{
label: 'Subscribers',
data: subscriberCounts,
borderColor: 'rgb(99, 102, 241)',
backgroundColor: 'rgba(99, 102, 241, 0.1)',
borderWidth: 2,
fill: true,
tension: 0.4
}]
},
options: subscriberChartOptions
});
console.log('Subscriber chart created:', subscriberChart);
}
})
.catch(error => {
console.error('Error loading weekly analytics:', error);
Expand Down