Add support to add events
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
|
import locale
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
|
from datetime import datetime
|
||||||
from typing import Annotated, Union
|
from typing import Annotated, Union
|
||||||
|
|
||||||
import starlette.status as status
|
import starlette.status as status
|
||||||
@@ -16,6 +18,8 @@ sqlite_url = f"sqlite:///{sqlite_file_name}"
|
|||||||
connect_args = {"check_same_thread": False}
|
connect_args = {"check_same_thread": False}
|
||||||
engine = create_engine(sqlite_url, connect_args=connect_args)
|
engine = create_engine(sqlite_url, connect_args=connect_args)
|
||||||
|
|
||||||
|
locale.setlocale(locale.LC_ALL, "de_DE.UTF-8")
|
||||||
|
|
||||||
|
|
||||||
def get_session():
|
def get_session():
|
||||||
with Session(engine) as session:
|
with Session(engine) as session:
|
||||||
@@ -45,10 +49,46 @@ async def read_root(request: Request, session: SessionDep):
|
|||||||
statement = select(Event).order_by(Event.event_time)
|
statement = select(Event).order_by(Event.event_time)
|
||||||
events = session.exec(statement).all()
|
events = session.exec(statement).all()
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
request=request, name="index.html", context={"events": events}
|
request=request,
|
||||||
|
name="index.html",
|
||||||
|
context={"events": events, "current_page": "home", "now": datetime.now()},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/event/add")
|
||||||
|
async def add_event_form(request: Request, session: SessionDep):
|
||||||
|
return templates.TemplateResponse(request=request, name="add_event.html")
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/event/add")
|
||||||
|
async def add_event(request: Request, session: SessionDep):
|
||||||
|
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 = Event(
|
||||||
|
title=form_data["eventName"],
|
||||||
|
event_time=event_time,
|
||||||
|
registration_deadline=registration_deadline,
|
||||||
|
description=form_data.get("eventDescription"),
|
||||||
|
recipe_link=form_data.get("recipeLink"),
|
||||||
|
)
|
||||||
|
session.add(event)
|
||||||
|
session.commit()
|
||||||
|
return RedirectResponse(url="/", status_code=status.HTTP_302_FOUND)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/event/{event_id}")
|
@app.get("/event/{event_id}")
|
||||||
async def read_event(request: Request, event_id: int, session: SessionDep):
|
async def read_event(request: Request, event_id: int, session: SessionDep):
|
||||||
statement = select(Event).where(Event.id == event_id)
|
statement = select(Event).where(Event.id == event_id)
|
||||||
@@ -56,6 +96,14 @@ async def read_event(request: Request, event_id: int, session: SessionDep):
|
|||||||
|
|
||||||
statement = select(Household)
|
statement = select(Household)
|
||||||
households = session.exec(statement).all()
|
households = session.exec(statement).all()
|
||||||
|
|
||||||
|
# filter out households with existing registrations
|
||||||
|
households = [
|
||||||
|
h
|
||||||
|
for h in households
|
||||||
|
if h.id not in [reg.household_id for reg in event.registrations]
|
||||||
|
]
|
||||||
|
|
||||||
return templates.TemplateResponse(
|
return templates.TemplateResponse(
|
||||||
request=request,
|
request=request,
|
||||||
name="event.html",
|
name="event.html",
|
||||||
|
|||||||
39
new-registration-app/templates/add_event.html
Normal file
39
new-registration-app/templates/add_event.html
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="row justify-content-center mt-4">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<h2>Neues Event erstellen</h2>
|
||||||
|
<form method="post" action="/event/add">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="eventName" class="form-label">Event Name</label>
|
||||||
|
<input type="text" class="form-control" id="eventName" name="eventName" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="eventTime" class="form-label">Datum und Uhrzeit</label>
|
||||||
|
<input type="datetime-local" class="form-control" id="eventTime" name="eventTime" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="registrationDeadline" class="form-label">Anmeldungs-Deadline</label>
|
||||||
|
<input type="datetime-local" class="form-control" id="registrationDeadline" name="registrationDeadline">
|
||||||
|
<small class="form-text text-muted">Leer lassen für Sonntag Abend vor dem Event</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="recipeLink" class="form-label">Rezept-Link</label>
|
||||||
|
<input type="text" class="form-control" id="recipeLink" name="recipeLink">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="eventDescription" class="form-label">Beschreibung</label>
|
||||||
|
<textarea class="form-control" id="eventDescription" name="eventDescription" rows="3"></textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary">Event erstellen</button>
|
||||||
|
<a href="/new-registration-app/static" class="btn btn-secondary">Abbrechen</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|
||||||
<title>Bootstrap demo</title>
|
<title>Allmende Essen</title>
|
||||||
<link href="/static/css/bootstrap.min.css" rel="stylesheet"
|
<link href="/static/css/bootstrap.min.css" rel="stylesheet"
|
||||||
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB">
|
integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB">
|
||||||
<link href="/static/icons/bootstrap-icons.min.css" rel="stylesheet">
|
<link href="/static/icons/bootstrap-icons.min.css" rel="stylesheet">
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
<body class="p-3 m-0 border-0 bd-example m-0 border-0">
|
<body class="p-3 m-0 border-0 bd-example m-0 border-0">
|
||||||
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" href="#">
|
<a class="navbar-brand" href="/">
|
||||||
<img src="/static/img/Logo.png" alt="Logo" height="30" class="d-inline-block align-text-top">
|
<img src="/static/img/Logo.png" alt="Logo" height="30" class="d-inline-block align-text-top">
|
||||||
Allmende Essen
|
Allmende Essen
|
||||||
</a>
|
</a>
|
||||||
@@ -22,13 +22,13 @@
|
|||||||
<div class="collapse navbar-collapse" id="navbarNav">
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link active" aria-current="page" href="#">Home</a>
|
<a class="nav-link {% if current_page == 'home' %}active{% endif %}" {% if current_page == 'home' %}aria-current="page"{% endif %} href="/">Home</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="#">Vergangene</a>
|
<a class="nav-link {% if current_page == 'vergangene' %}active{% endif %}" {% if current_page == 'vergangene' %}aria-current="page"{% endif %} href="/vergangene">Vergangene</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="#">Preise</a>
|
<a class="nav-link {% if current_page == 'preise' %}active{% endif %}" {% if current_page == 'preise' %}aria-current="page"{% endif %} href="/preise">Preise</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,11 +6,18 @@
|
|||||||
<p class="h3">Anmeldungen</p>
|
<p class="h3">Anmeldungen</p>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-4 d-flex align-items-center">
|
<div class="col-md-4 d-flex justify-content-center align-items-center flex-column">
|
||||||
<!-- Button trigger modal -->
|
<!-- Button trigger modal -->
|
||||||
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#staticBackdrop">
|
<button type="button" class="btn btn-primary mb-2" data-bs-toggle="modal" data-bs-target="#staticBackdrop">
|
||||||
Anmeldung hinzufügen
|
Anmeldung hinzufügen
|
||||||
</button>
|
</button>
|
||||||
|
{% if event.recipe_link %}
|
||||||
|
<div class="mb-3">
|
||||||
|
<a href="{{ event.recipe_link }}" class="btn btn-outline-primary" target="_blank">
|
||||||
|
<i class="bi bi-book"></i> Original Rezept ansehen
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-8">
|
<div class="col-md-8">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
@@ -71,9 +78,9 @@
|
|||||||
<h1 class="modal-title fs-5" id="staticBackdropLabel">Anmeldung hinzufügen</h1>
|
<h1 class="modal-title fs-5" id="staticBackdropLabel">Anmeldung hinzufügen</h1>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form action="/event/{{event.id}}/register" method="POST">
|
<form action="/event/{{event.id}}/register" method="POST">
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
<p>Wenn dein Haushalt nicht auswählbar ist, existiert schon eine Anmeldung. Wenn du die Anmeldung ändern willst, lösche die bestehende Anmeldung und lege eine neue an.</p>
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
<select name="household" class="form-select" aria-label="Multiple select example">
|
<select name="household" class="form-select" aria-label="Multiple select example">
|
||||||
<option selected>Wer?</option>
|
<option selected>Wer?</option>
|
||||||
|
|||||||
@@ -1,13 +1,26 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
<div class="row mt-4 mb-3">
|
||||||
|
<div class="col d-flex justify-content-between align-items-center">
|
||||||
|
<h2>Kommende Events</h2>
|
||||||
|
<a href="/event/add" class="btn btn-primary">
|
||||||
|
<i class="bi bi-plus-circle"></i> Neues Event erstellen
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% for event in events %}
|
{% for event in events %}
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<div class="card p-3 m-3">
|
<div class="card p-3 m-3">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<h5 class="card-title">{{ event.title }}</h5>
|
<div class="d-flex justify-content-between align-items-center">
|
||||||
|
<h5 class="card-title">{{ event.title }}</h5>
|
||||||
|
<h5 class="text-muted"><i class="bi bi-calendar"></i> {{ event.event_time.strftime('%A, %d.%m.%Y')
|
||||||
|
}}
|
||||||
|
</h5>
|
||||||
|
</div>
|
||||||
<p class="card-text">{{ event.description }}</p>
|
<p class="card-text">{{ event.description }}</p>
|
||||||
<a href="event/{{ event.id }}" class="btn btn-primary">Zur Anmeldung</a>
|
<a href="event/{{ event.id }}" class="btn {% if event.registration_deadline > now %}btn-primary{% else %}btn-secondary{% endif %}">{% if event.registration_deadline > now %}Zur Anmeldung{% else %}Details ansehen{% endif %}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user