Finished Multi-Habit-List feature and multiple habits for each habit_list

This commit is contained in:
Verox 2024-02-12 22:06:27 +01:00
parent 4dd997ce13
commit 4764112296
20 changed files with 348 additions and 493 deletions

54
app.py
View File

@ -5,6 +5,7 @@ from flask import Flask, render_template, redirect, url_for, request
from flask_login import login_required, LoginManager, login_user, logout_user, current_user from flask_login import login_required, LoginManager, login_user, logout_user, current_user
from models.Habit import Habit from models.Habit import Habit
from models.HabitList import HabitList
from models.HabitTrackings import HabitTrackings from models.HabitTrackings import HabitTrackings
from models.User import User from models.User import User
from utils import anonymous_required from utils import anonymous_required
@ -120,20 +121,20 @@ def logout():
@app.route('/') @app.route('/')
def index(): def index():
if current_user.is_authenticated: if current_user.is_authenticated:
habits = current_user.get_habits() habit_lists = current_user.get_habitLists()
name = "Hallo " + current_user.name name = "Hallo " + current_user.name
else: else:
habits = [] habit_lists = []
name = "Bitte melde dich an." name = "Bitte melde dich an."
# Sort habits by whether they have been checked today and then by slot # Sort habits by whether they have been checked today and then by slot
habits.sort(key=lambda habit: (habit.checked, habit.slot)) # habits.sort(key=lambda habit: (habit.checked, habit.slot))
return render_template( return render_template(
'index.html', 'index.html',
title=name, title=name,
utc_dt=datetime.datetime.now().strftime("%d.%m.%Y %H:%M %A"), utc_dt=datetime.datetime.now().strftime("%d.%m.%Y %H:%M %A"),
habits=habits, habit_lists=habit_lists,
errors={}, errors={},
) )
@ -156,6 +157,7 @@ def habit_create():
note = request.form.get('note') note = request.form.get('note')
times = request.form.get('times') times = request.form.get('times')
unit = request.form.get('unit') unit = request.form.get('unit')
list_id = request.form.get('list_query')
# Check for errors # Check for errors
errors = {} errors = {}
@ -167,6 +169,8 @@ def habit_create():
note = '' note = ''
if not unit: if not unit:
errors['unit'] = 'Die Einheit ist erforderlich.' errors['unit'] = 'Die Einheit ist erforderlich.'
if not list_id:
errors['list_query'] = 'Die Habitliste ist erforderlich.'
# Check if times is an integer # Check if times is an integer
try: try:
@ -190,7 +194,8 @@ def habit_create():
note=note, note=note,
times=times, times=times,
unit=unit, unit=unit,
errors=errors errors=errors,
list_id=list_id
) )
# Map unit to integer # Map unit to integer
@ -212,6 +217,45 @@ def habit_create():
return redirect(url_for('index')) return redirect(url_for('index'))
@app.route('/habit-list')
@login_required
def habit_list_creation():
return render_template(
'habit-list.html',
title='Erstelle eine Habitliste',
errors={},
)
@app.route('/habit-list', methods=['POST'])
@login_required
def habit_list_create():
name = request.form.get('name')
description = request.form.get('description')
# Check for errors
errors = {}
if not name:
errors['name'] = 'Der Name ist erforderlich.'
if not description:
note = ''
if errors:
return render_template(
'habit-list.html',
title='Erstelle eine Habitliste',
name=name,
description=description,
errors=errors
)
# Save habit to database
habit = HabitList.create(current_user.id, name, description)
# Back to index
return redirect(url_for('index'))
@app.route('/profile') @app.route('/profile')
@login_required @login_required
def profile(): def profile():

View File

@ -102,24 +102,46 @@ def get_habits(list_id: int):
def get_heatmap_value(user_id: int, days: int): def get_heatmap_value(user_id: int, days: int):
# Berechnet das Datum, ab dem die Habits gezählt werden sollen
date = (datetime.now() - timedelta(days=days)).date() date = (datetime.now() - timedelta(days=days)).date()
print(date) print(date)
query = f"SELECT id FROM habits WHERE (SELECT id FROM habit_lists WHERE (SELECT list_id FROM habit_users WHERE user_id = {user_id}) = id) = list_id;"
query2 = (f"SELECT habits.id FROM habits, habit_trackings WHERE (SELECT id FROM habit_lists WHERE (SELECT list_id FROM habit_users WHERE user_id = {user_id}) = id) = list_id " # Uses JOINs to get all Habits
f"AND habits.created_at LIKE '{date}%' AND habit_trackings.habit_id = habits.id;") query = (f"SELECT habits.id FROM habits "
print(query2) f"JOIN habit_lists ON habits.list_id = habit_lists.id "
f"JOIN habit_users ON habit_lists.id = habit_users.list_id "
f"WHERE habit_users.user_id = {user_id};")
# Uses JOINs to get all checked Habits on a specific date
query2 = (f"SELECT habits.id FROM habits "
f"JOIN habit_lists ON habits.list_id = habit_lists.id "
f"JOIN habit_users ON habit_lists.id = habit_users.list_id "
f"JOIN habit_trackings ON habits.id = habit_trackings.habit_id "
f"WHERE habit_users.user_id = {user_id} AND DATE(habit_trackings.created_at) = '{date}';")
conn = con3() conn = con3()
cursor = conn.cursor() cursor = conn.cursor()
# Execute the queries
cursor.execute(query) cursor.execute(query)
all_habits = cursor.fetchall() all_habits = cursor.fetchall()
cursor.execute(query2) cursor.execute(query2)
checked_habits = cursor.fetchall() checked_habits = cursor.fetchall()
# Close the database connection
count = len(all_habits) count = len(all_habits)
print(count) print(count)
count2 = len(checked_habits) count2 = len(checked_habits)
print(count2) print(count2)
# Close the database connection
conn.close() conn.close()
# Calculate the percentage of checked Habits
if count > 0:
return int(count2 / count * 100) return int(count2 / count * 100)
else:
return 0
def get_next_slot(list_id: int): def get_next_slot(list_id: int):
@ -219,17 +241,22 @@ def delete_habitTrackings(id: int):
def create_habitList(user_id: int, name: str, description: str): def create_habitList(user_id: int, name: str, description: str):
now = datetime.now().isoformat() now = datetime.now().isoformat()
query = ( query = (
f"INSERT INTO habit_lists (user_id, name, description, created_at, updated_at) VALUES ('{user_id}', '{name}', '{description}', '{now}');") f"INSERT INTO habit_lists (name, description, created_at, updated_at) VALUES ('{name}', '{description}', '{now}', '{now}');")
conn = con3() conn = con3()
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(query) cursor.execute(query)
query1 = f"INSERT INTO habit_users (user_id, list_id, created_at, updated_at) VALUES ('{user_id}', '{cursor.lastrowid}', '{now}', '{now}');"
cursor.execute(query1)
conn.commit() conn.commit()
conn.close() conn.close()
return cursor.lastrowid return cursor.lastrowid
def get_habitList(id: int): def get_habitList(id: int):
query = f"SELECT * FROM habit_list WHERE id = {id};" query = f"SELECT * FROM habit_lists WHERE id = {id};"
conn = con3() conn = con3()
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(query) cursor.execute(query)
@ -239,7 +266,7 @@ def get_habitList(id: int):
def get_habitLists(user_id: int): def get_habitLists(user_id: int):
query = f"SELECT * FROM habit_list WHERE user_id = {user_id};" query = f"SELECT habit_lists.* FROM habit_lists JOIN habit_users ON habit_lists.id = habit_users.list_id WHERE habit_users.user_id = {user_id};"
conn = con3() conn = con3()
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(query) cursor.execute(query)
@ -250,7 +277,7 @@ def get_habitLists(user_id: int):
def update_habitList(id: int, name: str, description: str): def update_habitList(id: int, name: str, description: str):
now = datetime.now().isoformat() now = datetime.now().isoformat()
query = f"UPDATE habit_list SET name = {name}, description = {description}, updated_at = '{now}' WHERE id = {id};" query = f"UPDATE habit_lists SET name = {name}, description = {description}, updated_at = '{now}' WHERE id = {id};"
conn = con3() conn = con3()
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(query) cursor.execute(query)
@ -260,7 +287,7 @@ def update_habitList(id: int, name: str, description: str):
def delete_habitList(id: int): def delete_habitList(id: int):
query = f"DELETE FROM habit_list WHERE id = {id};" query = f"DELETE FROM habit_lists WHERE id = {id};"
conn = con3() conn = con3()
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute(query) cursor.execute(query)

