UX: alarm-status, ablehnen-button, annika-footer, map polish
* Alarm-Status ist jetzt nur 'aktiv' wenn ein echter Push-Channel (Telegram mit Token+Chat oder E-Mail mit Adresse) konfiguriert ist. UI-only zählt nicht mehr als eingerichteter Alarm. * Ablehnen-Button in der Wohnungsliste: flat_rejections (migration v4) speichert pro-User-Ablehnungen, abgelehnte Flats fallen aus Liste und Karte raus. Wiederholbar pro User unabhängig. * Footer 'Programmiert für Annika ♥' erscheint nur auf Seiten, wenn annika angemeldet ist. * Map: Hinweistext unter leerer Karte entfernt; alle Zoom-Mechanismen deaktiviert (Scrollrad, Doppelklick, Box, Touch, Tastatur, +/- Buttons). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
376551213a
commit
42377f0b67
5 changed files with 97 additions and 18 deletions
37
web/db.py
37
web/db.py
|
|
@ -185,6 +185,16 @@ MIGRATIONS: list[str] = [
|
|||
ALTER TABLE flats ADD COLUMN lat REAL;
|
||||
ALTER TABLE flats ADD COLUMN lng REAL;
|
||||
""",
|
||||
# 0004: per-user rejections — flats the user doesn't want in the list anymore
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS flat_rejections (
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
flat_id TEXT NOT NULL REFERENCES flats(id),
|
||||
rejected_at TEXT NOT NULL,
|
||||
PRIMARY KEY (user_id, flat_id)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_rejections_user ON flat_rejections(user_id);
|
||||
""",
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -471,6 +481,33 @@ def recent_applications(user_id: Optional[int], limit: int = 50) -> list[sqlite3
|
|||
).fetchall())
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Rejections (flats a user doesn't want to see anymore)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
def reject_flat(user_id: int, flat_id: str) -> None:
|
||||
with _lock:
|
||||
_conn.execute(
|
||||
"INSERT OR IGNORE INTO flat_rejections(user_id, flat_id, rejected_at) VALUES (?, ?, ?)",
|
||||
(user_id, flat_id, now_iso()),
|
||||
)
|
||||
|
||||
|
||||
def unreject_flat(user_id: int, flat_id: str) -> None:
|
||||
with _lock:
|
||||
_conn.execute(
|
||||
"DELETE FROM flat_rejections WHERE user_id = ? AND flat_id = ?",
|
||||
(user_id, flat_id),
|
||||
)
|
||||
|
||||
|
||||
def rejected_flat_ids(user_id: int) -> set[str]:
|
||||
rows = _conn.execute(
|
||||
"SELECT flat_id FROM flat_rejections WHERE user_id = ?", (user_id,)
|
||||
).fetchall()
|
||||
return {row["flat_id"] for row in rows}
|
||||
|
||||
|
||||
def last_application_for_flat(user_id: int, flat_id: str) -> Optional[sqlite3.Row]:
|
||||
return _conn.execute(
|
||||
"""SELECT * FROM applications
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue