Initial Release: Lütte Planer mit Google-Login-Vorbereitung

- Login-System (Mock für Tests, Google OAuth vorbereitet)
- Reisen erstellen mit Emoji, Ziel und Datum
- Ablauf (Timeline), Packliste, Ideen, Notizen, Dokumente
- Team-System: Personen einladen per E-Mail + Einladungslinks
- Berechtigungen: Nur lesen / Bearbeiten / Admin
- E-Mail-Benachrichtigungen beim Einladen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-26 20:56:30 +02:00
co-authored by Claude Sonnet 4.6
commit bd8a322fc0
21 changed files with 1647 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
<?php
define('DB_FILE', DATA_DIR . 'planer.sqlite');
function db(): PDO {
static $pdo = null;
if ($pdo === null) {
$isNew = !file_exists(DB_FILE);
$pdo = new PDO('sqlite:' . DB_FILE);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$pdo->exec('PRAGMA foreign_keys = ON');
$pdo->exec('PRAGMA journal_mode = WAL');
if ($isNew) {
$pdo->exec(file_get_contents(__DIR__ . '/db.sql'));
}
}
return $pdo;
}
function dbAll(string $sql, array $params = []): array {
$stmt = db()->prepare($sql);
$stmt->execute($params);
return $stmt->fetchAll();
}
function dbOne(string $sql, array $params = []): ?array {
$stmt = db()->prepare($sql);
$stmt->execute($params);
$row = $stmt->fetch();
return $row === false ? null : $row;
}
function dbExec(string $sql, array $params = []): void {
$stmt = db()->prepare($sql);
$stmt->execute($params);
}
function dbInsert(string $table, array $data): int {
$cols = array_keys($data);
$sql = 'INSERT INTO ' . $table . ' (' . implode(',', $cols) . ') VALUES (' .
implode(',', array_map(fn($c) => ':' . $c, $cols)) . ')';
dbExec($sql, $data);
return (int) db()->lastInsertId();
}
function dbLastId(): int {
return (int) db()->lastInsertId();
}