View File

@ -1,9 +0,0 @@
CREATE TABLE IF NOT EXISTS habits
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
note TEXT NULL,
times INTEGER NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);

View File

@ -1 +0,0 @@
DROP TABLE habits;

View File

@ -1,12 +0,0 @@
CREATE TABLE IF NOT EXISTS habits
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER,
name TEXT NOT NULL,
note TEXT,
times INTEGER NOT NULL,
unit INTEGER,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id)
);

View File

@ -1 +0,0 @@
DROP TABLE habits;

View File

@ -1,13 +0,0 @@
CREATE TABLE IF NOT EXISTS habits
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
name TEXT NOT NULL,
note TEXT,
times INTEGER NOT NULL,
unit INTEGER,
list_index INTEGER NOT NULL,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id)
);

View File

@ -1 +0,0 @@
DROP TABLE habits;

View File

@ -1,2 +0,0 @@
INSERT INTO users (name, email, password, created_at, updated_at)
VALUES ('Nikolaus MikeyMouse', 'Nordpol@icloud.com', 'a36c101570cc4410993de5385ad7034adb2dae6a05139ac7672577803084634d', '23:00', '23:00');

View File

@ -1,2 +0,0 @@
INSERT INTO habits (user_id, name, note, times, unit, slot, created_at, updated_at)
VALUES ('1', 'Sport', '10x Liegestutze', '1', '1', '1', '23:00', '23:00');

View File

@ -1,2 +0,0 @@
INSERT INTO habits (user_id, name, note, times, unit, slot, created_at, updated_at)
VALUES ('1', 'Sport', '10x Klimmzuge', '1', '1', '3', '23:00', '23:00');

View File

@ -1,2 +0,0 @@
INSERT INTO habits (user_id, name, note, times, unit, slot, created_at, updated_at)
VALUES ('1', 'Essen', '1x Gemüse', '1', '2', '2', '23:00', '23:00');

View File

@ -1,2 +0,0 @@
INSERT INTO habits (user_id, name, note, times, unit, slot, created_at, updated_at)
VALUES ('2', 'Sport', '10x Liegestutze', '1', '1', '2', '23:00', '23:00');

View File

@ -9,7 +9,6 @@ from models.Habit import Habit
@dataclass @dataclass
class HabitList: class HabitList:
id: int id: int
user_id: int
name: str name: str
description: str description: str
created_at: date created_at: date
@ -18,12 +17,12 @@ class HabitList:
@staticmethod @staticmethod
def create(user_id: int, name: str, description: str): def create(user_id: int, name: str, description: str):
id = create_habitList(user_id, name, description) id = create_habitList(user_id, name, description)
return HabitList(id, user_id, name, description, datetime.now(), datetime.now()) return HabitList(id, name, description, datetime.now(), datetime.now())
@staticmethod @staticmethod
def get(id: int): def get(id: int):
habitList = get_habitList(id) habitList = get_habitList(id)
return HabitList(habitList[0], habitList[1], habitList[2], habitList[3], datetime.strptime(habitList[4], "%Y-%m-%dT%H:%M:%S.%f"), datetime.strptime(habitList[5], "%Y-%m-%dT%H:%M:%S.%f")) if habitList else None return HabitList(habitList[0], habitList[1], habitList[2], datetime.strptime(habitList[3], "%Y-%m-%dT%H:%M:%S.%f"), datetime.strptime(habitList[4], "%Y-%m-%dT%H:%M:%S.%f")) if habitList else None
def delete(self): def delete(self):
delete_habitTrackings(self.id) delete_habitTrackings(self.id)

