Finished habit_list invitation
This commit is contained in:
parent
ce68bc9786
commit
d465287316
27
app.py
27
app.py
@ -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 {}
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user