@@ -0,0 +1,5 @@
|
|||||||
|
# CLAUDE.md
|
||||||
|
|
||||||
|
## Conventions
|
||||||
|
|
||||||
|
- Database objects (tables, columns, indexes, constraints, etc.) must be named in English, using snake_case (all lowercase, words separated by underscores, e.g. `user_account`, `created_at`).
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -10,7 +10,7 @@ from flask_login import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
from config import Config
|
from config import Config
|
||||||
from models import db, User, Fahrt, VERKEHRSMITTEL_OPTIONEN
|
from models import db, User, Trip, VERKEHRSMITTEL_OPTIONEN
|
||||||
|
|
||||||
login_manager = LoginManager()
|
login_manager = LoginManager()
|
||||||
login_manager.login_view = "login"
|
login_manager.login_view = "login"
|
||||||
@@ -91,8 +91,8 @@ def register_routes(app):
|
|||||||
@login_required
|
@login_required
|
||||||
def dashboard():
|
def dashboard():
|
||||||
fahrten = (
|
fahrten = (
|
||||||
Fahrt.query.filter_by(user_id=current_user.id)
|
Trip.query.filter_by(user_id=current_user.id)
|
||||||
.order_by(Fahrt.datum.desc())
|
.order_by(Trip.trip_date.desc())
|
||||||
.all()
|
.all()
|
||||||
)
|
)
|
||||||
return render_template("dashboard.html", fahrten=fahrten)
|
return render_template("dashboard.html", fahrten=fahrten)
|
||||||
@@ -101,15 +101,15 @@ def register_routes(app):
|
|||||||
@login_required
|
@login_required
|
||||||
def neue_fahrt():
|
def neue_fahrt():
|
||||||
if request.method == "POST":
|
if request.method == "POST":
|
||||||
fahrt = Fahrt(
|
fahrt = Trip(
|
||||||
user_id=current_user.id,
|
user_id=current_user.id,
|
||||||
verkehrsmittel=request.form["verkehrsmittel"],
|
transport_mode=request.form["transport_mode"],
|
||||||
linie=request.form.get("linie", "").strip(),
|
line=request.form.get("line", "").strip(),
|
||||||
von=request.form["von"].strip(),
|
origin=request.form["origin"].strip(),
|
||||||
nach=request.form["nach"].strip(),
|
destination=request.form["destination"].strip(),
|
||||||
datum=request.form.get("datum") or date.today(),
|
trip_date=request.form.get("trip_date") or date.today(),
|
||||||
bewertung=int(request.form["bewertung"]),
|
rating=int(request.form["rating"]),
|
||||||
kommentar=request.form.get("kommentar", "").strip(),
|
comment=request.form.get("comment", "").strip(),
|
||||||
)
|
)
|
||||||
db.session.add(fahrt)
|
db.session.add(fahrt)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
@@ -125,7 +125,7 @@ def register_routes(app):
|
|||||||
@app.route("/fahrt/<int:fahrt_id>/loeschen", methods=["POST"])
|
@app.route("/fahrt/<int:fahrt_id>/loeschen", methods=["POST"])
|
||||||
@login_required
|
@login_required
|
||||||
def fahrt_loeschen(fahrt_id):
|
def fahrt_loeschen(fahrt_id):
|
||||||
fahrt = Fahrt.query.get_or_404(fahrt_id)
|
fahrt = Trip.query.get_or_404(fahrt_id)
|
||||||
if fahrt.user_id != current_user.id:
|
if fahrt.user_id != current_user.id:
|
||||||
flash("Nicht erlaubt.", "error")
|
flash("Nicht erlaubt.", "error")
|
||||||
return redirect(url_for("dashboard"))
|
return redirect(url_for("dashboard"))
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ class User(UserMixin, db.Model):
|
|||||||
email = db.Column(db.String(120), unique=True, nullable=False, index=True)
|
email = db.Column(db.String(120), unique=True, nullable=False, index=True)
|
||||||
password_hash = db.Column(db.String(255), nullable=False)
|
password_hash = db.Column(db.String(255), nullable=False)
|
||||||
|
|
||||||
fahrten = db.relationship(
|
trips = db.relationship(
|
||||||
"Fahrt", backref="user", lazy=True, cascade="all, delete-orphan"
|
"Trip", backref="user", lazy=True, cascade="all, delete-orphan"
|
||||||
)
|
)
|
||||||
|
|
||||||
def set_password(self, password: str) -> None:
|
def set_password(self, password: str) -> None:
|
||||||
@@ -36,18 +36,18 @@ VERKEHRSMITTEL_OPTIONEN = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class Fahrt(db.Model):
|
class Trip(db.Model):
|
||||||
__tablename__ = "fahrten"
|
__tablename__ = "trips"
|
||||||
|
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False, index=True)
|
user_id = db.Column(db.Integer, db.ForeignKey("users.id"), nullable=False, index=True)
|
||||||
|
|
||||||
verkehrsmittel = db.Column(db.String(50), nullable=False)
|
transport_mode = db.Column(db.String(50), nullable=False)
|
||||||
linie = db.Column(db.String(50))
|
line = db.Column(db.String(50))
|
||||||
von = db.Column(db.String(120), nullable=False)
|
origin = db.Column(db.String(120), nullable=False)
|
||||||
nach = db.Column(db.String(120), nullable=False)
|
destination = db.Column(db.String(120), nullable=False)
|
||||||
datum = db.Column(db.Date, nullable=False, default=date.today)
|
trip_date = db.Column(db.Date, nullable=False, default=date.today)
|
||||||
bewertung = db.Column(db.Integer, nullable=False) # 1-5
|
rating = db.Column(db.Integer, nullable=False) # 1-5
|
||||||
kommentar = db.Column(db.Text)
|
comment = db.Column(db.Text)
|
||||||
|
|
||||||
erstellt_am = db.Column(db.DateTime, server_default=db.func.now())
|
created_at = db.Column(db.DateTime, server_default=db.func.now())
|
||||||
|
|||||||
+14
-14
@@ -5,8 +5,8 @@
|
|||||||
<h2>Neue Fahrt erfassen</h2>
|
<h2>Neue Fahrt erfassen</h2>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="verkehrsmittel">Verkehrsmittel<span class="required">*</span></label>
|
<label for="transport_mode">Verkehrsmittel<span class="required">*</span></label>
|
||||||
<select id="verkehrsmittel" name="verkehrsmittel" required>
|
<select id="transport_mode" name="transport_mode" required>
|
||||||
{% for option in verkehrsmittel_optionen %}
|
{% for option in verkehrsmittel_optionen %}
|
||||||
<option value="{{ option }}">{{ option }}</option>
|
<option value="{{ option }}">{{ option }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -14,28 +14,28 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="linie">Linie</label>
|
<label for="line">Linie</label>
|
||||||
<input type="text" id="linie" name="linie" placeholder="z.B. S3, Bus 10">
|
<input type="text" id="line" name="line" placeholder="z.B. S3, Bus 10">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="von">Von<span class="required">*</span></label>
|
<label for="origin">Von<span class="required">*</span></label>
|
||||||
<input type="text" id="von" name="von" required>
|
<input type="text" id="origin" name="origin" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="nach">Nach<span class="required">*</span></label>
|
<label for="destination">Nach<span class="required">*</span></label>
|
||||||
<input type="text" id="nach" name="nach" required>
|
<input type="text" id="destination" name="destination" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="datum">Datum<span class="required">*</span></label>
|
<label for="trip_date">Datum<span class="required">*</span></label>
|
||||||
<input type="date" id="datum" name="datum" value="{{ heute }}" required>
|
<input type="date" id="trip_date" name="trip_date" value="{{ heute }}" required>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="bewertung">Bewertung<span class="required">*</span></label>
|
<label for="rating">Bewertung<span class="required">*</span></label>
|
||||||
<select id="bewertung" name="bewertung" required>
|
<select id="rating" name="rating" required>
|
||||||
<option value="5">★★★★★ Sehr gut</option>
|
<option value="5">★★★★★ Sehr gut</option>
|
||||||
<option value="4">★★★★☆ Gut</option>
|
<option value="4">★★★★☆ Gut</option>
|
||||||
<option value="3" selected>★★★☆☆ Okay</option>
|
<option value="3" selected>★★★☆☆ Okay</option>
|
||||||
@@ -45,8 +45,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="kommentar">Kommentar</label>
|
<label for="comment">Kommentar</label>
|
||||||
<textarea id="kommentar" name="kommentar" rows="3"></textarea>
|
<textarea id="comment" name="comment" rows="3"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit">Speichern</button>
|
<button type="submit">Speichern</button>
|
||||||
|
|||||||
@@ -23,19 +23,19 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{% for f in fahrten %}
|
{% for f in fahrten %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{ f.datum.strftime("%d.%m.%Y") }}</td>
|
<td>{{ f.trip_date.strftime("%d.%m.%Y") }}</td>
|
||||||
<td>{{ f.verkehrsmittel }}</td>
|
<td>{{ f.transport_mode }}</td>
|
||||||
<td>{{ f.linie or "–" }}</td>
|
<td>{{ f.line or "–" }}</td>
|
||||||
<td>{{ f.von }} → {{ f.nach }}</td>
|
<td>{{ f.origin }} → {{ f.destination }}</td>
|
||||||
<td class="stars">{{ "★" * f.bewertung }}{{ "☆" * (5 - f.bewertung) }}</td>
|
<td class="stars">{{ "★" * f.rating }}{{ "☆" * (5 - f.rating) }}</td>
|
||||||
<td>
|
<td>
|
||||||
<form method="post" action="{{ url_for('fahrt_loeschen', fahrt_id=f.id) }}" onsubmit="return confirm('Fahrt wirklich löschen?');" style="margin: 0;">
|
<form method="post" action="{{ url_for('fahrt_loeschen', fahrt_id=f.id) }}" onsubmit="return confirm('Fahrt wirklich löschen?');" style="margin: 0;">
|
||||||
<button type="submit" class="secondary" style="width: auto; padding: 0.35rem 0.7rem; font-size: 0.8rem;">Löschen</button>
|
<button type="submit" class="secondary" style="width: auto; padding: 0.35rem 0.7rem; font-size: 0.8rem;">Löschen</button>
|
||||||
</form>
|
</form>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% if f.kommentar %}
|
{% if f.comment %}
|
||||||
<tr><td></td><td colspan="5" style="color: var(--text-muted); font-size: 0.85rem;">{{ f.kommentar }}</td></tr>
|
<tr><td></td><td colspan="5" style="color: var(--text-muted); font-size: 0.85rem;">{{ f.comment }}</td></tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
Reference in New Issue
Block a user