Files
game1.shadow-land.de/www/public/dashboard.php

462 lines
21 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Airline Tycoon - Dashboard
* Hauptseite für eingeloggte Spieler
*/
require_once dirname(__DIR__) . '/src/bootstrap.php';
requireLogin();
$userId = Session::getUserId();
$user = $db->getUserById($userId);
if (!$user) {
Session::logout();
redirect('/login.php');
}
Session::refreshUserData($db);
// Aktualisiere User-Daten
$user = $db->getUserById($userId);
$stats = $db->getUserStats($userId);
$todayStats = $db->getTodayStats($userId);
$aircraft = $db->getUserAircraft($userId);
$routes = $db->getUserRoutes($userId);
// Level-Fortschritt berechnen
$expForNextLevel = $config['game']['level_up_threshold'] * pow($config['game']['level_multiplier'], $user['level'] - 1);
$levelProgress = ($user['experience'] / $expForNextLevel) * 100;
?>
<!DOCTYPE html>
<html lang="de" data-theme="light">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Airline Tycoon Dashboard - Verwalte deine Airline">
<meta name="csrf-token" content="<?= h(csrf_token()) ?>">
<title>Dashboard - Airline Tycoon</title>
<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 ?>dashboard.php" class="navbar-brand">✈️ <?= h($user['airline_name']) ?></a>
<button class="navbar-toggle" aria-label="Menü">☰</button>
<ul class="navbar-menu">
<li><a href="<?= BASE_PATH ?>dashboard.php" class="navbar-item active">📊 Dashboard</a></li>
<li><a href="<?= BASE_PATH ?>airports.php" class="navbar-item">🌍 Weltkarte</a></li>
<li><a href="<?= BASE_PATH ?>airports.php?action=fleet" class="navbar-item">✈️ Flotte</a></li>
<li><a href="<?= BASE_PATH ?>airports.php?action=routes" class="navbar-item">🛫 Routen</a></li>
<li>
<span class="navbar-item">
💰 <?= formatMoney($user['balance']) ?>
</span>
</li>
<li>
<a href="<?= BASE_PATH ?>logout.php" class="navbar-item">🚪 Abmelden</a>
</li>
<li>
<button class="theme-toggle" id="themeToggle" aria-label="Design wechseln">🌙</button>
</li>
</ul>
</div>
</nav>
<main class="container p-lg">
<!-- Willkommensnachricht -->
<div class="panel mb-lg">
<h1>👋 Willkommen, <?= h($user['username']) ?>!</h1>
<p class="mt-sm text-secondary">
Level <?= h($user['level']) ?> | <?= h($user['airline_name']) ?>
</p>
<!-- Level Fortschritt -->
<div class="mt-md">
<div class="d-flex flex-between mb-sm">
<span>Erfahrung</span>
<span><?= number_format($user['experience'], 0, ',', '.') ?> / <?= number_format($expForNextLevel, 0, ',', '.') ?> XP</span>
</div>
<div class="progress">
<div class="progress-bar" style="width: <?= min(100, $levelProgress) ?>%">
<?= number_format($levelProgress, 1, ',', '.') ?>%
</div>
</div>
</div>
</div>
<!-- Stats Grid -->
<div class="stats-grid mb-lg">
<div class="stat-card">
<div class="stat-icon">💰</div>
<div class="stat-value"><?= formatMoney($user['balance']) ?></div>
<div class="stat-label">Kontostand</div>
</div>
<div class="stat-card">
<div class="stat-icon">✈️</div>
<div class="stat-value"><?= count($aircraft) ?></div>
<div class="stat-label">Flugzeuge</div>
</div>
<div class="stat-card">
<div class="stat-icon">🛫</div>
<div class="stat-value"><?= count($routes) ?></div>
<div class="stat-label">Routen</div>
</div>
<div class="stat-card">
<div class="stat-icon">👥</div>
<div class="stat-value"><?= formatNumber($todayStats['total_passengers'] ?? 0) ?></div>
<div class="stat-label">Passagiere (heute)</div>
</div>
<div class="stat-card">
<div class="stat-icon">📈</div>
<div class="stat-value"><?= formatMoney($todayStats['total_profit'] ?? 0) ?></div>
<div class="stat-label">Gewinn (heute)</div>
</div>
<div class="stat-card">
<div class="stat-icon">🏆</div>
<div class="stat-value"><?= formatNumber($stats['total_flights'] ?? 0) ?></div>
<div class="stat-label">Flüge (gesamt)</div>
</div>
</div>
<!-- Quick Actions -->
<div class="panel mb-lg">
<h2 class="panel-header">⚡ Schnellaktionen</h2>
<div class="d-flex flex-wrap gap-md mt-md">
<a href="<?= BASE_PATH ?>airports.php" class="btn btn-primary">
🛫 Neue Route erstellen
</a>
<button class="btn btn-secondary" onclick="openModal('purchaseAircraftModal')">
🛒 Flugzeug kaufen
</button>
<a href="<?= BASE_PATH ?>airports.php" class="btn btn-outline">
🌍 Weltkarte ansehen
</a>
</div>
</div>
<!-- Aircraft & Routes -->
<div class="d-grid" style="grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: var(--space-lg);">
<!-- Meine Flugzeuge -->
<div class="panel">
<h2 class="panel-header">✈️ Meine Flotte</h2>
<?php if (empty($aircraft)): ?>
<div class="card text-center p-lg">
<p class="text-muted">Du hast noch keine Flugzeuge.</p>
<button class="btn btn-primary mt-md" onclick="openModal('purchaseAircraftModal')">
🛒 Jetzt Flugzeug kaufen
</button>
</div>
<?php else: ?>
<div class="table-container">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Typ</th>
<th>Zustand</th>
<th>Flüge</th>
<th>Aktion</th>
</tr>
</thead>
<tbody>
<?php foreach ($aircraft as $plane): ?>
<tr>
<td><?= h($plane['name']) ?></td>
<td><?= h($plane['aircraft_type']) ?></td>
<td>
<span class="badge <?= $plane['condition'] > 70 ? 'badge-success' : ($plane['condition'] > 30 ? 'badge-warning' : 'badge-danger') ?>">
<?= number_format($plane['condition'], 1, ',', '.') ?>%
</span>
</td>
<td><?= formatNumber($plane['flights_count']) ?></td>
<td>
<?php
// Finde eine Route für dieses Flugzeug
$hasRoute = false;
foreach ($routes as $route) {
$hasRoute = true;
break;
}
if ($hasRoute): ?>
<button class="btn btn-sm btn-success"
onclick="startFlightFromAircraft(<?= $plane['id'] ?>)">
▶️ Fliegen
</button>
<?php else: ?>
<span class="text-muted">Keine Route</span>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
<!-- Meine Routen -->
<div class="panel">
<h2 class="panel-header">🛫 Meine Routen</h2>
<?php if (empty($routes)): ?>
<div class="card text-center p-lg">
<p class="text-muted">Du hast noch keine Routen.</p>
<a href="<?= BASE_PATH ?>airports.php" class="btn btn-primary mt-md">
🛫 Jetzt Route erstellen
</a>
</div>
<?php else: ?>
<div class="table-container">
<table class="table">
<thead>
<tr>
<th>Von</th>
<th>Nach</th>
<th>Distanz</th>
<th>Nachfrage</th>
</tr>
</thead>
<tbody>
<?php foreach ($routes as $route): ?>
<tr>
<td>
<strong><?= h($route['from_iata']) ?></strong>
<br><small><?= h($route['from_city']) ?></small>
</td>
<td>
<strong><?= h($route['to_iata']) ?></strong>
<br><small><?= h($route['to_city']) ?></small>
</td>
<td><?= formatNumber($route['distance_km']) ?> km</td>
<td>
<div class="progress" style="width: 80px; height: 12px;">
<div class="progress-bar" style="width: <?= $route['demand_level'] ?>%">
<?= $route['demand_level'] ?>%
</div>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</div>
<!-- Letzte Flüge -->
<div class="panel mt-lg">
<h2 class="panel-header">📜 Letzte Flüge</h2>
<?php
$recentFlights = $db->select(
"SELECT f.*, a1.iata_code as from_iata, a2.iata_code as to_iata,
ac.name as aircraft_name, ac.aircraft_type
FROM flights f
JOIN routes r ON f.route_id = r.id
JOIN airports a1 ON r.from_airport_id = a1.id
JOIN airports a2 ON r.to_airport_id = a2.id
JOIN aircraft ac ON f.aircraft_id = ac.id
WHERE f.user_id = ?
ORDER BY f.created_at DESC
LIMIT 10",
[$userId]
);
?>
<?php if (empty($recentFlights)): ?>
<p class="text-center text-muted p-lg">Noch keine Flüge durchgeführt.</p>
<?php else: ?>
<div class="table-container">
<table class="table">
<thead>
<tr>
<th>Flug</th>
<th>Flugzeug</th>
<th>Passagiere</th>
<th>Umsatz</th>
<th>Gewinn</th>
<th>Zeit</th>
</tr>
</thead>
<tbody>
<?php foreach ($recentFlights as $flight): ?>
<tr>
<td>
<strong><?= h($flight['from_iata']) ?></strong> →
<strong><?= h($flight['to_iata']) ?></strong>
</td>
<td><?= h($flight['aircraft_name']) ?></td>
<td><?= formatNumber($flight['passengers']) ?></td>
<td><?= formatMoney($flight['revenue']) ?></td>
<td class="<?= $flight['profit'] >= 0 ? 'text-success' : 'text-danger' ?>">
<?= formatMoney($flight['profit']) ?>
</td>
<td><?= timeAgo($flight['created_at']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php endif; ?>
</div>
</main>
<!-- Flugzeug kaufen Modal -->
<div id="purchaseAircraftModal" class="modal-overlay">
<div class="modal">
<div class="modal-header">
<h3 class="modal-title">🛒 Flugzeug kaufen</h3>
<button class="modal-close" onclick="closeModal('purchaseAircraftModal')">×</button>
</div>
<div class="modal-body">
<p class="mb-md">Dein Kontostand: <strong><?= formatMoney($user['balance']) ?></strong></p>
<div class="d-grid gap-md">
<?php foreach ($config['aircraft_types'] as $type => $specs): ?>
<?php
$canAfford = $user['balance'] >= $specs['purchase_price'];
?>
<div class="card <?= $canAfford ? '' : 'text-muted' ?>"
style="<?= $canAfford ? '' : 'opacity: 0.6;' ?>">
<div class="d-flex flex-between flex-center">
<div>
<h4><?= h($type) ?></h4>
<p class="text-sm">
Sitze: <?= $specs['seat_capacity'] ?> |
Reichweite: <?= formatNumber($specs['range_km']) ?> km
</p>
</div>
<div class="text-right">
<div class="stat-value text-primary"><?= formatMoney($specs['purchase_price']) ?></div>
<?php if ($canAfford): ?>
<button class="btn btn-sm btn-success mt-sm"
onclick="purchaseAircraft('<?= h($type) ?>')">
Kaufen
</button>
<?php else: ?>
<span class="badge badge-danger">Zu teuer</span>
<?php endif; ?>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
<!-- Flug starten Modal -->
<div id="flightModal" class="modal-overlay">
<div class="modal">
<div class="modal-header">
<h3 class="modal-title">▶️ Flug starten</h3>
<button class="modal-close" onclick="closeModal('flightModal')">×</button>
</div>
<div class="modal-body">
<p>Wähle ein Flugzeug für diese Route:</p>
<div id="flightAircraftList" class="d-grid gap-md mt-md">
<!-- Wird per JavaScript gefüllt -->
</div>
</div>
</div>
</div>
<!-- Toast Container -->
<div id="toastContainer" class="toast-container"></div>
<script>
// Globale Daten für JavaScript
const GAME_DATA = {
routes: <?= json_encode($routes) ?>,
aircraft: <?= json_encode($aircraft) ?>,
userBalance: <?= $user['balance'] ?>
};
function startFlightFromAircraft(aircraftId) {
const modal = document.getElementById('flightModal');
const list = document.getElementById('flightAircraftList');
// Gefilterte Liste erstellen
const aircraftHtml = GAME_DATA.aircraft.map(ac => {
if (ac.id == aircraftId) {
return `
<div class="card">
<div class="d-flex flex-between flex-center">
<div>
<h4>${ac.name}</h4>
<p class="text-sm">${ac.aircraft_type} | Sitze: ${ac.seat_capacity}</p>
<p class="text-sm">Zustand: ${ac.condition}%</p>
</div>
<button class="btn btn-success" onclick="executeFlightForAircraft(${ac.id})">
▶️ Flug starten!
</button>
</div>
</div>
`;
}
return '';
}).join('');
list.innerHTML = aircraftHtml;
openModal('flightModal');
}
async function executeFlightForAircraft(aircraftId) {
// Einfach die erste Route verwenden für Demo
if (GAME_DATA.routes.length > 0) {
closeModal('flightModal');
try {
const result = await api.post('game.php?action=flight', {
route_id: GAME_DATA.routes[0].id,
aircraft_id: aircraftId
});
if (result.success) {
showToast(`Flug erfolgreich! +${formatMoney(result.profit)}`, 'success');
setTimeout(() => location.reload(), 1500);
} else {
showToast(result.error || 'Flug fehlgeschlagen', 'error');
}
} catch (error) {
showToast('Netzwerkfehler', 'error');
}
} else {
showToast('Keine Route verfügbar!', 'warning');
}
}
function purchaseAircraft(type) {
api.post('game.php?action=purchase', { aircraft_type: type })
.then(result => {
if (result.success) {
showToast(`${type} gekauft für ${formatMoney(result.price)}`, 'success');
closeModal('purchaseAircraftModal');
setTimeout(() => location.reload(), 1500);
} else {
showToast(result.error || 'Kauf fehlgeschlagen', 'error');
}
});
}
function updateDashboard() {
// Dashboard aktualisieren (wird bei Bedarf erweitert)
location.reload();
}
</script>
<script src="<?= BASE_PATH ?>assets/js/main.js"></script>
</body>
</html>