Fetch stops from OpenStreetMap
Deploy PBT / deploy (push) Successful in 16s

This commit is contained in:
2026-09-10 21:44:45 +02:00
parent 0ebf13aacf
commit 2a6e9c690b
14 changed files with 666 additions and 9 deletions
+15 -4
View File
@@ -18,14 +18,22 @@
<input type="text" id="line" name="line" placeholder="z.B. S3, Bus 10">
</div>
<div class="field">
<div class="field combo">
<label for="origin">Von<span class="required">*</span></label>
<input type="text" id="origin" name="origin" required>
<input type="text" id="origin" name="origin" required
placeholder="Haltestelle suchen …"
data-stop-input data-stop-target="#origin_stop_id">
<input type="hidden" id="origin_stop_id" name="origin_stop_id">
<p class="field-hint" data-stop-hint></p>
</div>
<div class="field">
<div class="field combo">
<label for="destination">Nach<span class="required">*</span></label>
<input type="text" id="destination" name="destination" required>
<input type="text" id="destination" name="destination" required
placeholder="Haltestelle suchen …"
data-stop-input data-stop-target="#destination_stop_id">
<input type="hidden" id="destination_stop_id" name="destination_stop_id">
<p class="field-hint" data-stop-hint></p>
</div>
<div class="field">
@@ -53,3 +61,6 @@
</form>
</div>
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='stops.js') }}" defer></script>
{% endblock %}
+35
View File
@@ -134,6 +134,36 @@
th, td { text-align: left; padding: 0.6rem 0.4rem; border-bottom: 1px solid var(--panel-border); font-size: 0.9rem; }
th { color: var(--text-muted); font-weight: 600; }
.stars { color: #e3b341; white-space: nowrap; }
.stop-dot { color: var(--success); font-size: 0.7rem; vertical-align: middle; }
.combo { position: relative; display: flex; flex-direction: column; }
.combo-list {
position: absolute;
z-index: 20;
left: 0;
right: 0;
top: calc(100% + 4px);
background: var(--panel);
border: 1px solid var(--panel-border);
border-radius: 6px;
max-height: 260px;
overflow-y: auto;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}
.combo-option {
display: flex;
align-items: baseline;
gap: 0.5rem;
padding: 0.5rem 0.7rem;
font-size: 0.9rem;
cursor: pointer;
}
.combo-option.active, .combo-option:hover { background: rgba(74, 158, 255, 0.15); }
.combo-option .muni { color: var(--text-muted); font-size: 0.8rem; }
.combo-option .kind { margin-left: auto; font-size: 0.75rem; color: var(--text-muted); white-space: nowrap; }
.combo-empty { padding: 0.5rem 0.7rem; font-size: 0.85rem; color: var(--text-muted); }
.field-hint { font-size: 0.75rem; color: var(--text-muted); margin-top: 0.3rem; min-height: 1em; }
.field-hint.matched { color: var(--success); }
</style>
</head>
<body>
@@ -158,5 +188,10 @@
{% endwith %}
{% block content %}{% endblock %}
<footer style="margin-top: 3rem; text-align: center; font-size: 0.75rem; color: var(--text-muted);">
Haltestellendaten © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>-Mitwirkende (ODbL)
</footer>
{% block scripts %}{% endblock %}
</body>
</html>
+4 -1
View File
@@ -26,7 +26,10 @@
<td>{{ f.trip_date.strftime("%d.%m.%Y") }}</td>
<td>{{ f.transport_mode }}</td>
<td>{{ f.line or "" }}</td>
<td>{{ f.origin }} → {{ f.destination }}</td>
<td>
{{ f.origin }}{% if f.origin_stop %}<span class="stop-dot" title="Verifizierte Haltestelle"></span>{% endif %}
→ {{ f.destination }}{% if f.destination_stop %}<span class="stop-dot" title="Verifizierte Haltestelle"></span>{% endif %}
</td>
<td class="stars">{{ "★" * f.rating }}{{ "☆" * (5 - f.rating) }}</td>
<td>
<form method="post" action="{{ url_for('fahrt_loeschen', fahrt_id=f.id) }}" onsubmit="return confirm('Fahrt wirklich löschen?');" style="margin: 0;">