View File

@ -47,7 +47,7 @@ class User(UserMixin):
raw_habitLists = get_habitLists(self.id) raw_habitLists = get_habitLists(self.id)
habitLists = [] habitLists = []
for habitList in raw_habitLists: for habitList in raw_habitLists:
habitList = HabitList(habitList[0], habitList[1], habitList[2], habitList[3], datetime.strptime(habitList[4], "%Y-%m-%dT%H:%M:%S.%f"), datetime.strptime(habitList[5], "%Y-%m-%dT%H:%M:%S.%f")) habitList = HabitList(habitList[0], habitList[1], habitList[2], datetime.strptime(habitList[3], "%Y-%m-%dT%H:%M:%S.%f"), datetime.strptime(habitList[4], "%Y-%m-%dT%H:%M:%S.%f"))
habitLists.append(habitList) habitLists.append(habitList)
return habitLists return habitLists

25
templates/habit-list.html Normal file
View File

@ -0,0 +1,25 @@
{% extends 'layouts/main.html' %}
{% block content %}
<h1 class="mt-5">Habitliste erstellen📋</h1>
<form action="/habit-list" method="POST">
<div class="mb-3">
<label for="name" class="form-label">Name der Liste</label>
<input type="text" class="form-control {% if errors.get('name') %} is-invalid {% endif %}" id="name" name="name" value="{{name}}">
<div class="invalid-feedback">
{{ errors.get('name', '') }}
</div>
</div>
<div class="mb-3">
<label for="description" class="form-label">Beschreibung</label>
<input type="text" class="form-control {% if errors.get('description') %} is-invalid {% endif %}" id="description" name="description" value="{{description}}">
<div class="invalid-feedback">
{{ errors.get('description', '') }}
</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endblock %}

View File

@ -54,6 +54,28 @@
</div> </div>
</div> </div>
<input type="hidden" name="list_query" id="list_query" class="{% if errors.get('list_query') %} is-invalid {% endif %}">
<div class="invalid-feedback">
{{ errors.get('list_query', '') }}
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Extracting the list-query from the URL
var listQuery = new URLSearchParams(window.location.search).get('list');
if ("{{ list_id }}" != "") {
listQuery = "{{ list_id }}";
// Add the list_id to the URL
var url = new URL(window.location.href);
url.searchParams.set('list', listQuery);
// window.history.pushState({}, '', url);
}
// Setting the list-query as the value of the hidden input field
document.getElementById('list_query').value = listQuery;
});
</script>
<button type="submit" class="btn btn-primary">Submit</button> <button type="submit" class="btn btn-primary">Submit</button>
</form> </form>

View File

