Goals working well
This commit is contained in:
111
templates/goals.html
Normal file
111
templates/goals.html
Normal file
@@ -0,0 +1,111 @@
|
||||
{% extends "layout.html" %}
|
||||
{% block content %}
|
||||
<div class="card" style="margin-bottom: 2rem;">
|
||||
<h2>My Goals</h2>
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1.5rem;">
|
||||
{% for goal in goals %}
|
||||
<div style="border: 1px solid var(--border-dim); border-radius: 8px; padding: 1.5rem; position: relative;">
|
||||
<div style="position: absolute; top: 10px; right: 10px;">
|
||||
<a href="{{ url_for('edit_goal', goal_id=goal._id) }}" style="color: var(--text-secondary); text-decoration: none; font-size: 0.9rem; margin-right: 8px;">Edit</a>
|
||||
<a href="{{ url_for('delete_goal', goal_id=goal._id) }}" style="color: var(--danger-color); text-decoration: none; font-size: 1.2rem;">×</a>
|
||||
</div>
|
||||
|
||||
<h3 style="font-size: 1.2rem; margin-bottom: 0.5rem; padding-right: 40px;">{{ goal.name }}</h3>
|
||||
<div style="font-size: 0.9rem; color: var(--text-secondary); margin-bottom: 1rem;">
|
||||
{{ goal.frequency|capitalize }} Target: {{ goal.target_hours }}h
|
||||
<br>
|
||||
<div style="margin-top: 5px;">
|
||||
<span style="background: {{ goal.activity_color }}; color: white; padding: 2px 6px; border-radius: 4px; font-size: 0.8rem;">
|
||||
{{ goal.activity_name }}
|
||||
</span>
|
||||
{% if goal.subcategory %}
|
||||
<span style="color: var(--text-secondary); font-size: 0.8rem;"> > {{ goal.subcategory }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display: flex; justify-content: space-between; align-items: flex-end; margin-bottom: 5px;">
|
||||
<!-- Use smart formatted progress (mins or hours) -->
|
||||
<span style="font-weight: bold; font-size: 1.5rem; color: var(--primary-color);">{{ goal.display_progress }}</span>
|
||||
<span style="font-size: 0.9rem; color: var(--text-secondary);">{{ goal.percent }}%</span>
|
||||
</div>
|
||||
|
||||
<!-- Progress Bar -->
|
||||
<div style="width: 100%; height: 8px; background: var(--bg-input); border-radius: 4px; overflow: hidden;">
|
||||
<div style="width: {{ goal.percent }}%; height: 100%; background: {% if goal.percent >= 100 %}#27ae60{% else %}var(--primary-color){% endif %}; transition: width 0.5s;"></div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<p style="color: var(--text-secondary);">No goals set yet.</p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card" style="max-width: 500px;">
|
||||
<h3>Set New Goal</h3>
|
||||
<form method="POST">
|
||||
<label>Goal Name</label>
|
||||
<input type="text" name="name" placeholder="e.g. Learn Python" required>
|
||||
|
||||
<label>Activity (Required)</label>
|
||||
<select name="activity_id" id="activitySelect" required onchange="updateSubcategories()">
|
||||
<option value="">-- Select Activity --</option>
|
||||
{% for act in activities %}
|
||||
<option value="{{ act._id }}" data-subcats='{{ act.subcategories|default([])|tojson }}'>{{ act.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
|
||||
<div id="subcatWrapper" style="display:none;">
|
||||
<label>Subcategory (Optional)</label>
|
||||
<select name="subcategory" id="subcategorySelect">
|
||||
<!-- Javascript will populate this -->
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<label>Frequency</label>
|
||||
<select name="frequency">
|
||||
<option value="daily">Daily</option>
|
||||
<option value="weekly">Weekly</option>
|
||||
<option value="monthly">Monthly</option>
|
||||
<option value="yearly">Yearly</option>
|
||||
</select>
|
||||
|
||||
<label>Target Hours</label>
|
||||
<input type="number" name="target_hours" step="0.5" placeholder="e.g. 1.0" required>
|
||||
|
||||
<button type="submit" class="btn" style="margin-top: 1rem;">Create Goal</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function updateSubcategories() {
|
||||
const actSelect = document.getElementById('activitySelect');
|
||||
const subWrapper = document.getElementById('subcatWrapper');
|
||||
const subSelect = document.getElementById('subcategorySelect');
|
||||
|
||||
const selectedOption = actSelect.options[actSelect.selectedIndex];
|
||||
|
||||
// Handle case where no activity is selected
|
||||
if (!selectedOption.value) {
|
||||
subWrapper.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
const subcats = JSON.parse(selectedOption.getAttribute('data-subcats') || '[]');
|
||||
|
||||
subSelect.innerHTML = '<option value="">-- All --</option>';
|
||||
|
||||
if (subcats && subcats.length > 0) {
|
||||
subWrapper.style.display = 'block';
|
||||
subcats.forEach(s => {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = s;
|
||||
opt.innerText = s;
|
||||
subSelect.appendChild(opt);
|
||||
});
|
||||
} else {
|
||||
subWrapper.style.display = 'none';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user