Add Impressum and QR code management templates

- Created a new Impressum page with legal information and contact details.
- Developed admin link page for linking QR codes to events with form functionality.
- Implemented QR code dashboard for managing QR code sets, including creation and quick actions.
- Added detailed view for QR code sets, allowing addition of QR codes and management actions.
- Introduced static file serving for favicon and related images.
- Established views for static content pages (about, contact, privacy, terms).
- Implemented translation management scripts for compiling and updating translations.
This commit is contained in:
Christian Krakau-Louis
2025-04-14 03:19:41 +02:00
parent 9eef726d9b
commit d595b468e9
43 changed files with 2895 additions and 391 deletions
+59 -35
View File
@@ -1,14 +1,18 @@
#!/usr/bin/env python3
from fastapi import FastAPI, Request, status
from fastapi import FastAPI, Request, Depends, Form
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse, RedirectResponse
from datetime import datetime
from fastapi.templating import Jinja2Templates
from pathlib import Path
import os
from starlette.middleware.sessions import SessionMiddleware
from .db import init_db, engine
from . import models
from .templates_config import templates
from .views import qr, redeem, teams, admin, leaderboard, dashboard
from .views import qr, redeem, teams, admin, leaderboard, dashboard, static, pages
from .db_init import seed_db
from app.i18n import get_translator, SUPPORTED_LANGUAGES, _ # Ensure `_` is correctly imported
# Create tables on startup
init_db()
@@ -17,7 +21,22 @@ init_db()
# In a production app, you would handle this differently
seed_db()
app = FastAPI()
# Create the FastAPI application
app = FastAPI(title="LeagueLedger")
# Add SessionMiddleware with a secure secret key
app.add_middleware(SessionMiddleware, secret_key="your-very-secret-session-key")
# Mount static files
app.mount("/static", StaticFiles(directory="app/static"), name="static")
# Configure static files
static.configure_static_files(app)
# Setup Jinja2 templates
templates = Jinja2Templates(directory="app/templates")
templates.env.globals["SUPPORTED_LANGUAGES"] = SUPPORTED_LANGUAGES
templates.env.globals["_"] = _
# User context middleware to make template globals available
@app.middleware("http")
@@ -33,41 +52,46 @@ async def add_template_globals(request: Request, call_next):
response = await call_next(request)
return response
# Routers - auth router removed
# Add translation context processor to Jinja templates
@app.middleware("http")
async def add_translation_context(request: Request, call_next):
response = await call_next(request)
return response
@app.get("/", response_class=HTMLResponse)
async def read_root(request: Request, i18n: dict = Depends(get_translator)):
return templates.TemplateResponse(
"index.html",
{"request": request, "user": None, **i18n}
)
@app.api_route("/set-language/{language_code}", methods=["GET", "POST"])
async def set_language(request: Request, language_code: str):
if request.method == "POST":
form = await request.form()
language = form.get("language", "en")
else:
language = language_code
if language in SUPPORTED_LANGUAGES:
request.session["language"] = language
response = RedirectResponse(url=request.headers.get("referer", "/"))
response.set_cookie(key="language", value=language, max_age=31536000) # 1 year
return response
return {"message": f"Invalid language code: {language}"}
# Routers
app.include_router(pages.router, tags=["Pages"]) # Pages router for index and static pages
app.include_router(qr.router, prefix="/qr", tags=["QR"])
app.include_router(redeem.router, prefix="/redeem", tags=["Redeem"])
app.include_router(teams.router, prefix="/teams", tags=["Teams"])
app.include_router(admin.router, prefix="/admin", tags=["Admin"])
app.include_router(leaderboard.router, prefix="/leaderboard", tags=["Leaderboard"])
app.include_router(dashboard.router, prefix="/dashboard", tags=["Dashboard"])
app.include_router(static.router, tags=["Static"]) # Include the static router
@app.get("/", response_class=HTMLResponse)
def index(request: Request):
return templates.TemplateResponse("index.html", {
"request": request,
"now": datetime.now
})
@app.get("/about", response_class=HTMLResponse)
def about(request: Request):
return templates.TemplateResponse("about.html", {
"request": request
})
@app.get("/contact", response_class=HTMLResponse)
def contact(request: Request):
return templates.TemplateResponse("contact.html", {
"request": request
})
@app.get("/privacy", response_class=HTMLResponse)
def privacy(request: Request):
return templates.TemplateResponse("privacy.html", {
"request": request
})
@app.get("/terms", response_class=HTMLResponse)
def terms(request: Request):
return templates.TemplateResponse("terms.html", {
"request": request
})
# Add a direct route for /scan that redirects to /redeem/scan
@app.get("/scan")
async def scan_redirect():
return RedirectResponse("/redeem/scan", status_code=303)