Finished habit_list invitation

This commit is contained in:
Verox001 2024-03-07 20:34:30 +01:00
parent ce68bc9786
commit d465287316
4 changed files with 140 additions and 24 deletions

27
app.py
View File

@ -63,6 +63,19 @@ def load_user(user_id):
def inject_user():
return dict(user=current_user)
@app.context_processor
def inject_notifications():
if current_user.is_authenticated:
habit_lists = current_user.get_unaccepted_habitLists()
lists = []
for habit_list in habit_lists:
# Check if the user is the first user in the list
if habit_list.get_users()[0].id != current_user.id:
lists.append(habit_list)
return dict(notifications=lists)
return dict(notifications=[])
@app.route('/login')
@anonymous_required
@ -847,39 +860,39 @@ def user_leave():
@app.route('/accept-list', methods=['POST'])
@login_required
def accept_list():
list_id = request.form.get('list_id')
list_id = request.json.get('list_id')
habit_list = HabitList.get(int(list_id))
users = habit_list.get_users()
# Check if user is part of the list
found = False
for user in users:
if user.id == habit_list.id:
if user.id == current_user.id:
found = True
break
if not found:
return redirect(url_for("index"))
return {}
current_user.accept_List(list_id)
current_user.accept_List(habit_list.id)
return {}
@app.route('/deny-list', methods=['POST'])
@login_required
def deny_list():
list_id = request.form.get('list_id')
list_id = request.json.get('list_id')
habit_list = HabitList.get(int(list_id))
users = habit_list.get_users()
# Check if user is part of the list
found = False
for user in users:
if user.id == habit_list.id:
if user.id == current_user.id:
found = True
break
if not found:
return redirect(url_for("index"))
return {}
habit_list.remove_user(current_user.id)
return {}

View File

@ -272,8 +272,8 @@ def create_habitList(user_id: int, name: str, description: str):
conn = con3()
cursor = conn.cursor()
cursor.execute(query)
query2 = (f"INSERT INTO habit_users (user_id, list_id, created_at, updated_at)"
f" VALUES ('{user_id}', '{cursor.lastrowid}', '{now}', '{now}');")
query2 = (f"INSERT INTO habit_users (user_id, list_id, created_at, updated_at, accepted)"
f" VALUES ('{user_id}', '{cursor.lastrowid}', '{now}', '{now}', 1);")
cursor.execute(query2)
conn.commit()
conn.close()
@ -291,7 +291,7 @@ def get_habitList(id: int):
def get_habitLists(user_id: int):
query = (f"SELECT habit_lists.* FROM habit_lists JOIN habit_users ON habit_lists.id = habit_users.list_id "
query = (f"SELECT habit_lists.*, habit_users.user_id, habit_users.accepted FROM habit_lists JOIN habit_users ON habit_lists.id = habit_users.list_id "
f"WHERE habit_users.user_id = {user_id};")
conn = con3()
cursor = conn.cursor()
@ -301,6 +301,17 @@ def get_habitLists(user_id: int):
return habit_lists
def get_unaccepted_habitLists(user_id: int):
query = (f"SELECT habit_lists.* FROM habit_lists JOIN habit_users ON habit_lists.id = habit_users.list_id "
f"WHERE habit_users.user_id = {user_id} AND habit_users.accepted = false;")
conn = con3()
cursor = conn.cursor()
cursor.execute(query)
habit_lists = cursor.fetchall()
conn.close()
return habit_lists
def get_users(list_id: int):
query = (f"SELECT users.* FROM users JOIN habit_users ON users.id = habit_users.user_id WHERE "
f"habit_users.list_id = {list_id};")
@ -323,7 +334,7 @@ def add_user(list_id: int, user_id: int):
conn.close()
def accept_List(list_id: int, user_id: int):
query = (f"UPDATE habit_users SET accepted = true WHERE {user_id} = habit_users.user_id AND {list_id} = habit_users.list_id;")
query = (f"UPDATE habit_users SET accepted = 1 WHERE habit_users.user_id = {user_id} AND habit_users.list_id = {list_id};")
conn = con3()
cursor = conn.cursor()
cursor.execute(query)

View File

@ -2,7 +2,7 @@ from datetime import datetime
from flask_login import UserMixin
from db.SQLiteClient import (create_user, get_user, get_user_by_email, update_user, delete_user,
get_habitLists, get_heatmap_value, accept_List)
get_habitLists, get_heatmap_value, accept_List, get_unaccepted_habitLists)
class User(UserMixin):
@ -53,6 +53,21 @@ class User(UserMixin):
raw_habitLists = get_habitLists(self.id)
habitLists = []
for habitList in raw_habitLists:
user_id = habitList[5]
accepted = habitList[6]
habitList = HabitList(habitList[0], habitList[1], habitList[2])
if accepted == 1 or habitList.get_users()[0].id == user_id:
habitLists.append(habitList)
return habitLists
def get_unaccepted_habitLists(self) -> list:
from models.HabitList import HabitList
raw_habitLists = get_unaccepted_habitLists(self.id)
habitLists = []
for habitList in raw_habitLists:
habitList = HabitList(habitList[0], habitList[1], habitList[2])
habitLists.append(habitList)
@ -78,4 +93,4 @@ class User(UserMixin):
return heatmap, day
def accept_List(self, HabitList_id):
accept_List(self.id, HabitList_id)
accept_List(HabitList_id, self.id)

View File

@ -2,15 +2,16 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" >
<meta content="width=device-width, initial-scale=1" name="viewport">
<title>{{ title }} - HabitTracker</title>
<link rel="icon" href="/static/favicon.ico">
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="../../static/css/background.css">
<link rel="stylesheet" type="text/css" href="../../static/css/profile.css">
<link href="https://cdn.jsdelivr.net/npm/fastbootstrap@2.2.0/dist/css/fastbootstrap.min.css" rel="stylesheet" integrity="sha256-V6lu+OdYNKTKTsVFBuQsyIlDiRWiOmtC8VQ8Lzdm2i4=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link href="../../static/css/background.css" rel="stylesheet" type="text/css">
<link href="../../static/css/profile.css" rel="stylesheet" type="text/css">
<link crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/fastbootstrap@2.2.0/dist/css/fastbootstrap.min.css"
integrity="sha256-V6lu+OdYNKTKTsVFBuQsyIlDiRWiOmtC8VQ8Lzdm2i4=" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" rel="stylesheet">
<!-- jQuery -->
@ -18,7 +19,9 @@
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Bootstrap JS (including Popper.js for Bootstrap 5) -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
<script crossorigin="anonymous"
integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL"
src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.2/Sortable.min.js"></script>
<!-- Axios Library-->
@ -31,7 +34,8 @@
<nav class="navbar navbar-expand-lg" style="background-color: #000000">
<div class="container-fluid">
<a class="navbar-brand" href="{{ url_for('index') }}" style="color: ivory">HabitTracker</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<button aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler"
data-bs-target="#navbarSupportedContent" data-bs-toggle="collapse" type="button">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
@ -39,17 +43,90 @@
<ul class="navbar-nav mb-2 mb-lg-0">
{% if not current_user.is_authenticated %}
<li class="nav-item me-2">
<a class="btn text-white btn-primary" aria-current="page" href="{{ url_for('login') }}">Login</a>
<a aria-current="page" class="btn text-white btn-primary" href="{{ url_for('login') }}">Login</a>
</li>
<li class="nav-item">
<a class="btn btn-outline-secondary" aria-current="page" href="{{ url_for('signup') }}">Signup</a>
<a aria-current="page" class="btn btn-outline-secondary" href="{{ url_for('signup') }}">Signup</a>
</li>
{% else %}
{% if notifications %}
<li class="nav-item me-4 mb-2 mb-lg-0">
<div class="dropdown">
<!--<button class="btn btn-default dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
Page actions
</button>-->
<i class="bi bi-bell-fill dropdown-toggle" data-bs-toggle="dropdown"
style="color: white; cursor: pointer"></i>
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill text-bg-danger">
{{ notifications|length }}
<span class="visually-hidden">unread messages</span>
</span>
<ul class="dropdown-menu" role="menu">
{% for notification in notifications %}
<li>
<div class="dropdown-item">
<div class="row">
<div class="col">
{{ notification.name }}
</div>
<div class="col">
<a class="accept-button" data-id="{{ notification.id }}" style="cursor: pointer"><i class="bi bi-check-circle-fill" style="color: green"></i></a>
</div>
<div class="col">
<a class="deny-button" data-id="{{ notification.id }}" style="cursor: pointer"><i class="bi bi-x-circle-fill" style="color: red"></i></a>
</div>
</div>
</div>
</li>
{% endfor %}
</ul>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var acceptButtons = document.querySelectorAll('.accept-button');
acceptButtons.forEach(function(button) {
button.addEventListener('click', function() {
var notificationId = this.getAttribute('data-id');
console.log('Notification accepted:', notificationId);
axios.post('/accept-list', {list_id: notificationId}, {
headers: {
'Content-Type': 'application/json'
}
}).then(() => {
location.reload();
});
});
});
});
document.addEventListener('DOMContentLoaded', function() {
var acceptButtons = document.querySelectorAll('.deny-button');
acceptButtons.forEach(function(button) {
button.addEventListener('click', function() {
var notificationId = this.getAttribute('data-id');
console.log('Notification accepted:', notificationId);
axios.post('/deny-list', {list_id: notificationId}, {
headers: {
'Content-Type': 'application/json'
}
}).then(() => {
location.reload();
});
});
});
});
</script>
</li>
{% endif %}
<li class="nav-item me-2 mb-2 mb-lg-0">
<a class="btn text-white btn-primary" aria-current="page" href="{{ url_for('profile') }}">Profil</a>
<a aria-current="page" class="btn text-white btn-primary" href="{{ url_for('profile') }}">Profil</a>
</li>
<li class="nav-item me-2">
<a class="btn btn-primary" aria-current="page" href="{{ url_for('logout') }}">Logout</a>
<a aria-current="page" class="btn btn-primary" href="{{ url_for('logout') }}">Logout</a>
</li>
{% endif %}
</ul>