feat(phase1): complete base structure - landing page, auth, dashboard, airports, API, DB schema, 60 airports CSV

This commit is contained in:
2026-04-24 15:53:59 +02:00
parent 2960bd4c2f
commit ab5f97acbf
18 changed files with 4926 additions and 0 deletions

134
www/public/login.php Normal file
View File

@@ -0,0 +1,134 @@
<?php
/**
* Airline Tycoon - Login Page
*/
require_once dirname(__DIR__) . '/src/bootstrap.php';
$error = '';
$success = Session::flash('success');
// Login verarbeiten
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? '');
$password = $_POST['password'] ?? '';
$remember = isset($_POST['remember']);
if (!validate_csrf($_POST['csrf_token'] ?? '')) {
$error = 'Ungültige Anfrage. Bitte versuche es erneut.';
} elseif (empty($username) || empty($password)) {
$error = 'Bitte fülle alle Felder aus.';
} else {
$user = $db->getUserByUsername($username);
if ($user && password_verify($password, $user['password_hash'])) {
Session::login($user);
// Redirect merken
$redirect = $_GET['redirect'] ?? '/dashboard.php';
redirect($redirect);
} else {
$error = 'Benutzername oder Passwort falsch.';
}
}
}
// Redirect wenn bereits eingeloggt
if (Session::isLoggedIn()) {
redirect('/dashboard.php');
}
?>
<!DOCTYPE html>
<html lang="de" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Anmelden - Airline Tycoon</title>
<meta name="csrf-token" content="<?= h(csrf_token()) ?>">
<link rel="stylesheet" href="<?= BASE_PATH ?>assets/css/style.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>✈️</text></svg>">
</head>
<body>
<!-- Navigation -->
<nav class="navbar">
<div class="navbar-container">
<a href="<?= BASE_PATH ?>" class="navbar-brand">✈️ Airline Tycoon</a>
<ul class="navbar-menu">
<li><a href="<?= BASE_PATH ?>" class="navbar-item">Zurück zur Startseite</a></li>
</ul>
</div>
</nav>
<main class="container p-lg">
<div class="panel" style="max-width: 450px; margin: 0 auto;">
<h1 class="text-center mb-lg">🔐 Anmelden</h1>
<?php if ($success): ?>
<div class="card mb-md" style="background: rgba(107, 203, 119, 0.2); border-color: var(--comic-green);">
<p class="text-success">✅ <?= h($success) ?></p>
</div>
<?php endif; ?>
<?php if ($error): ?>
<div class="card mb-md" style="background: rgba(255, 107, 107, 0.2); border-color: var(--comic-red);">
<p class="text-danger">❌ <?= h($error) ?></p>
</div>
<?php endif; ?>
<form method="POST" action="<?= BASE_PATH ?>login.php" data-ajax>
<input type="hidden" name="csrf_token" value="<?= h(csrf_token()) ?>">
<div class="form-group">
<label class="form-label" for="username">Benutzername</label>
<input
type="text"
id="username"
name="username"
class="form-input"
placeholder="Dein Benutzername"
required
autocomplete="username"
value="<?= h($_POST['username'] ?? '') ?>"
>
</div>
<div class="form-group">
<label class="form-label" for="password">Passwort</label>
<input
type="password"
id="password"
name="password"
class="form-input"
placeholder="Dein Passwort"
required
autocomplete="current-password"
>
</div>
<div class="form-group">
<label class="d-flex flex-center gap-sm">
<input type="checkbox" name="remember" id="remember">
<span>Angemeldet bleiben</span>
</label>
</div>
<button type="submit" class="btn btn-primary btn-block btn-lg">
🚀 Anmelden
</button>
</form>
<div class="text-center mt-lg">
<p>Noch kein Konto?</p>
<a href="<?= BASE_PATH ?>register.php" class="btn btn-secondary">
Jetzt registrieren
</a>
</div>
</div>
</main>
<!-- Toast Container -->
<div id="toastContainer" class="toast-container"></div>
<script src="<?= BASE_PATH ?>assets/js/main.js"></script>
</body>
</html>