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
+124
View File
@@ -0,0 +1,124 @@
<?php
require_once __DIR__ . '/config.php';
startSession();
// Einladungs-Token prüfen
$inviteToken = $_GET['invite'] ?? '';
$inviteTrip = null;
if ($inviteToken) {
$invite = dbOne('SELECT * FROM reise_einladungen WHERE token = ? AND used_at IS NULL', [$inviteToken]);
if ($invite) $inviteTrip = getTrip($invite['trip_id']);
}
// Mock-Login verarbeiten
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['mock_login'])) {
$name = trim($_POST['name'] ?? '');
$email = strtolower(trim($_POST['email'] ?? ''));
if ($name && filter_var($email, FILTER_VALIDATE_EMAIL)) {
$user = dbOne('SELECT * FROM users WHERE email = ?', [$email]);
if (!$user) {
$farben = ['#2563eb','#7c3aed','#db2777','#059669','#d97706','#dc2626'];
$farbe = $farben[array_rand($farben)];
$id = dbInsert('users', ['email' => $email, 'name' => $name, 'farbe' => $farbe]);
$user = dbOne('SELECT * FROM users WHERE id = ?', [$id]);
}
loginUser($user);
// Einladung einlösen
if ($inviteToken && $invite) {
$exists = dbOne('SELECT 1 FROM reise_zugriff WHERE trip_id = ? AND user_id = ?', [$invite['trip_id'], $user['id']]);
if (!$exists) {
dbInsert('reise_zugriff', ['trip_id' => $invite['trip_id'], 'user_id' => $user['id'], 'access' => $invite['access'], 'invited_by' => $invite['invited_by']]);
}
dbExec('UPDATE reise_einladungen SET used_at = ? WHERE token = ?', [time(), $inviteToken]);
header('Location: /Develop/PlanerGoogel/ablauf.php?trip=' . urlencode($invite['trip_id'])); exit;
}
header('Location: /Develop/PlanerGoogel/'); exit;
}
$error = 'Bitte Name und gültige E-Mail-Adresse eingeben.';
}
if (!empty($_SESSION['user_id'])) {
header('Location: /Develop/PlanerGoogel/'); exit;
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Anmelden <?= SITE_TITLE ?></title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Playfair+Display:ital,wght@0,400;1,400&display=swap" rel="stylesheet">
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0;}
:root{--blue:#2563eb;--blue-dk:#1d4ed8;--bg:#f0f6ff;--white:#fff;--border:#bfdbfe;--ink:#1e293b;--muted:#64748b;--radius:12px;}
body{background:var(--bg);font-family:'Inter',sans-serif;color:var(--ink);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:20px;}
.card{background:var(--white);border-radius:var(--radius);box-shadow:0 8px 40px rgba(37,99,235,.13);padding:40px 36px;width:100%;max-width:420px;}
.logo{text-align:center;margin-bottom:28px;}
.logo-icon{font-size:2.5rem;display:block;margin-bottom:8px;}
.logo-title{font-family:'Playfair Display',serif;font-size:1.6rem;color:var(--blue-dk);}
.logo-sub{font-size:.8rem;color:var(--muted);margin-top:4px;}
.invite-box{background:#f0fdf4;border:1.5px solid #86efac;border-radius:10px;padding:12px 16px;margin-bottom:20px;font-size:.83rem;color:#15803d;}
.invite-box strong{display:block;margin-bottom:2px;}
/* Google Button (Platzhalter) */
.btn-google{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:11px 16px;background:#fff;border:1.5px solid #dadce0;border-radius:8px;font-family:'Inter',sans-serif;font-size:.9rem;font-weight:500;color:#3c4043;cursor:not-allowed;opacity:.6;position:relative;}
.btn-google svg{width:18px;height:18px;flex-shrink:0;}
.btn-google-badge{position:absolute;right:12px;font-size:.65rem;background:#fef9c3;color:#854d0e;border-radius:4px;padding:2px 6px;border:1px solid #fde68a;}
.divider{display:flex;align-items:center;gap:10px;margin:20px 0;color:var(--muted);font-size:.78rem;}
.divider::before,.divider::after{content:'';flex:1;height:1px;background:var(--border);}
label{display:block;font-size:.78rem;font-weight:500;color:var(--muted);margin-bottom:4px;margin-top:14px;}
label:first-of-type{margin-top:0;}
input{width:100%;padding:10px 13px;border:1.5px solid var(--border);border-radius:8px;font-family:'Inter',sans-serif;font-size:.88rem;color:var(--ink);outline:none;transition:border-color .18s;}
input:focus{border-color:var(--blue);box-shadow:0 0 0 3px rgba(37,99,235,.1);}
.btn-login{width:100%;margin-top:18px;padding:11px;background:var(--blue);color:#fff;border:none;border-radius:8px;font-family:'Inter',sans-serif;font-size:.9rem;font-weight:500;cursor:pointer;transition:background .18s;}
.btn-login:hover{background:var(--blue-dk);}
.error{background:#fef2f2;border:1.5px solid #fca5a5;border-radius:8px;padding:10px 14px;font-size:.82rem;color:#dc2626;margin-bottom:16px;}
.note{font-size:.73rem;color:var(--muted);text-align:center;margin-top:16px;line-height:1.5;}
</style>
</head>
<body>
<div class="card">
<div class="logo">
<span class="logo-icon"><?= SITE_ICON ?></span>
<div class="logo-title"><?= SITE_TITLE ?></div>
<div class="logo-sub">Reisen planen, teilen und erleben</div>
</div>
<?php if ($inviteTrip): ?>
<div class="invite-box">
<strong>Du wurdest eingeladen!</strong>
Melde dich an, um der Reise <em><?= h($inviteTrip['name']) ?></em> beizutreten.
</div>
<?php endif; ?>
<!-- Google Login (kommt später) -->
<button class="btn-google" disabled title="Kommt bald">
<svg viewBox="0 0 48 48"><path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"/><path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"/><path fill="#FBBC05" d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"/><path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.18 1.48-4.97 2.31-8.16 2.31-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"/><path fill="none" d="M0 0h48v48H0z"/></svg>
Mit Google anmelden
<span class="btn-google-badge">Kommt bald</span>
</button>
<div class="divider">oder zum Testen</div>
<?php if (!empty($error)): ?>
<div class="error"><?= h($error) ?></div>
<?php endif; ?>
<form method="POST">
<?php if ($inviteToken): ?><input type="hidden" name="invite" value="<?= h($inviteToken) ?>"><?php endif; ?>
<label for="name">Dein Name</label>
<input type="text" id="name" name="name" placeholder="z.B. Jason" required value="<?= h($_POST['name'] ?? '') ?>">
<label for="email">E-Mail-Adresse</label>
<input type="email" id="email" name="email" placeholder="deine@email.de" required value="<?= h($_POST['email'] ?? '') ?>">
<button type="submit" name="mock_login" class="btn-login">Anmelden / Registrieren</button>
</form>
<p class="note">Diese Anmeldung ist nur zum Testen.<br>Google Login wird später aktiviert.</p>
</div>
</body>
</html>