@ -1,11 +1,11 @@
{% extends 'layouts/main.html' %} {% extends 'layouts/main.html' %}
{% block content %} {% block content %}
<h1>{{ title }}</h1> <h1>{{ title }}</h1>
<h3>{{ utc_dt }}</h3> <h3>{{ utc_dt }}</h3>
<style> <style>
#heatmap { #heatmap {
display: grid; display: grid;
grid-template-columns: repeat(7, 0fr); /* 7 Tage in einer Woche */ grid-template-columns: repeat(7, 0fr); /* 7 Tage in einer Woche */
@ -20,9 +20,9 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
</style> </style>
<div class="row"> <div class="row">
<div class="col-md-5 col-12"> <div class="col-md-5 col-12">
<div id="heatmap"></div> <div id="heatmap"></div>
@ -82,20 +82,28 @@
</script> </script>
<div class="col-md-7 col-12"> <div class="col-md-7 col-12">
<div class="row mb-3"> <div class="row mb-3">
<h2 class="col-9">Gewohnheiten</h2> <h2 class="col-9">Gewohnheiten</h2>
<a class="col-3 btn btn-primary" role="button" href="/habit">Gewohnheit erstellen</a> <a class="col-3 btn btn-primary" role="button" href="/habit-list">Neue Liste erstellen</a>
</div>
{% for habit_list in habit_lists %}
<div class="row mb-3">
<h2 class="col-9">{{ habit_list.name }}</h2>
<a class="col-3 btn btn-primary" role="button" href="/habit?list={{ habit_list.id }}">Gewohnheit erstellen</a>
</div> </div>
<ul class="task-list row"> <ul class="task-list row">
{% for habit in habits %} {% for habit in habit_list.get_habits() %}
<li class="row d-flex align-items-center mb-2" id="habit-{{habit.id}}"> <li class="row d-flex align-items-center mb-2" id="habit-{{ habit.id }}">
<div class="col-auto drag-handle" style="cursor: grab;"> <div class="col-auto drag-handle" style="cursor: grab;">
<i class="bi bi-grip-vertical"></i> <i class="bi bi-grip-vertical"></i>
</div> </div>
<div class="col-auto"> <div class="col-auto">
<input {% if habit.checked %} checked {% endif %} type="checkbox" class="task-checkbox" id="{{habit.id}}" onclick="sendPostRequest('{{habit.id}}')"> <input {% if habit.checked %} checked {% endif %} type="checkbox" class="task-checkbox"
id="{{ habit.id }}"
onclick="sendPostRequest('{{ habit.id }}')">
</div> </div>
<div class="col" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis"> <div class="col" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
@ -113,18 +121,25 @@
</div> </div>
<button type="button" class="btn btn-xs btn-danger rounded-circle" data-bs-toggle="modal" data-bs-target="#exampleModal" style="width: 40px; height: 40px" onclick="setSelectedHabitId({{habit.id}})"> <button type="button" class="btn btn-xs btn-danger rounded-circle" data-bs-toggle="modal"
data-bs-target="#exampleModal" style="width: 40px; height: 40px"
onclick="setSelectedHabitId({{ habit.id }})">
<i class="bi bi-trash3"></i> <i class="bi bi-trash3"></i>
</button> </button>
<div class="col-12"> <div class="col-12">
<div class="progress" style="height: 2px; width: 90%"> <div class="progress" style="height: 2px; width: 90%">
<div class="progress-bar" id="progress-bar-{{habit.id}}" role="progressbar" style="width: {{ habit.percentage }}%; background-color: {% if habit.percentage >= 100 %} green {% else %} primary {% endif %}" aria-valuenow="{{ habit.percentage }}" aria-valuemin="0" aria-valuemax="100"></div> <div class="progress-bar" id="progress-bar-{{ habit.id }}" role="progressbar"
style="width: {{ habit.percentage }}%; background-color: {% if habit.percentage >= 100 %} green {% else %} primary {% endif %}"
aria-valuenow="{{ habit.percentage }}" aria-valuemin="0"
aria-valuemax="100"></div>
</div> </div>
</div> </div>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
{% endfor %}
</div> </div>
<script> <script>
@ -147,7 +162,9 @@
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary btn-danger" data-bs-dismiss="modal" onclick="deleteHabit(selectedHabitId)">Löschen</button> <button type="button" class="btn btn-primary btn-danger" data-bs-dismiss="modal"
onclick="deleteHabit(selectedHabitId)">Löschen
</button>
</div> </div>
</div> </div>
</div> </div>
@ -180,7 +197,7 @@
var habitId = checkboxId; var habitId = checkboxId;
// Make a POST request to /check with the habit id // Make a POST request to /check with the habit id
axios.post('/check', { habitId: habitId }, { axios.post('/check', {habitId: habitId}, {
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
} }
@ -202,7 +219,7 @@
function deleteHabit(habitId) { function deleteHabit(habitId) {
// Make a POST request to /delete with the habit id // Make a POST request to /delete with the habit id
axios.post('/delete', { habitId: habitId }, { axios.post('/delete', {habitId: habitId}, {
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
} }
@ -219,22 +236,22 @@
}); });
} }
</script> </script>
</div> </div>
<script> <script>
document.addEventListener('DOMContentLoaded', (event) => { document.addEventListener('DOMContentLoaded', (event) => {
var el = document.querySelector('.task-list'); var el = document.querySelector('.task-list');
Sortable.create(el, { Sortable.create(el, {
handle: '.drag-handle', handle: '.drag-handle',
animation: 150, animation: 150,
onEnd: function(evt) { onEnd: function (evt) {
console.log(evt.oldIndex, evt.newIndex); console.log(evt.oldIndex, evt.newIndex);
var habitId = el.children[evt.newIndex].id.split('-')[1]; var habitId = el.children[evt.newIndex].id.split('-')[1];
var oldIndex = evt.oldIndex; var oldIndex = evt.oldIndex;
var newIndex = evt.newIndex; var newIndex = evt.newIndex;
axios.post('/reorder', { habitId: habitId, oldIndex: oldIndex, newIndex: newIndex }, { axios.post('/reorder', {habitId: habitId, oldIndex: oldIndex, newIndex: newIndex}, {
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
} }
@ -248,5 +265,5 @@
} }
}); });
}); });
</script> </script>
{% endblock %} {% endblock %}

View File

@ -1,167 +0,0 @@
{% extends 'layouts/main.html' %}
{% block content %}
<h1>{{ title }}</h1>
<h3>{{ utc_dt }}</h3>
<style>
table {
border-collapse: collapse;
width: 100%;
}
th, td {
border: 1px solid #dddddd;
text-align: center;
padding: 8px;
}
th {
background-color: #f2f2f2;
}
.current-week {
/* Change the color for the current week */
background-color: rgba(255, 204, 0, 1); /* Full opacity */
}
.past-week {
/* Change the color for past weeks */
background-color: rgba(224, 224, 224, 1); /* Full opacity */
}
.future-week {
/* Change the color for future weeks */
background-color: rgba(192, 224, 192, 1); /* Full opacity */
}
.current-day {
/* Highlight the current day */
border: 2px solid #ff0000;
border-radius: 5px;
}
</style>
<table id="heatmap">
<thead>
<tr>
<th></th> <!-- Empty cell for spacing -->
<th class="past-week">-2</th>
<th class="past-week">-1</th>
<th class="current-week">0</th>
<th class="future-week">+1</th>
<th class="future-week">+2</th>
</tr>
</thead>
<tbody>
<tr>
<td >Montag</td>
<td class="past-week" data-tasks="5">15</td>
<td class="past-week" data-tasks="8">20</td>
<td class="current-week" data-tasks="12">25</td>
<td class="future-week" data-tasks="7">30</td>
<td class="future-week" data-tasks="10">35</td>
</tr>
<tr>
<td class="current-day">Dienstag</td>
<td class="past-week" data-tasks="5">15</td>
<td class="past-week" data-tasks="8">20</td>
<td class="current-week" data-tasks="12">25</td>
<td class="future-week" data-tasks="7">30</td>
<td class="future-week" data-tasks="10">35</td>
</tr>
<tr>
<td >Mittwoch</td>
<td class="past-week" data-tasks="5">15</td>
<td class="past-week" data-tasks="8">20</td>
<td class="current-week" data-tasks="12">25</td>
<td class="future-week" data-tasks="7">30</td>
<td class="future-week" data-tasks="10">35</td>
</tr>
<tr>
<td >Donnerstag</td>
<td class="past-week" data-tasks="5">15</td>
<td class="past-week" data-tasks="8">20</td>
<td class="current-week" data-tasks="12">25</td>
<td class="future-week" data-tasks="7">30</td>
<td class="future-week" data-tasks="10">35</td>
</tr>
<tr>
<td >Freitag</td>
<td class="past-week" data-tasks="5">15</td>
<td class="past-week" data-tasks="8">20</td>
<td class="current-week" data-tasks="12">25</td>
<td class="future-week" data-tasks="7">30</td>
<td class="future-week" data-tasks="10">35</td>
</tr>
<tr>
<td >Samstag</td>
<td class="past-week" data-tasks="5">15</td>
<td class="past-week" data-tasks="8">20</td>
<td class="current-week" data-tasks="12">25</td>
<td class="future-week" data-tasks="7">30</td>
<td class="future-week" data-tasks="10">35</td>
</tr> <tr>
<td >Sonntag</td>
<td class="past-week" data-tasks="5">15</td>
<td class="past-week" data-tasks="8">20</td>
<td class="current-week" data-tasks="12">25</td>
<td class="future-week" data-tasks="7">30</td>
<td class="future-week" data-tasks="10">35</td>
</tr>
</tbody>
</table>
<script>
// Adjust background color based on the number of tasks
document.addEventListener('DOMContentLoaded', function () {
var cells = document.querySelectorAll('#heatmap tbody td');
cells.forEach(function (cell) {
var tasks = parseInt(cell.getAttribute('data-tasks')) || 0;
var opacity = tasks / 20; // Adjust the denominator based on your preference
// Get the RGB values from the background color
var rgb = cell.style.backgroundColor.match(/\d+/g);
// Calculate the green value based on the number of tasks
var greenValue = Math.round(opacity * 255);
// Set the new background color with adjusted green value
cell.style.backgroundColor = 'rgba(0,' + greenValue + ',0,' + opacity + ')';
});
});
</script>
<div class="row">
<h2 class="col-10">Task List</h2>
<a class="col-2 btn btn-primary" role="button" href="/habit">
Task erstellen
</a>
</div>
<ul class="task-list row">
{% for habit in habits %}
<li class="row col-md-4">
<div class="col-auto">
<input type="checkbox" class="task-checkbox">
</div>
<div class="col" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
{{ habit.name }} hhhbhghbhjndjksbeujsdkfheuwaihgkjfgfjnsidkgjnkdghujds
</div>
</li>
<div class="col-md-8" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
{{ habit.note }}
</div>
{% endfor %}
</ul>
{% endblock %}

View File

@ -1,65 +0,0 @@
{% extends 'layouts/main.html' %}
{% block content %}
<h1>{{ title }}</h1>
<h3>{{ utc_dt }}</h3>
<div class="heatmap" id="heatmap"></div>
<script>
// Simulierte Aktivitätsdaten (ersetze dies durch deine echten Daten)
const activityData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 5, 4, 3, 2, 1, 9, 5, 36, 75, 8, 9, 1, 0, 23, 0, 0, 0, 64, 0, 0, 64, 0, 0, 19, 84];
// Funktion zum Erstellen der Heatmap
function createHeatmap(data) {
const heatmapContainer = document.getElementById('heatmap');
for (let i = 0; i < data.length; i++) {
const opacity = data[i] / Math.max(...data); // Berechne die Opazität basierend auf Aktivitätsanzahl
const dayElement = document.createElement('div');
dayElement.classList.add('day');
dayElement.style.backgroundColor = `rgba(0, 255, 0, ${opacity})`;
heatmapContainer.appendChild(dayElement);
}
}
// Erstelle die Heatmap mit den simulierten Daten
createHeatmap(activityData);
</script>
<div class="row">
<h2 class="col-10">Task List</h2>
<a class="col-2 btn btn-primary" role="button" href="/habit">
Task erstellen
</a>
</div>
<ul class="task-list row">
{% for habit in habits %}
<li class="row col-md-4">
<div class="col-auto">
<input type="checkbox" class="task-checkbox">
</div>
<div class="col" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
{{ habit.name }} hhhbhghbhjndjksbeujsdkfheuwaihgkjfgfjnsidkgjnkdghujds
</div>
</li>
<div class="col-md-8" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis">
{{ habit.note }}
</div>
{% endfor %}
</ul>
{% endblock %}