Compute dashboard stats
Some checks failed
Rust / Test (push) Has been cancelled
Rust / Rustfmt (push) Has been cancelled
Rust / Clippy (push) Has been cancelled
Rust / Code coverage (push) Has been cancelled

Track open rate for new post notifications (user clicked the button in
the link or not). No data about the user is collected during the
process, it only uses an ID inserted by the issue delivery worker.
This commit is contained in:
Alphonse Paix
2025-09-24 04:30:27 +02:00
parent 33281132c6
commit 4cb1d2b6fd
19 changed files with 303 additions and 60 deletions

View File

@@ -34,8 +34,24 @@
</svg>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Total subscribers</p>
<p class="text-2xl font-semibold text-gray-900">2,143</p>
<p class="text-sm font-medium text-gray-500">Subscribers</p>
<p class="text-2xl font-semibold text-gray-900">{{ stats.subscribers }}</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6 border border-gray-200">
<div class="flex items-center">
<div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center shrink-0">
<svg class="w-6 h-6 text-purple-600 mr-2"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 20h9M12 4h9M5 4h.01M5 20h.01M5 12h.01M9 16h6M9 8h6" />
</svg>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Posts</p>
<p class="text-2xl font-semibold text-gray-900">{{ stats.posts }}</p>
</div>
</div>
</div>
@@ -50,8 +66,8 @@
</svg>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Issues sent</p>
<p class="text-2xl font-semibold text-gray-900">23</p>
<p class="text-sm font-medium text-gray-500">Notifications</p>
<p class="text-2xl font-semibold text-gray-900">{{ stats.notifications_sent }}</p>
</div>
</div>
</div>
@@ -68,23 +84,7 @@
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Open rate</p>
<p class="text-2xl font-semibold text-gray-900">68%</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg shadow-md p-6 border border-gray-200">
<div class="flex items-center">
<div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center shrink-0">
<svg class="w-6 h-6 text-purple-600"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 7h8m0 0v8m0-8l-8 8-4-4-6 6" />
</svg>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Growth</p>
<p class="text-2xl font-semibold text-gray-900">+12%</p>
<p class="text-2xl font-semibold text-gray-900">{{ stats.formatted_rate() }}</p>
</div>
</div>
</div>

View File

@@ -7,7 +7,8 @@
<h2 class="post-title">{{ post_title }}</h2>
{% if !post_excerpt.is_empty() %}<p class="post-excerpt">{{ post_excerpt }}</p>{% endif %}
</div>
<a href="{{ base_url }}/posts/{{ post_id }}" class="cta-button">Read the full post →</a>
<a href="{{ base_url }}/posts/{{ post_id }}?origin=EMAIL_ID"
class="cta-button">Read the full post →</a>
<p>
This post covers practical insights and real-world examples that I hope will be valuable for your backend development journey.
</p>