Update Terms of Use Modal and fix message flashing.

This commit is contained in:
Patrick Jentsch 2025-06-03 13:51:28 +02:00
parent c28d534942
commit 56844e0898
8 changed files with 53 additions and 28 deletions

View File

@ -19,6 +19,7 @@ def before_request():
and request.endpoint
and request.blueprint != 'auth'
and request.endpoint != 'static'
and request.endpoint != 'main.accept_terms_of_use'
):
return redirect(url_for('auth.unconfirmed'))

View File

@ -1,8 +1,9 @@
from flask import flash, redirect, render_template, url_for
from flask import abort, flash, jsonify, redirect, render_template, url_for
from flask_login import current_user, login_required, login_user
from app.blueprints.auth.forms import LoginForm
from app.models import Corpus, User
from . import bp
from app import db
@bp.route('/', methods=['GET', 'POST'])
@ -72,6 +73,16 @@ def terms_of_use():
)
@bp.route('/accept-terms-of-use', methods=['POST'])
@login_required
def accept_terms_of_use():
current_user.terms_of_use_accepted = True
db.session.commit()
return jsonify('You accepted the terms of use'), 202
@bp.route('/social')
@login_required
def social():

View File

@ -132,19 +132,3 @@ def delete_user_avatar(user_id: int):
thread.start()
return jsonify('Avatar marked for deletion'), 202
# TODO: Move this to main blueprint(?)
@bp.route('/accept-terms-of-use', methods=['POST'])
@login_required
def accept_terms_of_use():
if not (
current_user.is_authenticated
or current_user.confirmed
):
abort(403)
current_user.terms_of_use_accepted = True
db.session.commit()
return jsonify('You accepted the terms of use'), 202

View File

@ -5,6 +5,7 @@ nopaque.app.Client = class Client {
// Endpoints
this.corpora = new nopaque.app.endpoints.Corpora(this);
this.jobs = new nopaque.app.endpoints.Jobs(this);
this.main = new nopaque.app.endpoints.Main(this);
this.settings = new nopaque.app.endpoints.Settings(this);
this.users = new nopaque.app.endpoints.Users(this);

View File

@ -0,0 +1,22 @@
nopaque.app.endpoints.Main = class Main {
constructor(app) {
this.app = app;
}
async acceptTermsOfUse() {
const options = {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
method: 'POST',
};
const response = await fetch(`/accept-terms-of-use`, options);
const data = await response.json();
if (!response.ok) {throw new Error(`${data.name}: ${data.description}`);}
return data;
}
}

View File

@ -71,10 +71,7 @@ nopaque.app.extensions.UI = class UI {
M.Modal.init(
document.querySelector('#terms-of-use-modal'),
{
dismissible: false,
onCloseEnd: (modalElement) => {
nopaque.requests.users.entity.acceptTermsOfUse();
}
dismissible: false
}
);
// #endregion

View File

@ -19,12 +19,10 @@
</div>
<div class="modal-footer">
{% if current_user.is_authenticated %}
{% if current_user.terms_of_use_accepted %}
<a href="#!" class="btn-flat waves-effect waves-light modal-close">Close</a>
{% if current_user.is_authenticated and not current_user.terms_of_use_accepted %}
<a href="#!" class="btn waves-effect waves-light modal-close" id="terms-of-use-modal-accept-button">Accept</a>
{% else %}
<a href="#!" class="btn waves-effect waves-light modal-close">Accept</a>
{% endif %}
<a href="#!" class="btn-flat waves-effect waves-light modal-close">Close</a>
{% endif %}
</div>
</div>

View File

@ -13,6 +13,7 @@
'js/app/endpoints/index.js',
'js/app/endpoints/corpora.js',
'js/app/endpoints/jobs.js',
'js/app/endpoints/main.js',
'js/app/endpoints/settings.js',
'js/app/endpoints/users.js',
'js/app/extensions/index.js',
@ -102,6 +103,16 @@
}
{% if not current_user.terms_of_use_accepted %}
const termsOfUseAcceptButtonElement = document.querySelector('#terms-of-use-modal-accept-button');
termsOfUseAcceptButtonElement.addEventListener('click', async () => {
try {
await app.main.acceptTermsOfUse();
app.ui.flash('Terms of use accepted.');
} catch (error) {
app.ui.flash('Failed to accept terms of use.', 'error');
}
});
const termsOfUseModalElement = document.querySelector('#terms-of-use-modal');
const termsOfUseModal = M.Modal.getInstance(termsOfUseModalElement);
@ -109,10 +120,10 @@
{% endif %}
{% endif %}
const flashedMessages = {{ get_flashed_messages()|tojson }};
const flashedMessages = {{ get_flashed_messages(with_categories=true)|tojson }};
for (let [category, message] of flashedMessages) {
app.ui.flash(message, message);
app.ui.flash(message, category);
}
}