Goals working well

This commit is contained in:
2026-02-10 19:46:25 +01:00
parent 37190679ed
commit 9ef70e0436
5 changed files with 398 additions and 15 deletions

142
app.py
View File

@@ -2,7 +2,7 @@ from flask import Flask, render_template, request, redirect, url_for, session, f
from flask_bcrypt import Bcrypt
from pymongo import MongoClient
from bson.objectid import ObjectId
from datetime import datetime
from datetime import datetime, timedelta
import os
from dotenv import load_dotenv
@@ -109,18 +109,23 @@ def add_activity():
'user_id': get_user_id(),
'name': name,
'color': color,
'subcategories': [] # Initialize empty list
'subcategories': []
}).inserted_id
# Add optional tasks
tasks_text = request.form.get('tasks', '')
if tasks_text:
tasks = [t.strip() for t in tasks_text.split(',') if t.strip()]
# Add optional default tasks (Revised from list input)
tasks_str = request.form.get('tasks_list_data', '')
if tasks_str:
tasks = [t.strip() for t in tasks_str.split(',') if t.strip()]
for t in tasks:
db.task_templates.insert_one({
'activity_id': activity_id,
db.tasks.insert_one({
'user_id': get_user_id(),
'name': t
'name': t,
'activity_id': ObjectId(activity_id),
'is_template': True,
'status': 'open',
'time_entry_id': None,
'created_at': datetime.now(),
'comments': []
})
return redirect(url_for('index'))
@@ -183,7 +188,7 @@ def start_timer_bg(activity_id):
'user_id': user_id,
'name': t['name'],
'activity_id': ObjectId(activity_id),
'time_entry_id': new_entry_id,
'time_entry_id': new_entry_id, # Link to this specific session
'status': 'open',
'is_template': False,
'created_at': datetime.now(),
@@ -498,5 +503,122 @@ def log_entry_detail(entry_id):
return render_template('logbook_detail.html', entry=entry, tasks=tasks)
@app.route('/goals', methods=['GET', 'POST'])
def goals():
if not is_logged_in(): return redirect(url_for('login'))
user_id = get_user_id()
# Handle creating new goal
if request.method == 'POST':
name = request.form['name']
target_hours = float(request.form['target_hours'])
frequency = request.form['frequency'] # daily, weekly, monthly, yearly
activity_id = request.form.get('activity_id') # Required now
subcategory = request.form.get('subcategory', '')
if not activity_id:
flash("You must select an activity for this goal.")
return redirect(url_for('goals'))
db.goals.insert_one({
'user_id': user_id,
'name': name,
'target_hours': target_hours,
'frequency': frequency,
'activity_id': ObjectId(activity_id),
'subcategory': subcategory,
'created_at': datetime.now()
})
return redirect(url_for('goals'))
# Fetch goals and calculate progress
goals_list = list(db.goals.find({'user_id': user_id}))
activities = list(db.activities.find({'user_id': user_id}))
today = datetime.now()
start_of_today = today.replace(hour=0, minute=0, second=0, microsecond=0)
# Determine date ranges
ranges = {
'daily': start_of_today,
'weekly': start_of_today - timedelta(days=today.weekday()), # Monday
'monthly': start_of_today.replace(day=1),
'yearly': start_of_today.replace(month=1, day=1)
}
for goal in goals_list:
start_date = ranges.get(goal['frequency'], start_of_today)
query = {
'user_id': user_id,
'start_time': {'$gte': start_date},
'end_time': {'$ne': None}
}
if goal.get('activity_id'):
query['activity_id'] = goal['activity_id']
if goal.get('subcategory'):
query['subcategory'] = goal['subcategory']
entries = list(db.time_entries.find(query))
total_seconds = sum([(e['end_time'] - e['start_time']).total_seconds() for e in entries])
current_hours = total_seconds / 3600
# Display formatting: Show minutes if < 1 hour, else show hours
if current_hours > 0 and current_hours < 1:
minutes = int(total_seconds / 60)
goal['display_progress'] = f"{minutes}m"
else:
goal['display_progress'] = f"{round(current_hours, 1)}h"
goal['current_hours'] = round(current_hours, 1) # Keep purely numeric for math/sorting if needed
goal['percent'] = min(100, int((current_hours / goal['target_hours']) * 100))
# Link activity name for display
if goal.get('activity_id'):
act = db.activities.find_one({'_id': goal['activity_id']})
goal['activity_name'] = act['name'] if act else 'Unknown'
goal['activity_color'] = act['color'] if act else '#ccc'
return render_template('goals.html', goals=goals_list, activities=activities)
@app.route('/edit_goal/<goal_id>', methods=['GET', 'POST'])
def edit_goal(goal_id):
if not is_logged_in(): return redirect(url_for('login'))
user_id = get_user_id()
if request.method == 'POST':
name = request.form['name']
target_hours = float(request.form['target_hours'])
frequency = request.form['frequency']
activity_id = request.form.get('activity_id')
subcategory = request.form.get('subcategory', '')
db.goals.update_one(
{'_id': ObjectId(goal_id), 'user_id': user_id},
{'$set': {
'name': name,
'target_hours': target_hours,
'frequency': frequency,
'activity_id': ObjectId(activity_id),
'subcategory': subcategory
}}
)
return redirect(url_for('goals'))
goal = db.goals.find_one({'_id': ObjectId(goal_id), 'user_id': user_id})
if not goal: return "Goal not found", 404
activities = list(db.activities.find({'user_id': user_id}))
return render_template('edit_goal.html', goal=goal, activities=activities)
@app.route('/delete_goal/<goal_id>')
def delete_goal(goal_id):
if not is_logged_in(): return redirect(url_for('login'))
db.goals.delete_one({'_id': ObjectId(goal_id), 'user_id': get_user_id()})
return redirect(url_for('goals'))
if __name__ == '__main__':
app.run(debug=True)