feat: streak counter to count how many days a user has posted consecutively

This commit is contained in:
2025-07-21 18:43:07 +00:00
parent 0004557bb5
commit 200bc973b8
3 changed files with 101 additions and 11 deletions
+39 -1
View File
@@ -42,6 +42,40 @@ def init_db():
cursor.close()
conn.close()
def calculate_streak():
conn = get_db_connection()
cursor = conn.cursor()
cursor.execute("SELECT date FROM journal_entry ORDER BY date DESC")
dates = [row[0] for row in cursor.fetchall()]
cursor.close()
conn.close()
if not dates:
return 0
streak = 0
today = datetime.now(tz).date()
from datetime import timedelta
for i, entry_date in enumerate(dates):
# entry_date is a date object or string, ensure date object
if isinstance(entry_date, str):
entry_date = dt.strptime(entry_date, "%Y-%m-%d").date()
if i == 0:
# First entry: must be today or yesterday to start streak
if entry_date == today:
streak = 1
elif entry_date == today - timedelta(days=1):
streak = 1
today = entry_date
else:
break
else:
expected = today - timedelta(days=1)
if entry_date == expected:
streak += 1
today = entry_date
else:
break
return streak
@app.route('/')
def index():
page = request.args.get('page', 1, type=int)
@@ -61,7 +95,8 @@ def index():
has_prev = page > 1
has_next = offset + per_page < total
now = datetime.now(tz)
return render_template('index.html', entries=entries, today=today, page=page, has_prev=has_prev, has_next=has_next, now=now, todays_entry=todays_entry)
streak = calculate_streak()
return render_template('index.html', entries=entries, today=today, page=page, has_prev=has_prev, has_next=has_next, now=now, todays_entry=todays_entry, streak=streak)
@app.route('/add', methods=['POST'])
def add_entry():
@@ -193,3 +228,6 @@ def delete_entry(entry_id):
init_db()
logging.info('EchoLog started up successfully.')
if __name__ == '__main__':
app.run(host='0.0.0.0', port='5000')
+1 -1
View File
@@ -4,4 +4,4 @@ echo "Generating CSS..."
./tailwindcss -i ./static/input.css -o ./static/output.css --content "./templates/*.html" --minify
echo "Starting app..."
gunicorn --workers 2 --bind 0.0.0.0:5000 app:app --log-level warning
python app.py
+60 -8
View File
@@ -23,16 +23,68 @@
</head>
<body class="bg-gradient-to-br from-gray-900 via-gray-800 to-gray-900 min-h-screen text-white">
<div class="container mx-auto max-w-2xl p-6">
<header class="mb-8 flex items-center justify-between">
<div>
<a href="/"><h1 class="text-4xl font-extrabold tracking-tight bg-gradient-to-r from-blue-400 via-purple-400 to-pink-400 bg-clip-text text-transparent">EchoLog</h1></a>
<p class="text-gray-400 mt-1">Your personal homelab journal</p>
</div>
<style>
@media (max-width: 767px) {
.logout-mobile {
position: absolute;
top: 0.75rem;
right: 0.75rem;
z-index: 10;
display: block;
}
.streak-mobile {
display: flex;
justify-content: center;
margin-top: 1rem;
gap: 0.75rem;
}
.streak-desktop {
display: none !important;
}
}
@media (min-width: 768px) {
.logout-mobile {
display: none !important;
}
.streak-mobile {
display: none !important;
}
.streak-desktop {
display: flex !important;
align-items: center;
margin-top: 0;
}
}
</style>
<header class="mb-8 relative">
{% if session.logged_in %}
<a href="/logout" class="text-gray-300 hover:text-pink-400 transition text-xl" title="Logout">
<i class="fas fa-sign-out-alt"></i>
</a>
<div class="logout-mobile mt-6">
<a href="/logout" class="text-gray-300 hover:text-pink-400 transition text-xl" title="Logout">
<i class="fas fa-sign-out-alt"></i>
</a>
</div>
{% endif %}
<div class="flex flex-col items-center md:flex-row md:items-center md:justify-between md:gap-6">
<div class="w-full md:w-auto">
<a href="/"><h1 class="text-4xl font-extrabold tracking-tight leading-normal bg-gradient-to-r from-blue-400 via-purple-400 to-pink-400 bg-clip-text text-transparent">EchoLog</h1></a>
<p class="text-gray-400">Your personal homelab journal</p>
</div>
<div class="streak-mobile">
<i class="fas fa-fire text-pink-400 text-2xl animate-pulse mr-0.2 mt-1"></i>
<span class="text-2xl font-extrabold text-blue-400 mr-0.2">{{ streak }}</span>
<span class="text-lg font-bold text-blue-400 mt-1">day{{ 's' if streak != 1 else '' }}</span>
</div>
<div class="streak-desktop">
<i class="fas fa-fire text-pink-400 text-2xl animate-pulse mr-2 mt-1" title="Streak Count"></i>
<span class="text-2xl font-extrabold text-blue-400 mr-2">{{ streak }}</span>
<span class="text-lg font-bold text-blue-400 mt-1">day{{ 's' if streak != 1 else '' }}</span>
{% if session.logged_in %}
<a href="/logout" class="text-gray-300 hover:text-pink-400 transition text-xl ml-16 mt-1" title="Logout">
<i class="fas fa-sign-out-alt"></i>
</a>
{% endif %}
</div>
</div>
</header>
<form action="/add" method="POST" class="mb-8 bg-gray-800/80 rounded-xl shadow-lg p-6 border border-gray-700">