Update redirect paths and enhance user context in templates and views

This commit is contained in:
Christian Krakau-Louis
2025-04-14 05:54:21 +02:00
parent 690065f788
commit e952630295
8 changed files with 189 additions and 37 deletions
+47 -4
View File
@@ -67,12 +67,22 @@ def get_relationships(model_class: Type[Base]) -> Dict[str, str]:
return relationships
@router.get("/", response_class=HTMLResponse)
async def admin_home(request: Request):
async def admin_home(request: Request, db: Session = Depends(get_db)):
"""Admin dashboard home."""
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(User).get(user_id)
# Check admin status
if not user or not user.is_admin:
raise HTTPException(status_code=403, detail="Forbidden: Admin access required")
model_list = [(key, name) for key, (_, name) in MODELS.items()]
return templates.TemplateResponse(
"admin/index.html",
{"request": request, "models": model_list}
{"request": request, "models": model_list, "user": user}
)
@router.get("/{model_name}", response_class=HTMLResponse)
@@ -84,6 +94,16 @@ async def list_records(
db: Session = Depends(get_db)
):
"""List records for a model with pagination."""
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(User).get(user_id)
# Check admin status
if not user or not user.is_admin:
raise HTTPException(status_code=403, detail="Forbidden: Admin access required")
if model_name not in MODELS:
raise HTTPException(status_code=404, detail=f"Model {model_name} not found")
@@ -123,6 +143,7 @@ async def list_records(
"per_page": per_page,
"total_pages": total_pages,
"total_records": total_records,
"user": user # Add user to the context
}
)
@@ -133,6 +154,16 @@ async def create_record_form(
db: Session = Depends(get_db)
):
"""Show form for creating a new record."""
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(User).get(user_id)
# Check admin status
if not user or not user.is_admin:
raise HTTPException(status_code=403, detail="Forbidden: Admin access required")
if model_name not in MODELS:
raise HTTPException(status_code=404, detail=f"Model {model_name} not found")
@@ -162,7 +193,8 @@ async def create_record_form(
"columns_info": columns_info,
"record": None, # No record for new form
"foreign_key_options": foreign_key_options,
"is_new": True
"is_new": True,
"user": user # Add user to the context
}
)
@@ -222,6 +254,16 @@ async def edit_record_form(
db: Session = Depends(get_db)
):
"""Show form for editing an existing record."""
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(User).get(user_id)
# Check admin status
if not user or not user.is_admin:
raise HTTPException(status_code=403, detail="Forbidden: Admin access required")
if model_name not in MODELS:
raise HTTPException(status_code=404, detail=f"Model {model_name} not found")
@@ -261,7 +303,8 @@ async def edit_record_form(
"columns_info": columns_info,
"record": record_data,
"foreign_key_options": foreign_key_options,
"is_new": False
"is_new": False,
"user": user # Add user to the context
}
)
+52 -3
View File
@@ -92,6 +92,45 @@ def user_dashboard(request: Request, db: Session = Depends(get_db)):
.limit(5)\
.all()
# Get user teams with enhanced data for display
user_teams_enhanced = []
if user_teams:
# Get all team points to calculate ranks
team_points_query = db.query(
models.Team.id,
func.sum(models.QRCode.points).label('total_points')
).outerjoin(
models.QRCode,
models.QRCode.redeemed_at_team == models.Team.id
).group_by(models.Team.id)
# Get results and sort by points in descending order
team_points = {row.id: row.total_points or 0 for row in team_points_query.all()}
ranked_teams = sorted(team_points.items(), key=lambda x: x[1], reverse=True)
# Create a dictionary mapping team ID to rank
team_ranks = {team_id: i+1 for i, (team_id, _) in enumerate(ranked_teams)}
# Enhance user teams with rank and points data
for team in user_teams:
points = team_points.get(team.id, 0)
rank = team_ranks.get(team.id, len(team_ranks) + 1)
user_teams_enhanced.append({
'id': team.id,
'name': team.name,
'points': points,
'rank': rank,
'description': getattr(team, 'description', None)
})
# Find best rank if the user has any teams
best_rank = None
if user_teams_enhanced:
ranks = [team['rank'] for team in user_teams_enhanced]
best_rank = min(ranks) if ranks else None
return templates.TemplateResponse(
"dashboard/index.html",
{
@@ -101,7 +140,8 @@ def user_dashboard(request: Request, db: Session = Depends(get_db)):
"total_points": total_points,
"event_count": event_count,
"recent_events": recent_events,
"user_teams": user_teams
"user_teams": user_teams_enhanced,
"best_rank": best_rank
}
)
except Exception as e:
@@ -109,6 +149,15 @@ def user_dashboard(request: Request, db: Session = Depends(get_db)):
raise HTTPException(status_code=500, detail=f"Dashboard error: {str(e)}")
@router.get("/scan", response_class=HTMLResponse)
def scan_qr_page(request: Request):
def scan_qr_page(request: Request, db: Session = Depends(get_db)):
"""Render the QR code scanning page."""
return templates.TemplateResponse("scan_qr.html", {"request": request})
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(models.User).get(user_id)
return templates.TemplateResponse("scan_qr.html", {
"request": request,
"user": user # Add user to the context
})
+25 -4
View File
@@ -20,7 +20,7 @@ from reportlab.lib.enums import TA_CENTER
from pydantic import BaseModel
from ..db import SessionLocal
from ..models import QRCode, QRSet, Event
from ..models import QRCode, QRSet, Event, User
from ..templates_config import templates
router = APIRouter()
@@ -55,6 +55,12 @@ class QRCodeRequest(BaseModel):
@router.get("/", response_class=HTMLResponse)
async def qr_dashboard(request: Request, db: Session = Depends(get_db)):
"""QR code management dashboard."""
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(User).get(user_id)
# Get all QR sets
qr_sets = db.query(QRSet).all()
@@ -64,7 +70,8 @@ async def qr_dashboard(request: Request, db: Session = Depends(get_db)):
return templates.TemplateResponse("qr/dashboard.html", {
"request": request,
"qr_sets": qr_sets,
"events": events
"events": events,
"user": user # Add user to the context
})
@@ -94,6 +101,12 @@ async def create_qr_set(
@router.get("/sets/{set_id}", response_class=HTMLResponse)
async def view_qr_set(request: Request, set_id: int, db: Session = Depends(get_db)):
"""View details of a QR set."""
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(User).get(user_id)
qr_set = db.query(QRSet).filter(QRSet.id == set_id).first()
if not qr_set:
raise HTTPException(status_code=404, detail="QR Set not found")
@@ -105,7 +118,8 @@ async def view_qr_set(request: Request, set_id: int, db: Session = Depends(get_d
"request": request,
"qr_set": qr_set,
"qr_codes": qr_codes,
"base_url": BASE_URL
"base_url": BASE_URL,
"user": user # Add user to the context
})
@@ -208,6 +222,12 @@ def generate_admin_qr(set_id: int, db: Session = Depends(get_db)):
@router.get("/admin-link/{admin_code}", response_class=HTMLResponse)
async def admin_link_page(request: Request, admin_code: str, db: Session = Depends(get_db)):
"""Page for linking QR sets to events via admin code."""
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(User).get(user_id)
# Extract set_id from admin code
try:
set_id = int(admin_code.split("-")[1])
@@ -225,7 +245,8 @@ async def admin_link_page(request: Request, admin_code: str, db: Session = Depen
"request": request,
"qr_set": qr_set,
"admin_code": admin_code,
"events": events
"events": events,
"user": user # Add user to the context
})
+51 -14
View File
@@ -29,6 +29,12 @@ def redeem_code(code: str, request: Request, db: Session = Depends(get_db)):
Display a page to let the user choose which team to apply points to.
No login required.
"""
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(User).get(user_id)
# Find the QR code record
qr_code = db.query(QRCode).filter_by(code=code).first()
@@ -39,7 +45,8 @@ def redeem_code(code: str, request: Request, db: Session = Depends(get_db)):
{
"request": request,
"error_title": "Invalid Code",
"error_message": "This QR code is invalid or does not exist."
"error_message": "This QR code is invalid or does not exist.",
"user": user # Add user to the context
}
)
@@ -49,7 +56,8 @@ def redeem_code(code: str, request: Request, db: Session = Depends(get_db)):
{
"request": request,
"error_title": "Code Already Used",
"error_message": "This QR code has already been redeemed."
"error_message": "This QR code has already been redeemed.",
"user": user # Add user to the context
}
)
@@ -60,7 +68,8 @@ def redeem_code(code: str, request: Request, db: Session = Depends(get_db)):
{
"request": request,
"error_title": "Expired Code",
"error_message": "This QR code has expired and can no longer be redeemed."
"error_message": "This QR code has expired and can no longer be redeemed.",
"user": user # Add user to the context
}
)
@@ -72,16 +81,24 @@ def redeem_code(code: str, request: Request, db: Session = Depends(get_db)):
"ticket": qr_code, # Using the same template variable name for compatibility
"user_teams": all_teams,
"has_achievement": bool(qr_code.achievement_name),
"base_url": BASE_URL
"base_url": BASE_URL,
"user": user # Add user to the context
})
@router.get("/scan", response_class=HTMLResponse)
def scan_qr_code(request: Request):
def scan_qr_code(request: Request, db: Session = Depends(get_db)):
"""
Display the QR code scanner page
"""
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(User).get(user_id)
return templates.TemplateResponse("scan_qr.html", {
"request": request
"request": request,
"user": user # Add user to the context
})
@router.post("/apply/{code}")
@@ -93,6 +110,12 @@ async def apply_code(
"""
Apply the QR code to a selected team and award points and/or achievements
"""
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(User).get(user_id)
# Get form data
form_data = await request.form()
team_id = int(form_data.get("team_id", 0))
@@ -103,7 +126,8 @@ async def apply_code(
{
"request": request,
"error_title": "Team Selection Required",
"error_message": "Please select a team to redeem this code."
"error_message": "Please select a team to redeem this code.",
"user": user # Add user to the context
}
)
@@ -115,7 +139,8 @@ async def apply_code(
{
"request": request,
"error_title": "Invalid Code",
"error_message": "This QR code is invalid or does not exist."
"error_message": "This QR code is invalid or does not exist.",
"user": user # Add user to the context
}
)
@@ -126,7 +151,8 @@ async def apply_code(
{
"request": request,
"error_title": "Code Already Used",
"error_message": "This QR code has already been redeemed."
"error_message": "This QR code has already been redeemed.",
"user": user # Add user to the context
}
)
@@ -137,7 +163,8 @@ async def apply_code(
{
"request": request,
"error_title": "Expired Code",
"error_message": "This QR code has expired and can no longer be redeemed."
"error_message": "This QR code has expired and can no longer be redeemed.",
"user": user # Add user to the context
}
)
@@ -148,7 +175,8 @@ async def apply_code(
{
"request": request,
"error_title": "Team Not Found",
"error_message": "The selected team could not be found."
"error_message": "The selected team could not be found.",
"user": user # Add user to the context
}
)
@@ -180,7 +208,8 @@ async def apply_code(
"achievement": qr_code.achievement_name if qr_code.achievement_name else None,
"team": team,
"event": qr_code.event if qr_code.event else None,
"base_url": BASE_URL
"base_url": BASE_URL,
"user": user # Add user to the context
}
)
@@ -194,6 +223,12 @@ async def manual_code_entry(
Handle manual code entry from the form.
This redirects to the normal redeem flow after validating the code.
"""
# Get user from session for navbar
user = None
user_id = request.session.get("user_id")
if user_id:
user = db.query(User).get(user_id)
# Check if the code exists
qr_code = db.query(QRCode).filter_by(code=code).first()
@@ -203,7 +238,8 @@ async def manual_code_entry(
{
"request": request,
"error_title": "Invalid Code",
"error_message": "The code you entered is invalid or does not exist."
"error_message": "The code you entered is invalid or does not exist.",
"user": user # Add user to the context
}
)
@@ -214,7 +250,8 @@ async def manual_code_entry(
{
"request": request,
"error_title": "Code Already Used",
"error_message": "This code has already been redeemed."
"error_message": "This code has already been redeemed.",
"user": user # Add user to the context
}
)