From 4aa6ac97fd298b7f888ae20af9f1e473728324b2 Mon Sep 17 00:00:00 2001 From: Niklas Meinzer Date: Wed, 15 Oct 2025 12:02:18 +0200 Subject: [PATCH] Feat: Add ability to edit events for logged in users --- src/meal_manager/main.py | 96 ++++++++++++++++++----- src/meal_manager/templates/add_event.html | 16 ++-- src/meal_manager/templates/event.html | 25 +++++- src/meal_manager/templates/index.html | 22 +----- src/meal_manager/templates/macros.j2 | 19 +++++ 5 files changed, 127 insertions(+), 51 deletions(-) create mode 100644 src/meal_manager/templates/macros.j2 diff --git a/src/meal_manager/main.py b/src/meal_manager/main.py index d20ed7e..09ab57c 100644 --- a/src/meal_manager/main.py +++ b/src/meal_manager/main.py @@ -36,7 +36,8 @@ def get_session(): with Session(engine) as session: yield session -def get_user(request: Request, allow_none: bool=True) -> dict | None: + +def get_user(request: Request, allow_none: bool = True) -> dict | None: """ Retrieve user information from the incoming request. @@ -68,6 +69,7 @@ def get_user(request: Request, allow_none: bool=True) -> dict | None: else: raise HTTPException(status_code=401, detail="Not logged in") + def create_db_and_tables(): Base.metadata.create_all(engine) @@ -87,8 +89,10 @@ SessionDep = Annotated[Session, Depends(get_session)] UserDep = Annotated[dict, Depends(get_user)] StrictUserDep = Annotated[dict, Depends(partial(get_user, allow_none=False))] + + @app.get("/") -async def index(request: Request, session: SessionDep, user : UserDep): +async def index(request: Request, session: SessionDep, user: UserDep): """Displays coming events and a button to register new ones""" now = datetime.now() # TODO: Once we refactored to use SQLAlchemy directly, we can probably do a nicer filtering on the date alone @@ -194,22 +198,46 @@ async def add_event_form(request: Request, user: StrictUserDep): return templates.TemplateResponse(request=request, name="add_event.html") +@app.get("/event/{event_id}/edit") +async def edit_event_form( + request: Request, event_id: int, session: SessionDep, user: StrictUserDep +): + statement = select(Event).where(Event.id == event_id) + event = session.scalars(statement).one() + + return templates.TemplateResponse( + request=request, + context={"event": event, "edit_mode": True}, + name="add_event.html", + ) + + +@app.post("/event/{event_id}/edit") +async def edit_event( + request: Request, event_id: int, session: SessionDep, user: StrictUserDep +): + statement = select(Event).where(Event.id == event_id) + event = session.scalars(statement).one() + + form_data = await request.form() + event_time, registration_deadline = await parse_event_times(form_data) + + event.title = form_data["eventName"] + event.event_time = event_time + event.registration_deadline = registration_deadline + event.description = form_data.get("eventDescription") + event.recipe_link = form_data.get("recipeLink") + + session.commit() + + return RedirectResponse(url=f"/event/{event.id}", status_code=status.HTTP_302_FOUND) + + @app.post("/event/add") async def add_event(request: Request, session: SessionDep, user: StrictUserDep): form_data = await request.form() - event_time = datetime.fromisoformat(form_data["eventTime"]) - registration_deadline = form_data.get("registrationDeadline") - if not registration_deadline: - # Find the last Sunday before event_time - deadline = event_time - while deadline.weekday() != 6: # 6 represents Sunday - deadline = deadline.replace(day=deadline.day - 1) - registration_deadline = deadline.replace( - hour=19, minute=30, second=0, microsecond=0 - ) - else: - registration_deadline = datetime.fromisoformat(registration_deadline) + event_time, registration_deadline = await parse_event_times(form_data) event = Event( title=form_data["eventName"], @@ -222,8 +250,27 @@ async def add_event(request: Request, session: SessionDep, user: StrictUserDep): session.commit() return RedirectResponse(url="/", status_code=status.HTTP_302_FOUND) + +async def parse_event_times(form_data): + event_time = datetime.fromisoformat(form_data["eventTime"]) + registration_deadline = form_data.get("registrationDeadline") + if not registration_deadline: + # Find the last Sunday before event_time + deadline = event_time + while deadline.weekday() != 6: # 6 represents Sunday + deadline = deadline.replace(day=deadline.day - 1) + registration_deadline = deadline.replace( + hour=19, minute=30, second=0, microsecond=0 + ) + else: + registration_deadline = datetime.fromisoformat(registration_deadline) + return event_time, registration_deadline + + @app.get("/event/{event_id}/delete") -async def delete_event(request: Request, session: SessionDep, event_id: int, user: StrictUserDep): +async def delete_event( + request: Request, session: SessionDep, event_id: int, user: StrictUserDep +): if not user["admin"]: raise HTTPException(status_code=403, detail="Not authorized") @@ -234,8 +281,11 @@ async def delete_event(request: Request, session: SessionDep, event_id: int, use session.commit() return RedirectResponse(url="/", status_code=status.HTTP_302_FOUND) + @app.get("/event/{event_id}") -async def read_event(request: Request, event_id: int, session: SessionDep, user: UserDep): +async def read_event( + request: Request, event_id: int, session: SessionDep, user: UserDep +): statement = select(Event).where(Event.id == event_id) event = session.scalars(statement).one() @@ -252,7 +302,12 @@ async def read_event(request: Request, event_id: int, session: SessionDep, user: return templates.TemplateResponse( request=request, name="event.html", - context={"event": event, "households": households, "now": datetime.now(), "user": user}, + context={ + "event": event, + "households": households, + "now": datetime.now(), + "user": user, + }, ) @@ -334,6 +389,7 @@ async def delete_team_registration( session.commit() return RedirectResponse(url=f"/event/{event_id}", status_code=status.HTTP_302_FOUND) + @app.get("/event/{event_id}/pdf") def get_event_attendance_pdf(event_id: int, session: SessionDep): @@ -347,7 +403,5 @@ def get_event_attendance_pdf(event_id: int, session: SessionDep): } return Response( - content=pdf_buffer.getvalue(), - media_type="application/pdf", - headers=headers - ) \ No newline at end of file + content=pdf_buffer.getvalue(), media_type="application/pdf", headers=headers + ) diff --git a/src/meal_manager/templates/add_event.html b/src/meal_manager/templates/add_event.html index 201ccdd..07e995e 100644 --- a/src/meal_manager/templates/add_event.html +++ b/src/meal_manager/templates/add_event.html @@ -3,35 +3,35 @@ {% block content %}
-

Neues Event erstellen

-
+ {% if edit_mode %}

Event bearbeiten

{% else %}

Neues Event erstellen

{% endif %} + {% if edit_mode %}{% else %}{% endif %}
- +
- +
- + Leer lassen für Sonntag Abend vor dem Event
- +
- +
- +
diff --git a/src/meal_manager/templates/event.html b/src/meal_manager/templates/event.html index b156e85..ee88ff6 100644 --- a/src/meal_manager/templates/event.html +++ b/src/meal_manager/templates/event.html @@ -1,3 +1,4 @@ +{% import "macros.j2" as macros %} {% macro teamEntries(event, work_type) -%} {% for entry in event.team | selectattr("work_type", "equalto", work_type)%}
@@ -34,9 +35,24 @@ Original Rezept ansehen {% endif %} - - Druckansicht - +
+ +
+ {% if user -%} + + Event bearbeiten + + {% else -%} + + {% endif -%} +
+
{% if user and user.admin %}
+ +{{ macros.login_info_modal() }} + {% endblock %} \ No newline at end of file diff --git a/src/meal_manager/templates/index.html b/src/meal_manager/templates/index.html index 0adf9fe..8b69cc6 100644 --- a/src/meal_manager/templates/index.html +++ b/src/meal_manager/templates/index.html @@ -1,4 +1,5 @@ {% extends "base.html" %} +{% import "macros.j2" as macros %} {% block content %}
@@ -8,7 +9,7 @@ Neues Event erstellen {% else %} - {% endif %} @@ -48,22 +49,5 @@
- +{{ macros.login_info_modal() }} {% endblock %} - diff --git a/src/meal_manager/templates/macros.j2 b/src/meal_manager/templates/macros.j2 new file mode 100644 index 0000000..a98ec30 --- /dev/null +++ b/src/meal_manager/templates/macros.j2 @@ -0,0 +1,19 @@ +{% macro login_info_modal() -%} + +{%- endmacro %} \ No newline at end of file