diff --git a/database/schema.sql b/database/schema.sql
index 4bfb6e9..c99314b 100644
--- a/database/schema.sql
+++ b/database/schema.sql
@@ -8,7 +8,7 @@ CREATE TABLE IF NOT EXISTS users (
email VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
airline_name VARCHAR(100) DEFAULT '',
- balance DECIMAL(15,2) DEFAULT 500000.00,
+ balance DECIMAL(15,2) DEFAULT 10000000.00,
level INTEGER DEFAULT 1,
experience INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
@@ -92,10 +92,55 @@ CREATE TABLE IF NOT EXISTS daily_stats (
total_revenue DECIMAL(15,2) DEFAULT 0.00,
total_profit DECIMAL(15,2) DEFAULT 0.00,
fuel_cost DECIMAL(15,2) DEFAULT 0.00,
+ maintenance_cost DECIMAL(15,2) DEFAULT 0.00,
UNIQUE(user_id, date),
FOREIGN KEY (user_id) REFERENCES users(id)
);
+-- Kredite
+CREATE TABLE IF NOT EXISTS loans (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ user_id INTEGER NOT NULL,
+ principal DECIMAL(15,2) NOT NULL,
+ current_amount DECIMAL(15,2) NOT NULL,
+ interest_rate DECIMAL(5,4) DEFAULT 0.02,
+ daily_interest DECIMAL(15,2) DEFAULT 0.00,
+ days_outstanding INTEGER DEFAULT 0,
+ status VARCHAR(20) DEFAULT 'active',
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ due_date DATE,
+ FOREIGN KEY (user_id) REFERENCES users(id)
+);
+
+-- Transaktionen (alle Buchungen)
+CREATE TABLE IF NOT EXISTS transactions (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ user_id INTEGER NOT NULL,
+ type VARCHAR(50) NOT NULL,
+ category VARCHAR(50) NOT NULL,
+ amount DECIMAL(15,2) NOT NULL,
+ balance_after DECIMAL(15,2) NOT NULL,
+ description TEXT DEFAULT '',
+ reference_id INTEGER,
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (user_id) REFERENCES users(id)
+);
+
+-- Wartungshistorie
+CREATE TABLE IF NOT EXISTS maintenance_history (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ aircraft_id INTEGER NOT NULL,
+ user_id INTEGER NOT NULL,
+ maintenance_type VARCHAR(50) DEFAULT 'scheduled',
+ cost DECIMAL(15,2) NOT NULL,
+ condition_before DECIMAL(5,2) DEFAULT 100.00,
+ condition_after DECIMAL(5,2) DEFAULT 100.00,
+ notes TEXT DEFAULT '',
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+ FOREIGN KEY (aircraft_id) REFERENCES aircraft(id),
+ FOREIGN KEY (user_id) REFERENCES users(id)
+);
+
-- Events (Werbeaktionen, Wettbewerbe)
CREATE TABLE IF NOT EXISTS events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -114,3 +159,27 @@ CREATE INDEX IF NOT EXISTS idx_flights_user ON flights(user_id);
CREATE INDEX IF NOT EXISTS idx_flights_route ON flights(route_id);
CREATE INDEX IF NOT EXISTS idx_aircraft_user ON aircraft(user_id);
CREATE INDEX IF NOT EXISTS idx_airports_iata ON airports(iata_code);
+
+-- Flugzeugtypen (Referenztabelle)
+CREATE TABLE IF NOT EXISTS aircraft_types (
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
+ code VARCHAR(20) UNIQUE NOT NULL,
+ name VARCHAR(100) NOT NULL,
+ manufacturer VARCHAR(50) NOT NULL,
+ range_km INTEGER NOT NULL,
+ capacity INTEGER NOT NULL,
+ buy_price DECIMAL(15,2) NOT NULL,
+ crew_cost_per_tick DECIMAL(10,2) NOT NULL,
+ fuel_per_km DECIMAL(6,4) DEFAULT 0.1500,
+ maintenance_interval INTEGER DEFAULT 50,
+ description TEXT DEFAULT '',
+ created_at DATETIME DEFAULT CURRENT_TIMESTAMP
+);
+
+INSERT OR IGNORE INTO aircraft_types (code, name, manufacturer, range_km, capacity, buy_price, crew_cost_per_tick, fuel_per_km, maintenance_interval, description) VALUES
+('dash8-100', 'Dash 8-100', 'Bombardier', 1500, 37, 500000.00, 200.00, 0.12, 50, 'Kleiner RegionalturboProp mit 37 Sitzen'),
+('atr72-500', 'ATR 72-500', 'ATR', 1650, 70, 1500000.00, 300.00, 0.15, 50, 'Mittlerer RegionalturboProp mit 70 Sitzen'),
+('a320-200', 'A320-200', 'Airbus', 5700, 150, 8000000.00, 600.00, 0.25, 50, 'Kurz-/Mittelstrecken-Jet mit 150 Sitzen'),
+('b737-800', 'B737-800', 'Boeing', 5700, 162, 9500000.00, 650.00, 0.26, 50, 'Kurz-/Mittelstrecken-Jet mit 162 Sitzen'),
+('b777-200', 'B777-200', 'Boeing', 12000, 300, 35000000.00, 1200.00, 0.55, 50, 'Langstrecken-Widebody mit 300 Sitzen'),
+('a380-800', 'A380-800', 'Airbus', 15200, 525, 85000000.00, 2000.00, 0.80, 50, 'Doppelstöckiger Langstrecken-Airliner mit 525 Sitzen');
diff --git a/www/public/aircraft.php b/www/public/aircraft.php
new file mode 100644
index 0000000..5d7521e
--- /dev/null
+++ b/www/public/aircraft.php
@@ -0,0 +1,371 @@
+getUserById($userId);
+$aircraft = $db->getUserAircraft($userId);
+$config = $db->getConfig();
+
+// Wartungsstatus prüfen
+$maintenanceDue = $db->checkMaintenanceDue($userId);
+?>
+
+
+
+
+
+ Flotte - = htmlspecialchars($user['airline_name']) ?> - = $config['app']['name'] ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
🛫 Deine Flotte
+
Verwalte deine Flugzeuge, prüfe den Zustand und buche Wartungen
+
+
+
+
+
+
+
⚠️
+
+
Wartung fällig!
+
Bei = count($maintenanceDue) ?> Flugzeug(en) ist die Wartung überfällig.
+
+
+
+
+
+
+
+
✈️
+
= count($aircraft) ?>
+
Flugzeuge
+
+
+
💺
+
= number_format(array_sum(array_column($aircraft, 'seat_capacity')), 0, ',', '.') ?>
+
Gesamtkapazität
+
+
+
🛡️
+
= count($maintenanceDue) ?>
+
Wartung fällig
+
+
+
📅
+
= $config['game']['maintenance_interval'] ?>
+
Flüge bis Wartung
+
+
+
+
+
+
+
+
+
+
✈️
+
Keine Flugzeuge vorhanden
+
Du besitzt noch keine Flugzeuge. Kaufe dein erstes Flugzeug im Markt!
+
Zum Markt
+
+
+
+
+
+
+ | Name |
+ Typ |
+ Zustand |
+ Flüge |
+ Nächste Wartung |
+ Reichweite |
+ Kapazität |
+ Aktionen |
+
+
+
+
+ = 80 ? 'text-success' : ($plane['condition'] >= 50 ? 'text-warning' : 'text-danger');
+ $maintenanceProgress = min(100, ($plane['flights_count'] / $config['game']['maintenance_interval']) * 100);
+ $needsMaintenance = $plane['flights_count'] >= $config['game']['maintenance_interval'];
+ ?>
+
+ |
+ = htmlspecialchars($plane['name']) ?>
+ |
+
+ = htmlspecialchars($plane['aircraft_type']) ?>
+ |
+
+
+
+ = number_format($plane['condition'], 1, ',', '.') ?>%
+
+
+
+ |
+ = number_format($plane['flights_count'], 0, ',', '.') ?> |
+
+
+ ⚠️ Jetzt!
+
+
+ = number_format($config['game']['maintenance_interval'] - $plane['flights_count'], 0, ',', '.') ?> Flüge
+
+
+ |
+ = number_format($plane['range_km'], 0, ',', '.') ?> km |
+ = number_format($plane['seat_capacity'], 0, ',', '.') ?> Pax |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+ 📊 Flugzeugtypen
+
+ $specs): ?>
+
+
= htmlspecialchars($type) ?>
+
+
+ Preis:
+ = number_format($specs['purchase_price'], 0, ',', '.') ?> €
+
+
+ Reichweite:
+ = number_format($specs['range_km'], 0, ',', '.') ?> km
+
+
+ Kapazität:
+ = $specs['seat_capacity'] ?> Pax
+
+
+ Crew-Kosten:
+ = $specs['crew_cost_per_tick'] ?? 500 ?> €/Tick
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Flugzeug:
+
Zustand:
+
Geschätzte Kosten:
+
+
+
Nach der Wartung wird der Zustand auf 100% zurückgesetzt und der Flugzähler zurückgesetzt.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/www/public/api/game.php b/www/public/api/game.php
index e05b3b1..5660caf 100644
--- a/www/public/api/game.php
+++ b/www/public/api/game.php
@@ -49,6 +49,37 @@ switch ($action) {
handleLeaderboard();
break;
+ // NEU: Kredite
+ case 'take_loan':
+ handleTakeLoan();
+ break;
+
+ case 'repay_loan':
+ handleRepayLoan();
+ break;
+
+ case 'loans':
+ handleLoans();
+ break;
+
+ // NEU: Wartung
+ case 'maintenance':
+ handleMaintenance();
+ break;
+
+ case 'aircraft_details':
+ handleAircraftDetails();
+ break;
+
+ // NEU: Finanzen
+ case 'transactions':
+ handleTransactions();
+ break;
+
+ case 'finance_summary':
+ handleFinanceSummary();
+ break;
+
default:
jsonResponse(['error' => 'Unbekannte Aktion'], 400);
}
@@ -329,3 +360,216 @@ function handleLeaderboard() {
'count' => count($leaders)
]);
}
+
+// ============================================
+// KREDIT HANDLERS
+// ============================================
+function handleTakeLoan() {
+ global $db, $config;
+
+ $userId = Session::getUserId();
+
+ // CSRF Check
+ if (!Session::validateCsrfToken($_POST['csrf_token'] ?? '')) {
+ jsonResponse(['error' => 'Ungültiges CSRF-Token'], 403);
+ }
+
+ $amount = (float) ($_POST['amount'] ?? 0);
+
+ if ($amount <= 0) {
+ jsonResponse(['error' => 'Ungültiger Betrag'], 400);
+ }
+
+ try {
+ $loanId = $db->createLoan($userId, $amount);
+
+ // Update user balance
+ $user = $db->getUserById($userId);
+
+ jsonResponse([
+ 'success' => true,
+ 'message' => 'Kredit über ' . number_format($amount, 0, ',', '.') . ' € aufgenommen!',
+ 'loan_id' => $loanId,
+ 'amount' => $amount,
+ 'new_balance' => $user['balance'] + $amount,
+ 'interest_rate' => $config['loans']['interest_rate'],
+ 'daily_interest' => $amount * $config['loans']['interest_rate']
+ ]);
+ } catch (Exception $e) {
+ jsonResponse(['error' => $e->getMessage()], 400);
+ }
+}
+
+function handleRepayLoan() {
+ global $db;
+
+ $userId = Session::getUserId();
+
+ // CSRF Check
+ if (!Session::validateCsrfToken($_POST['csrf_token'] ?? '')) {
+ jsonResponse(['error' => 'Ungültiges CSRF-Token'], 403);
+ }
+
+ $loanId = (int) ($_POST['loan_id'] ?? 0);
+ $amount = (float) ($_POST['amount'] ?? 0);
+
+ if ($loanId <= 0 || $amount <= 0) {
+ jsonResponse(['error' => 'Ungültige Parameter'], 400);
+ }
+
+ try {
+ $result = $db->repayLoan($userId, $loanId, $amount);
+
+ jsonResponse([
+ 'success' => true,
+ 'message' => number_format($result['repaid'], 2, ',', '.') . ' € zurückgezahlt!',
+ 'repaid' => $result['repaid'],
+ 'remaining' => $result['remaining'],
+ 'new_balance' => $result['new_balance']
+ ]);
+ } catch (Exception $e) {
+ jsonResponse(['error' => $e->getMessage()], 400);
+ }
+}
+
+function handleLoans() {
+ global $db;
+
+ $userId = Session::getUserId();
+ $loans = $db->getUserLoans($userId);
+ $totalDebt = $db->getTotalDebt($userId);
+ $totalDebtWithInterest = $db->getTotalDebtWithInterest($userId);
+
+ jsonResponse([
+ 'success' => true,
+ 'loans' => $loans,
+ 'total_debt' => $totalDebt,
+ 'total_debt_with_interest' => $totalDebtWithInterest,
+ 'count' => count($loans)
+ ]);
+}
+
+// ============================================
+// WARTUNG HANDLERS
+// ============================================
+function handleMaintenance() {
+ global $db, $config;
+
+ $userId = Session::getUserId();
+
+ // CSRF Check
+ if (!Session::validateCsrfToken($_POST['csrf_token'] ?? '')) {
+ jsonResponse(['error' => 'Ungültiges CSRF-Token'], 403);
+ }
+
+ $aircraftId = (int) ($_POST['aircraft_id'] ?? 0);
+
+ if ($aircraftId <= 0) {
+ jsonResponse(['error' => 'Flugzeug-ID erforderlich'], 400);
+ }
+
+ try {
+ $result = $db->performMaintenance($userId, $aircraftId);
+
+ jsonResponse([
+ 'success' => true,
+ 'message' => 'Wartung erfolgreich durchgeführt!',
+ 'cost' => $result['cost'],
+ 'condition_before' => $result['condition_before'],
+ 'condition_after' => $result['condition_after'],
+ 'new_balance' => $result['new_balance']
+ ]);
+ } catch (Exception $e) {
+ jsonResponse(['error' => $e->getMessage()], 400);
+ }
+}
+
+function handleAircraftDetails() {
+ global $db;
+
+ $userId = Session::getUserId();
+ $aircraftId = (int) ($_GET['id'] ?? 0);
+
+ if ($aircraftId <= 0) {
+ jsonResponse(['error' => 'Flugzeug-ID erforderlich'], 400);
+ }
+
+ $aircraft = $db->selectOne(
+ "SELECT * FROM aircraft WHERE id = ? AND user_id = ?",
+ [$aircraftId, $userId]
+ );
+
+ if (!$aircraft) {
+ jsonResponse(['error' => 'Flugzeug nicht gefunden'], 404);
+ }
+
+ // Get maintenance history for this aircraft
+ $maintenanceHistory = $db->select(
+ "SELECT * FROM maintenance_history WHERE aircraft_id = ? ORDER BY created_at DESC LIMIT 10",
+ [$aircraftId]
+ );
+
+ // Get aircraft config for maintenance cost estimate
+ $config = $db->getConfig();
+ $aircraftConfig = $config['aircraft_types'][$aircraft['aircraft_type']] ?? [];
+ $maintenanceCost = $aircraftConfig['maintenance_base_cost'] ?? 50000;
+
+ // Adjust for condition
+ $conditionLoss = 100 - $aircraft['condition'];
+ $estimatedCost = $maintenanceCost + ($conditionLoss * 0.01 * $maintenanceCost);
+
+ jsonResponse([
+ 'success' => true,
+ 'aircraft' => $aircraft,
+ 'maintenance_history' => $maintenanceHistory,
+ 'maintenance_cost' => $estimatedCost,
+ 'maintenance_interval' => $config['game']['maintenance_interval']
+ ]);
+}
+
+// ============================================
+// FINANZEN HANDLERS
+// ============================================
+function handleTransactions() {
+ global $db;
+
+ $userId = Session::getUserId();
+ $limit = min(100, (int) ($_GET['limit'] ?? 50));
+
+ $transactions = $db->getUserTransactions($userId, $limit);
+
+ jsonResponse([
+ 'success' => true,
+ 'transactions' => $transactions,
+ 'count' => count($transactions)
+ ]);
+}
+
+function handleFinanceSummary() {
+ global $db;
+
+ $userId = Session::getUserId();
+ $user = $db->getUserById($userId);
+
+ $today = date('Y-m-d');
+ $weekAgo = date('Y-m-d', strtotime('-7 days'));
+ $monthAgo = date('Y-m-d', strtotime('-30 days'));
+
+ $todayStats = $db->getTransactionSummary($userId, $today, $today);
+ $weekStats = $db->getTransactionSummary($userId, $weekAgo, $today);
+ $monthStats = $db->getTransactionSummary($userId, $monthAgo, $today);
+
+ $loans = $db->getUserLoans($userId);
+ $totalDebt = $db->getTotalDebtWithInterest($userId);
+
+ jsonResponse([
+ 'success' => true,
+ 'balance' => $user['balance'],
+ 'net_worth' => $user['balance'] - $totalDebt,
+ 'total_debt' => $totalDebt,
+ 'today' => $todayStats,
+ 'week' => $weekStats,
+ 'month' => $monthStats,
+ 'active_loans' => count($loans)
+ ]);
+}
diff --git a/www/public/assets/css/style.css b/www/public/assets/css/style.css
index 676b232..06e2c8c 100644
--- a/www/public/assets/css/style.css
+++ b/www/public/assets/css/style.css
@@ -1048,3 +1048,373 @@ a:hover {
height: 48px;
}
}
+
+/* ============================================
+ PHASE 2: AIRCRAFT, MARKET & FINANCES STYLES
+ ============================================ */
+
+/* Aircraft Market Grid */
+.aircraft-market-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+ gap: var(--space-lg);
+}
+
+.market-aircraft-card {
+ background: var(--bg-secondary);
+ border: 3px solid var(--text-primary);
+ border-radius: var(--radius-lg);
+ padding: var(--space-lg);
+ box-shadow: var(--shadow-md);
+ transition: transform var(--transition-fast);
+}
+
+.market-aircraft-card:hover {
+ transform: translateY(-4px);
+ box-shadow: var(--shadow-lg);
+}
+
+.market-aircraft-card.disabled {
+ opacity: 0.6;
+ filter: grayscale(30%);
+}
+
+.market-aircraft-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: var(--space-md);
+ padding-bottom: var(--space-md);
+ border-bottom: 2px dashed var(--border-color);
+}
+
+.market-aircraft-name {
+ font-family: var(--font-primary);
+ font-size: 1.25rem;
+ color: var(--text-primary);
+}
+
+.market-aircraft-price {
+ font-family: var(--font-primary);
+ font-size: 1.5rem;
+ font-weight: bold;
+}
+
+.market-aircraft-specs {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-sm);
+}
+
+.spec-row {
+ display: flex;
+ justify-content: space-between;
+ padding: var(--space-xs) 0;
+}
+
+.spec-label {
+ color: var(--text-secondary);
+ font-size: 0.875rem;
+}
+
+.spec-value {
+ font-weight: 600;
+ color: var(--text-primary);
+}
+
+.cannot-afford {
+ text-align: center;
+ padding: var(--space-md);
+ background: var(--bg-tertiary);
+ border-radius: var(--radius-md);
+}
+
+/* Aircraft Types Grid */
+.aircraft-types-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
+ gap: var(--space-md);
+}
+
+.aircraft-type-card {
+ background: var(--bg-tertiary);
+ border: 2px solid var(--border-color);
+ border-radius: var(--radius-md);
+ padding: var(--space-md);
+}
+
+.aircraft-type-name {
+ font-family: var(--font-primary);
+ font-size: 1.1rem;
+ margin-bottom: var(--space-sm);
+ padding-bottom: var(--space-sm);
+ border-bottom: 1px dashed var(--border-color);
+}
+
+.aircraft-type-stats {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-xs);
+}
+
+.aircraft-type-stat {
+ display: flex;
+ justify-content: space-between;
+ font-size: 0.875rem;
+}
+
+/* Balance Banner */
+.balance-banner {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background: var(--accent-gradient);
+ color: white;
+ padding: var(--space-lg);
+}
+
+.balance-info {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-xs);
+}
+
+.balance-label {
+ font-size: 0.875rem;
+ opacity: 0.9;
+}
+
+.balance-value {
+ font-family: var(--font-primary);
+ font-size: 2rem;
+ font-weight: bold;
+}
+
+/* Period Stats */
+.period-stats {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+ gap: var(--space-md);
+}
+
+.period-card {
+ background: var(--bg-tertiary);
+ border: 2px solid var(--border-color);
+ border-radius: var(--radius-md);
+ padding: var(--space-md);
+}
+
+.period-card h3 {
+ font-family: var(--font-primary);
+ font-size: 1rem;
+ margin-bottom: var(--space-md);
+ padding-bottom: var(--space-sm);
+ border-bottom: 1px solid var(--border-color);
+}
+
+.period-amounts {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-sm);
+}
+
+.amount-row {
+ display: flex;
+ justify-content: space-between;
+ font-size: 0.875rem;
+}
+
+.amount-row.total {
+ font-weight: bold;
+ padding-top: var(--space-sm);
+ border-top: 1px dashed var(--border-color);
+ margin-top: var(--space-sm);
+}
+
+/* Loan Info */
+.loan-info {
+ background: var(--info-bg);
+ border: 2px solid var(--accent-color);
+ border-radius: var(--radius-md);
+ padding: var(--space-md);
+}
+
+.loan-info h3 {
+ font-family: var(--font-primary);
+ margin-bottom: var(--space-md);
+}
+
+.loan-info ul {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.loan-info li {
+ padding: var(--space-xs) 0;
+ border-bottom: 1px dashed var(--border-color);
+}
+
+.loan-info li:last-child {
+ border-bottom: none;
+}
+
+/* Aircraft Detail Modal */
+.aircraft-detail-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: var(--space-lg);
+ padding-bottom: var(--space-md);
+ border-bottom: 2px dashed var(--border-color);
+}
+
+.aircraft-detail-grid {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr);
+ gap: var(--space-md);
+}
+
+.detail-item {
+ display: flex;
+ flex-direction: column;
+ gap: var(--space-xs);
+}
+
+.detail-label {
+ font-size: 0.75rem;
+ color: var(--text-secondary);
+ text-transform: uppercase;
+}
+
+.detail-value {
+ font-weight: 600;
+ font-size: 1rem;
+}
+
+.maintenance-history {
+ list-style: none;
+ padding: 0;
+ margin: var(--space-md) 0 0 0;
+}
+
+.maintenance-history li {
+ padding: var(--space-sm);
+ background: var(--bg-tertiary);
+ border-radius: var(--radius-sm);
+ margin-bottom: var(--space-sm);
+ font-size: 0.875rem;
+}
+
+/* Info Grid */
+.info-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+ gap: var(--space-lg);
+}
+
+.info-card {
+ background: var(--bg-secondary);
+ border: 2px solid var(--border-color);
+ border-radius: var(--radius-md);
+ padding: var(--space-md);
+}
+
+.info-card h3 {
+ font-family: var(--font-primary);
+ font-size: 1rem;
+ margin-bottom: var(--space-md);
+}
+
+.info-list {
+ list-style: disc;
+ padding-left: var(--space-lg);
+}
+
+.info-list li {
+ padding: var(--space-xs) 0;
+ font-size: 0.875rem;
+ color: var(--text-secondary);
+}
+
+/* Maintenance Progress */
+.maintenance-progress {
+ display: flex;
+ align-items: center;
+ gap: var(--space-sm);
+}
+
+.maintenance-bar {
+ flex: 1;
+ height: 8px;
+ background: var(--bg-tertiary);
+ border-radius: 4px;
+ overflow: hidden;
+}
+
+.maintenance-bar-fill {
+ height: 100%;
+ background: var(--comic-green);
+ transition: width var(--transition-normal);
+}
+
+.maintenance-bar-fill.warning {
+ background: var(--comic-orange);
+}
+
+.maintenance-bar-fill.danger {
+ background: var(--comic-red);
+}
+
+/* D-flex utilities */
+.d-flex {
+ display: flex;
+}
+
+.flex-col {
+ flex-direction: column;
+}
+
+.align-start {
+ align-items: flex-start;
+}
+
+.gap-sm {
+ gap: var(--space-sm);
+}
+
+.gap-md {
+ gap: var(--space-md);
+}
+
+.w-100 {
+ width: 100%;
+}
+
+/* Responsive table container */
+.table-container {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+}
+
+/* Aircraft condition colors */
+.condition-excellent {
+ color: var(--comic-green);
+}
+
+.condition-good {
+ color: var(--accent-color);
+}
+
+.condition-warning {
+ color: var(--comic-orange);
+}
+
+.condition-danger {
+ color: var(--comic-red);
+}
+
+/* Aircraft table */
+.aircraft-table td {
+ vertical-align: middle;
+}
diff --git a/www/public/dashboard.php b/www/public/dashboard.php
index 6de0944..7f69b59 100644
--- a/www/public/dashboard.php
+++ b/www/public/dashboard.php
@@ -24,6 +24,10 @@ $todayStats = $db->getTodayStats($userId);
$aircraft = $db->getUserAircraft($userId);
$routes = $db->getUserRoutes($userId);
+// Kredite und Finanzen
+$totalDebt = $db->getTotalDebtWithInterest($userId);
+$maintenanceDue = $db->checkMaintenanceDue($userId);
+
// Level-Fortschritt berechnen
$expForNextLevel = $config['game']['level_up_threshold'] * pow($config['game']['level_multiplier'], $user['level'] - 1);
$levelProgress = ($user['experience'] / $expForNextLevel) * 100;
@@ -47,9 +51,10 @@ $levelProgress = ($user['experience'] / $expForNextLevel) * 100;