Remove unused templates for newsletter creation, settings, and submissions; update unsubscribe confirmation link; add tests for email templates API.
All checks were successful
CI / test (3.11) (pull_request) Successful in 1m59s
CI / build-image (pull_request) Successful in 2m43s

This commit is contained in:
2025-11-06 11:10:10 +01:00
parent 3a11b00fd5
commit c1e3ce185f
26 changed files with 1921 additions and 1732 deletions

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
from flask import Flask
from . import admin, auth, contact, embed, monitoring, newsletter
from . import admin, auth, contact, embed, monitoring, newsletter, static
def register_blueprints(app: Flask) -> None:
@@ -14,3 +14,4 @@ def register_blueprints(app: Flask) -> None:
app.register_blueprint(auth.bp)
app.register_blueprint(admin.bp)
app.register_blueprint(embed.bp)
app.register_blueprint(static.bp)

View File

@@ -14,21 +14,21 @@ bp = Blueprint("admin", __name__, url_prefix="/admin")
@auth.login_required
def dashboard():
"""Display admin dashboard overview."""
return render_template("admin_dashboard.html")
return render_template("admin/admin_dashboard.html")
@bp.route("/newsletter")
@auth.login_required
def newsletter_subscribers():
"""Display newsletter subscriber management page."""
return render_template("admin_newsletter.html")
return render_template("admin/admin_newsletter.html")
@bp.route("/newsletter/create")
@auth.login_required
def newsletter_create():
"""Display newsletter creation and sending page."""
return render_template("admin_newsletter_create.html")
return render_template("admin/admin_newsletter_create.html")
@bp.route("/settings")
@@ -72,21 +72,28 @@ def settings_page():
},
}
return render_template("admin_settings.html", settings=app_settings)
return render_template("admin/admin_settings.html", settings=app_settings)
@bp.route("/submissions")
@auth.login_required
def submissions():
"""Display contact form submissions page."""
return render_template("admin_submissions.html")
return render_template("admin/admin_submissions.html")
@bp.route("/embeds")
@auth.login_required
def embeds():
"""Display embeddable forms management page."""
return render_template("admin_embeds.html")
return render_template("admin/admin_embeds.html")
@bp.route('/email-templates')
@auth.login_required
def email_templates():
"""Display admin page for editing email templates."""
return render_template('admin/admin_email_templates.html')
@bp.route("/api/settings", methods=["GET"])
@@ -110,6 +117,11 @@ def validate_setting(key: str, value: str) -> str | None:
"newsletter_enabled": lambda v: v in ["true", "false"],
"rate_limit_max": lambda v: v.isdigit() and 0 <= int(v) <= 1000,
"rate_limit_window": lambda v: v.isdigit() and 1 <= int(v) <= 3600,
# Embed dimensions (pixels)
"embed_contact_width": lambda v: v.isdigit() and 100 <= int(v) <= 2000,
"embed_contact_height": lambda v: v.isdigit() and 100 <= int(v) <= 2000,
"embed_newsletter_width": lambda v: v.isdigit() and 100 <= int(v) <= 2000,
"embed_newsletter_height": lambda v: v.isdigit() and 100 <= int(v) <= 2000,
}
if key in validations and not validations[key](value):

View File

@@ -1,8 +1,7 @@
"""Embeddable forms routes."""
from __future__ import annotations
from flask import Blueprint, render_template, send_from_directory
import os
from flask import Blueprint, render_template
bp = Blueprint("embed", __name__)
@@ -17,10 +16,3 @@ def contact_form():
def newsletter_form():
"""Serve the embeddable newsletter subscription form."""
return render_template("embed_newsletter.html")
@bp.route("/static/css/styles.css", methods=["GET"])
def serve_css():
"""Serve the unified CSS file."""
static_dir = os.path.join(os.path.dirname(__file__), '..', '..', 'static')
return send_from_directory(static_dir, 'css/styles.css')

27
server/routes/static.py Normal file
View File

@@ -0,0 +1,27 @@
from __future__ import annotations
from flask import Blueprint, render_template, send_from_directory
import os
bp = Blueprint("static", __name__)
@bp.route("/static/css/styles.css", methods=["GET"])
def serve_css():
"""Serve the unified CSS file."""
static_dir = os.path.join(os.path.dirname(__file__), '..', '..', 'static')
return send_from_directory(static_dir, 'css/styles.css')
@bp.route("/static/css/admin.css", methods=["GET"])
def serve_admin_css():
"""Serve the unified CSS file."""
static_dir = os.path.join(os.path.dirname(__file__), '..', '..', 'static')
return send_from_directory(static_dir, 'css/admin.css')
@bp.route("/static/js/admin.js", methods=["GET"])
def serve_admin_js():
"""Serve the unified JS file."""
static_dir = os.path.join(os.path.dirname(__file__), '..', '..', 'static')
return send_from_directory(static_dir, 'js/admin.js')