mirror of
https://github.com/ManfredAabye/OpenSim-Viewer-Webinterface.git
synced 2026-08-14 00:48:10 +00:00
21102025
This commit is contained in:
+379
@@ -0,0 +1,379 @@
|
||||
<?php
|
||||
$title = "Klassifizierte Anzeigen";
|
||||
include_once "include/config.php";
|
||||
include_once "include/" . HEADER_FILE;
|
||||
|
||||
// Datenbankverbindung
|
||||
$con = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
|
||||
if (!$con) {
|
||||
die("Datenbankverbindung fehlgeschlagen: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Funktionen für klassifizierte Anzeigen
|
||||
function getAllClassifieds($con, $category = null, $search = null) {
|
||||
$sql = "SELECT c.*, u.FirstName, u.LastName, r.regionName
|
||||
FROM classifieds c
|
||||
LEFT JOIN UserAccounts u ON c.creatoruuid = u.PrincipalID
|
||||
LEFT JOIN regions r ON c.simname = r.regionName
|
||||
WHERE 1=1";
|
||||
|
||||
if ($category && $category != 'all') {
|
||||
$sql .= " AND c.category = '" . mysqli_real_escape_string($con, $category) . "'";
|
||||
}
|
||||
|
||||
if ($search) {
|
||||
$search = mysqli_real_escape_string($con, $search);
|
||||
$sql .= " AND (c.name LIKE '%$search%' OR c.description LIKE '%$search%')";
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY c.creationdate DESC";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getClassifiedById($con, $classifieduuid) {
|
||||
$sql = "SELECT c.*, u.FirstName, u.LastName, r.regionName, r.serverURI
|
||||
FROM classifieds c
|
||||
LEFT JOIN UserAccounts u ON c.creatoruuid = u.PrincipalID
|
||||
LEFT JOIN regions r ON c.simname = r.regionName
|
||||
WHERE c.classifieduuid = '" . mysqli_real_escape_string($con, $classifieduuid) . "'";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getCategories() {
|
||||
return [
|
||||
'all' => 'Alle Kategorien',
|
||||
'shopping' => 'Shopping',
|
||||
'land_rental' => 'Landvermietung',
|
||||
'property_rental' => 'Immobilien',
|
||||
'special_attraction' => 'Sehenswürdigkeiten',
|
||||
'new_products' => 'Neue Produkte',
|
||||
'employment' => 'Stellenanzeigen',
|
||||
'wanted' => 'Gesucht',
|
||||
'service' => 'Dienstleistungen',
|
||||
'personal' => 'Persönliches'
|
||||
];
|
||||
}
|
||||
|
||||
// Aktionen verarbeiten
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : 'list';
|
||||
$category = isset($_GET['category']) ? $_GET['category'] : 'all';
|
||||
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
|
||||
$classifiedId = isset($_GET['id']) ? $_GET['id'] : '';
|
||||
|
||||
?>
|
||||
|
||||
<div class="container-fluid mt-4">
|
||||
<div class="row">
|
||||
<!-- Sidebar -->
|
||||
<div class="col-md-3">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-filter"></i> Filter & Suche</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- Suchformular -->
|
||||
<form method="GET" action="classifieds.php">
|
||||
<div class="mb-3">
|
||||
<label for="search" class="form-label">Suche:</label>
|
||||
<input type="text" class="form-control" id="search" name="search"
|
||||
value="<?php echo htmlspecialchars($search); ?>"
|
||||
placeholder="Suchbegriff eingeben...">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="category" class="form-label">Kategorie:</label>
|
||||
<select class="form-select" id="category" name="category">
|
||||
<?php foreach (getCategories() as $key => $value): ?>
|
||||
<option value="<?php echo $key; ?>" <?php echo ($category == $key) ? 'selected' : ''; ?>>
|
||||
<?php echo $value; ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
<i class="fas fa-search"></i> Suchen
|
||||
</button>
|
||||
<a href="classifieds.php" class="btn btn-secondary w-100 mt-2">
|
||||
<i class="fas fa-refresh"></i> Zurücksetzen
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Schnelllinks -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-star"></i> Beliebte Kategorien</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-grid gap-2">
|
||||
<a href="classifieds.php?category=shopping" class="btn btn-outline-primary btn-sm">
|
||||
🛍️ Shopping
|
||||
</a>
|
||||
<a href="classifieds.php?category=land_rental" class="btn btn-outline-success btn-sm">
|
||||
🏡 Landvermietung
|
||||
</a>
|
||||
<a href="classifieds.php?category=special_attraction" class="btn btn-outline-info btn-sm">
|
||||
🎭 Sehenswürdigkeiten
|
||||
</a>
|
||||
<a href="classifieds.php?category=employment" class="btn btn-outline-warning btn-sm">
|
||||
💼 Jobs
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hauptinhalt -->
|
||||
<div class="col-md-9">
|
||||
<?php if ($action == 'view' && $classifiedId): ?>
|
||||
<!-- Detail-Ansicht einer Anzeige -->
|
||||
<?php
|
||||
$result = getClassifiedById($con, $classifiedId);
|
||||
$classified = mysqli_fetch_assoc($result);
|
||||
|
||||
if ($classified):
|
||||
?>
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h4><i class="fas fa-ad"></i> <?php echo htmlspecialchars($classified['name']); ?></h4>
|
||||
<a href="classifieds.php" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Zurück zur Liste
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<h5>Beschreibung:</h5>
|
||||
<p class="text-justify"><?php echo nl2br(htmlspecialchars($classified['description'])); ?></p>
|
||||
|
||||
<div class="row mt-4">
|
||||
<div class="col-md-6">
|
||||
<h6>Details:</h6>
|
||||
<ul class="list-unstyled">
|
||||
<li><strong>Kategorie:</strong> <?php echo getCategories()[$classified['category']] ?? 'Unbekannt'; ?></li>
|
||||
<li><strong>Preis:</strong> L$ <?php echo number_format($classified['priceforlisting'], 0, ',', '.'); ?></li>
|
||||
<li><strong>Erstellt:</strong> <?php echo date('d.m.Y H:i', $classified['creationdate']); ?></li>
|
||||
<li><strong>Aufrufe:</strong> <?php echo number_format($classified['clickthrough'], 0, ',', '.'); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h6>Kontakt & Location:</h6>
|
||||
<ul class="list-unstyled">
|
||||
<li><strong>Ersteller:</strong> <?php echo htmlspecialchars($classified['FirstName'] . ' ' . $classified['LastName']); ?></li>
|
||||
<li><strong>Region:</strong> <?php echo htmlspecialchars($classified['regionName'] ?? $classified['simname']); ?></li>
|
||||
<li><strong>Position:</strong> <?php echo htmlspecialchars($classified['posglobal']); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<!-- Snapshot-Bild falls vorhanden -->
|
||||
<?php if ($classified['snapshotuuid'] && $classified['snapshotuuid'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<div class="text-center mb-3">
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $classified['snapshotuuid']; ?>"
|
||||
class="img-fluid rounded"
|
||||
alt="Anzeigenbild"
|
||||
style="max-height: 200px;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Teleport-Button -->
|
||||
<div class="d-grid">
|
||||
<a href="secondlife://<?php echo htmlspecialchars($classified['simname']); ?>/<?php echo htmlspecialchars($classified['posglobal']); ?>"
|
||||
class="btn btn-success btn-lg">
|
||||
<i class="fas fa-rocket"></i> Teleportieren
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Auf Karte anzeigen -->
|
||||
<div class="d-grid mt-2">
|
||||
<a href="maptile.php?region=<?php echo urlencode($classified['simname']); ?>"
|
||||
class="btn btn-info">
|
||||
<i class="fas fa-map"></i> Auf Karte anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-warning">
|
||||
<i class="fas fa-exclamation-triangle"></i> Anzeige nicht gefunden.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else: ?>
|
||||
<!-- Anzeigen-Liste -->
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h4><i class="fas fa-list"></i> Klassifizierte Anzeigen</h4>
|
||||
<span class="badge bg-info">
|
||||
Kategorie: <?php echo getCategories()[$category]; ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$result = getAllClassifieds($con, $category, $search);
|
||||
$count = mysqli_num_rows($result);
|
||||
?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6><?php echo $count; ?> Anzeigen gefunden</h6>
|
||||
<?php if ($search): ?>
|
||||
<span class="badge bg-secondary">
|
||||
Suche nach: "<?php echo htmlspecialchars($search); ?>"
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($count > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($row = mysqli_fetch_assoc($result)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-4">
|
||||
<div class="card h-100">
|
||||
<?php if ($row['snapshotuuid'] && $row['snapshotuuid'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $row['snapshotuuid']; ?>"
|
||||
class="card-img-top"
|
||||
alt="Anzeigenbild"
|
||||
style="height: 150px; object-fit: cover;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-body d-flex flex-column">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($row['name']); ?></h6>
|
||||
<p class="card-text text-muted small flex-grow-1">
|
||||
<?php echo htmlspecialchars(substr($row['description'], 0, 100) . (strlen($row['description']) > 100 ? '...' : '')); ?>
|
||||
</p>
|
||||
|
||||
<div class="mt-auto">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<small class="text-muted">
|
||||
<?php echo getCategories()[$row['category']] ?? 'Unbekannt'; ?>
|
||||
</small>
|
||||
<span class="badge bg-success">
|
||||
L$ <?php echo number_format($row['priceforlisting'], 0, ',', '.'); ?>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<small class="text-muted">
|
||||
von <?php echo htmlspecialchars($row['FirstName'] . ' ' . $row['LastName']); ?>
|
||||
</small>
|
||||
<small class="text-muted">
|
||||
<?php echo $row['clickthrough']; ?> Aufrufe
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<a href="classifieds.php?action=view&id=<?php echo $row['classifieduuid']; ?>"
|
||||
class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-eye"></i> Details anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-search fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine Anzeigen gefunden</h5>
|
||||
<p class="text-muted">
|
||||
<?php if ($search || $category != 'all'): ?>
|
||||
Versuchen Sie es mit anderen Suchbegriffen oder einer anderen Kategorie.
|
||||
<?php else: ?>
|
||||
Es wurden noch keine klassifizierten Anzeigen erstellt.
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiken Footer -->
|
||||
<div class="container-fluid mt-4">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card bg-light">
|
||||
<div class="card-body">
|
||||
<div class="row text-center">
|
||||
<?php
|
||||
$totalAds = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM classifieds"))[0];
|
||||
$categoriesUsed = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(DISTINCT category) FROM classifieds"))[0];
|
||||
$totalClicks = mysqli_fetch_row(mysqli_query($con, "SELECT SUM(clickthrough) FROM classifieds"))[0];
|
||||
$totalRevenue = mysqli_fetch_row(mysqli_query($con, "SELECT SUM(priceforlisting) FROM classifieds"))[0];
|
||||
?>
|
||||
|
||||
<div class="col-md-3">
|
||||
<i class="fas fa-ad fa-2x text-primary"></i>
|
||||
<h5 class="mt-2"><?php echo number_format($totalAds, 0, ',', '.'); ?></h5>
|
||||
<p class="text-muted">Gesamt Anzeigen</p>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<i class="fas fa-tags fa-2x text-success"></i>
|
||||
<h5 class="mt-2"><?php echo $categoriesUsed; ?></h5>
|
||||
<p class="text-muted">Kategorien verwendet</p>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<i class="fas fa-mouse-pointer fa-2x text-info"></i>
|
||||
<h5 class="mt-2"><?php echo number_format($totalClicks, 0, ',', '.'); ?></h5>
|
||||
<p class="text-muted">Gesamt Aufrufe</p>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<i class="fas fa-coins fa-2x text-warning"></i>
|
||||
<h5 class="mt-2">L$ <?php echo number_format($totalRevenue, 0, ',', '.'); ?></h5>
|
||||
<p class="text-muted">Gesamt Umsatz</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card-img-top {
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.card:hover .card-img-top {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.card {
|
||||
transition: box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Auto-Submit für Kategorie-Änderungen
|
||||
document.getElementById('category').addEventListener('change', function() {
|
||||
this.form.submit();
|
||||
});
|
||||
|
||||
// Klick-Tracking (optional)
|
||||
function trackClick(classifiedId) {
|
||||
fetch('classifieds_api.php?action=track_click&id=' + classifiedId);
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php
|
||||
mysqli_close($con);
|
||||
include_once "include/footerModern.php";
|
||||
?>
|
||||
+776
@@ -0,0 +1,776 @@
|
||||
<?php
|
||||
$title = "Economy Dashboard";
|
||||
include_once "include/config.php";
|
||||
include_once "include/" . HEADER_FILE;
|
||||
|
||||
// Datenbankverbindung
|
||||
$con = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
|
||||
if (!$con) {
|
||||
die("Datenbankverbindung fehlgeschlagen: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Economy Funktionen
|
||||
function getUserBalance($con, $userId) {
|
||||
$sql = "SELECT * FROM balances WHERE PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "'";
|
||||
$result = mysqli_query($con, $sql);
|
||||
return $result ? mysqli_fetch_assoc($result) : null;
|
||||
}
|
||||
|
||||
function getUserTransactions($con, $userId, $limit = 50, $offset = 0) {
|
||||
$sql = "SELECT t.*,
|
||||
ua_from.FirstName as FromFirstName, ua_from.LastName as FromLastName,
|
||||
ua_to.FirstName as ToFirstName, ua_to.LastName as ToLastName
|
||||
FROM transactions t
|
||||
LEFT JOIN UserAccounts ua_from ON t.fromID = ua_from.PrincipalID
|
||||
LEFT JOIN UserAccounts ua_to ON t.toID = ua_to.PrincipalID
|
||||
WHERE (t.fromID = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
OR t.toID = '" . mysqli_real_escape_string($con, $userId) . "')
|
||||
ORDER BY t.time DESC
|
||||
LIMIT " . intval($limit) . " OFFSET " . intval($offset);
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getTotalSales($con, $userId = null) {
|
||||
$sql = "SELECT * FROM totalsales";
|
||||
if ($userId) {
|
||||
$sql .= " WHERE user = '" . mysqli_real_escape_string($con, $userId) . "'";
|
||||
}
|
||||
$sql .= " ORDER BY time DESC";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getEconomyStats($con) {
|
||||
$totalMoney = mysqli_fetch_row(mysqli_query($con, "SELECT SUM(balance) FROM balances"))[0] ?? 0;
|
||||
$totalUsers = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM balances WHERE balance > 0"))[0];
|
||||
$totalTransactions = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM transactions"))[0];
|
||||
$dailyVolume = mysqli_fetch_row(mysqli_query($con, "SELECT SUM(amount) FROM transactions WHERE time > (UNIX_TIMESTAMP() - 86400)"))[0] ?? 0;
|
||||
|
||||
$avgBalance = $totalUsers > 0 ? $totalMoney / $totalUsers : 0;
|
||||
|
||||
return [
|
||||
'total_money' => $totalMoney,
|
||||
'total_users' => $totalUsers,
|
||||
'total_transactions' => $totalTransactions,
|
||||
'daily_volume' => $dailyVolume,
|
||||
'avg_balance' => $avgBalance
|
||||
];
|
||||
}
|
||||
|
||||
function getTopUsers($con, $type = 'balance', $limit = 10) {
|
||||
if ($type == 'balance') {
|
||||
$sql = "SELECT b.*, ua.FirstName, ua.LastName
|
||||
FROM balances b
|
||||
LEFT JOIN UserAccounts ua ON b.PrincipalID = ua.PrincipalID
|
||||
ORDER BY b.balance DESC
|
||||
LIMIT " . intval($limit);
|
||||
} elseif ($type == 'transactions') {
|
||||
$sql = "SELECT COUNT(*) as transaction_count, t.fromID as PrincipalID, ua.FirstName, ua.LastName
|
||||
FROM transactions t
|
||||
LEFT JOIN UserAccounts ua ON t.fromID = ua.PrincipalID
|
||||
WHERE t.time > (UNIX_TIMESTAMP() - (30*86400))
|
||||
GROUP BY t.fromID
|
||||
ORDER BY transaction_count DESC
|
||||
LIMIT " . intval($limit);
|
||||
}
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getTransactionTypes($con, $userId = null, $days = 30) {
|
||||
$sql = "SELECT type, COUNT(*) as count, SUM(amount) as total_amount
|
||||
FROM transactions
|
||||
WHERE time > (UNIX_TIMESTAMP() - (" . intval($days) . "*86400))";
|
||||
|
||||
if ($userId) {
|
||||
$sql .= " AND (fromID = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
OR toID = '" . mysqli_real_escape_string($con, $userId) . "')";
|
||||
}
|
||||
|
||||
$sql .= " GROUP BY type ORDER BY total_amount DESC";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getRecentTransactions($con, $limit = 20) {
|
||||
$sql = "SELECT t.*,
|
||||
ua_from.FirstName as FromFirstName, ua_from.LastName as FromLastName,
|
||||
ua_to.FirstName as ToFirstName, ua_to.LastName as ToLastName
|
||||
FROM transactions t
|
||||
LEFT JOIN UserAccounts ua_from ON t.fromID = ua_from.PrincipalID
|
||||
LEFT JOIN UserAccounts ua_to ON t.toID = ua_to.PrincipalID
|
||||
ORDER BY t.time DESC
|
||||
LIMIT " . intval($limit);
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
// Parameter verarbeiten
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : 'dashboard';
|
||||
$userId = isset($_GET['user']) ? $_GET['user'] : '';
|
||||
$period = isset($_GET['period']) ? $_GET['period'] : '30';
|
||||
|
||||
// Dummy-Benutzer-ID für Demo (normalerweise aus Session)
|
||||
$currentUserId = '00000000-0000-0000-0000-000000000001'; // Beispiel-User-ID
|
||||
|
||||
?>
|
||||
|
||||
<div class="container-fluid mt-4">
|
||||
<div class="row">
|
||||
<!-- Sidebar -->
|
||||
<div class="col-md-3">
|
||||
<!-- Mein Konto -->
|
||||
<div class="card">
|
||||
<div class="card-header bg-success text-white">
|
||||
<h5><i class="fas fa-wallet"></i> Mein Konto</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$myBalance = getUserBalance($con, $currentUserId);
|
||||
$myRecentTransactions = getUserTransactions($con, $currentUserId, 5);
|
||||
$myTransactionCount = mysqli_num_rows($myRecentTransactions);
|
||||
?>
|
||||
|
||||
<div class="text-center mb-3">
|
||||
<h3 class="text-success">
|
||||
L$ <?php echo number_format($myBalance['balance'] ?? 0, 0, ',', '.'); ?>
|
||||
</h3>
|
||||
<small class="text-muted">Aktueller Kontostand</small>
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<a href="economy.php?action=my_account" class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-chart-line"></i> Mein Konto
|
||||
</a>
|
||||
<a href="economy.php?action=send_money" class="btn btn-success btn-sm">
|
||||
<i class="fas fa-paper-plane"></i> Geld senden
|
||||
</a>
|
||||
<a href="economy.php?action=my_transactions" class="btn btn-outline-info btn-sm">
|
||||
<i class="fas fa-list"></i> Transaktionen (<?php echo $myTransactionCount; ?>)
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Navigation -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-navigation"></i> Economy Navigation</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-grid gap-2">
|
||||
<a href="economy.php?action=dashboard" class="btn btn-outline-primary btn-sm">
|
||||
<i class="fas fa-tachometer-alt"></i> Dashboard
|
||||
</a>
|
||||
<a href="economy.php?action=leaderboard" class="btn btn-outline-warning btn-sm">
|
||||
<i class="fas fa-trophy"></i> Rangliste
|
||||
</a>
|
||||
<a href="economy.php?action=statistics" class="btn btn-outline-info btn-sm">
|
||||
<i class="fas fa-chart-bar"></i> Statistiken
|
||||
</a>
|
||||
<a href="economy.php?action=recent" class="btn btn-outline-secondary btn-sm">
|
||||
<i class="fas fa-clock"></i> Neueste Transaktionen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Schnellstatistiken -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-info-circle"></i> Grid Economy</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php $stats = getEconomyStats($con); ?>
|
||||
|
||||
<div class="text-center">
|
||||
<div class="mb-2">
|
||||
<h5 class="text-primary">L$ <?php echo number_format($stats['total_money'], 0, ',', '.'); ?></h5>
|
||||
<small class="text-muted">Geld im Umlauf</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<h5 class="text-success"><?php echo number_format($stats['total_users'], 0, ',', '.'); ?></h5>
|
||||
<small class="text-muted">Aktive Konten</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<h5 class="text-info"><?php echo number_format($stats['total_transactions'], 0, ',', '.'); ?></h5>
|
||||
<small class="text-muted">Gesamt Transaktionen</small>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="text-warning">L$ <?php echo number_format($stats['daily_volume'], 0, ',', '.'); ?></h5>
|
||||
<small class="text-muted">Heute umgesetzt</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hauptinhalt -->
|
||||
<div class="col-md-9">
|
||||
<?php if ($action == 'my_account'): ?>
|
||||
<!-- Mein Konto Detail -->
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h4><i class="fas fa-user-circle"></i> Mein Economy-Konto</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$balance = getUserBalance($con, $currentUserId);
|
||||
$transactionsResult = getUserTransactions($con, $currentUserId, 20);
|
||||
$transactionTypes = getTransactionTypes($con, $currentUserId);
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="card bg-success text-white">
|
||||
<div class="card-body text-center">
|
||||
<h2>L$ <?php echo number_format($balance['balance'] ?? 0, 0, ',', '.'); ?></h2>
|
||||
<p class="mb-0">Aktueller Kontostand</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card bg-info text-white">
|
||||
<div class="card-body text-center">
|
||||
<?php
|
||||
$monthlySpent = mysqli_fetch_row(mysqli_query($con, "
|
||||
SELECT SUM(amount) FROM transactions
|
||||
WHERE fromID = '" . mysqli_real_escape_string($con, $currentUserId) . "'
|
||||
AND time > (UNIX_TIMESTAMP() - (30*86400))
|
||||
"))[0] ?? 0;
|
||||
?>
|
||||
<h2>L$ <?php echo number_format($monthlySpent, 0, ',', '.'); ?></h2>
|
||||
<p class="mb-0">Ausgaben (30 Tage)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card bg-warning text-white">
|
||||
<div class="card-body text-center">
|
||||
<?php
|
||||
$monthlyReceived = mysqli_fetch_row(mysqli_query($con, "
|
||||
SELECT SUM(amount) FROM transactions
|
||||
WHERE toID = '" . mysqli_real_escape_string($con, $currentUserId) . "'
|
||||
AND time > (UNIX_TIMESTAMP() - (30*86400))
|
||||
"))[0] ?? 0;
|
||||
?>
|
||||
<h2>L$ <?php echo number_format($monthlyReceived, 0, ',', '.'); ?></h2>
|
||||
<p class="mb-0">Einnahmen (30 Tage)</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Transaktionstypen -->
|
||||
<div class="row mt-4">
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-chart-pie"></i> Transaktionstypen (30 Tage)</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php while ($type = mysqli_fetch_assoc($transactionTypes)): ?>
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<span><?php echo htmlspecialchars($type['type']); ?></span>
|
||||
<div>
|
||||
<span class="badge bg-primary me-2"><?php echo $type['count']; ?>x</span>
|
||||
<span class="badge bg-success">L$ <?php echo number_format($type['total_amount'], 0, ',', '.'); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-tools"></i> Konto-Aktionen</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-grid gap-2">
|
||||
<button class="btn btn-success" onclick="showSendMoneyModal()">
|
||||
<i class="fas fa-paper-plane"></i> Geld senden
|
||||
</button>
|
||||
<button class="btn btn-info" onclick="showRequestMoneyModal()">
|
||||
<i class="fas fa-hand-holding-usd"></i> Geld anfordern
|
||||
</button>
|
||||
<a href="economy.php?action=my_transactions" class="btn btn-outline-primary">
|
||||
<i class="fas fa-list"></i> Alle Transaktionen anzeigen
|
||||
</a>
|
||||
<button class="btn btn-outline-secondary" onclick="exportTransactions()">
|
||||
<i class="fas fa-download"></i> Transaktionen exportieren
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Neueste Transaktionen -->
|
||||
<div class="mt-4">
|
||||
<h5><i class="fas fa-history"></i> Neueste Transaktionen</h5>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Von/An</th>
|
||||
<th>Betrag</th>
|
||||
<th>Typ</th>
|
||||
<th>Beschreibung</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($transaction = mysqli_fetch_assoc($transactionsResult)): ?>
|
||||
<tr>
|
||||
<td><?php echo date('d.m.Y H:i', $transaction['time']); ?></td>
|
||||
<td>
|
||||
<?php if ($transaction['fromID'] == $currentUserId): ?>
|
||||
<span class="text-danger">→ <?php echo htmlspecialchars($transaction['ToFirstName'] . ' ' . $transaction['ToLastName']); ?></span>
|
||||
<?php else: ?>
|
||||
<span class="text-success">← <?php echo htmlspecialchars($transaction['FromFirstName'] . ' ' . $transaction['FromLastName']); ?></span>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-<?php echo ($transaction['fromID'] == $currentUserId) ? 'danger' : 'success'; ?>">
|
||||
<?php echo ($transaction['fromID'] == $currentUserId) ? '-' : '+'; ?>L$ <?php echo number_format($transaction['amount'], 0, ',', '.'); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($transaction['type']); ?></td>
|
||||
<td><?php echo htmlspecialchars($transaction['description'] ?? '-'); ?></td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php elseif ($action == 'leaderboard'): ?>
|
||||
<!-- Ranglisten -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4><i class="fas fa-trophy"></i> Economy Ranglisten</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<!-- Top Balances -->
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<h5><i class="fas fa-coins"></i> Top Konten (Kontostand)</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$topBalances = getTopUsers($con, 'balance', 10);
|
||||
$rank = 1;
|
||||
?>
|
||||
<?php while ($user = mysqli_fetch_assoc($topBalances)): ?>
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<div>
|
||||
<span class="badge bg-<?php echo $rank <= 3 ? ($rank == 1 ? 'warning' : ($rank == 2 ? 'secondary' : 'dark')) : 'light text-dark'; ?> me-2">
|
||||
#<?php echo $rank; ?>
|
||||
</span>
|
||||
<a href="profile.php?user=<?php echo $user['PrincipalID']; ?>" class="text-decoration-none">
|
||||
<?php echo htmlspecialchars($user['FirstName'] . ' ' . $user['LastName']); ?>
|
||||
</a>
|
||||
</div>
|
||||
<span class="badge bg-success">L$ <?php echo number_format($user['balance'], 0, ',', '.'); ?></span>
|
||||
</div>
|
||||
<?php $rank++; endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Top Transaktionen -->
|
||||
<div class="col-md-6">
|
||||
<div class="card">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h5><i class="fas fa-exchange-alt"></i> Aktivste Benutzer (30 Tage)</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$topTransactions = getTopUsers($con, 'transactions', 10);
|
||||
$rank = 1;
|
||||
?>
|
||||
<?php while ($user = mysqli_fetch_assoc($topTransactions)): ?>
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<div>
|
||||
<span class="badge bg-<?php echo $rank <= 3 ? ($rank == 1 ? 'warning' : ($rank == 2 ? 'secondary' : 'dark')) : 'light text-dark'; ?> me-2">
|
||||
#<?php echo $rank; ?>
|
||||
</span>
|
||||
<a href="profile.php?user=<?php echo $user['PrincipalID']; ?>" class="text-decoration-none">
|
||||
<?php echo htmlspecialchars($user['FirstName'] . ' ' . $user['LastName']); ?>
|
||||
</a>
|
||||
</div>
|
||||
<span class="badge bg-primary"><?php echo $user['transaction_count']; ?> Transaktionen</span>
|
||||
</div>
|
||||
<?php $rank++; endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php elseif ($action == 'recent'): ?>
|
||||
<!-- Neueste Transaktionen -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4><i class="fas fa-clock"></i> Neueste Grid-Transaktionen</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$recentTransactions = getRecentTransactions($con, 50);
|
||||
?>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Zeit</th>
|
||||
<th>Von</th>
|
||||
<th>An</th>
|
||||
<th>Betrag</th>
|
||||
<th>Typ</th>
|
||||
<th>Beschreibung</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php while ($transaction = mysqli_fetch_assoc($recentTransactions)): ?>
|
||||
<tr>
|
||||
<td><?php echo date('d.m.Y H:i', $transaction['time']); ?></td>
|
||||
<td>
|
||||
<?php if ($transaction['FromFirstName']): ?>
|
||||
<a href="profile.php?user=<?php echo $transaction['fromID']; ?>" class="text-decoration-none">
|
||||
<?php echo htmlspecialchars($transaction['FromFirstName'] . ' ' . $transaction['FromLastName']); ?>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<em>System</em>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<?php if ($transaction['ToFirstName']): ?>
|
||||
<a href="profile.php?user=<?php echo $transaction['toID']; ?>" class="text-decoration-none">
|
||||
<?php echo htmlspecialchars($transaction['ToFirstName'] . ' ' . $transaction['ToLastName']); ?>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<em>System</em>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-success">
|
||||
L$ <?php echo number_format($transaction['amount'], 0, ',', '.'); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span class="badge bg-info">
|
||||
<?php echo htmlspecialchars($transaction['type']); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td><?php echo htmlspecialchars($transaction['description'] ?? '-'); ?></td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<!-- Economy Dashboard -->
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h4><i class="fas fa-tachometer-alt"></i> Economy Dashboard</h4>
|
||||
<p class="mb-0">Übersicht über die Grid-Wirtschaft</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hauptstatistiken -->
|
||||
<div class="row mt-3">
|
||||
<?php $stats = getEconomyStats($con); ?>
|
||||
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-primary text-white">
|
||||
<div class="card-body text-center">
|
||||
<i class="fas fa-coins fa-2x mb-2"></i>
|
||||
<h4>L$ <?php echo number_format($stats['total_money'], 0, ',', '.'); ?></h4>
|
||||
<p class="mb-0">Geld im Umlauf</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-success text-white">
|
||||
<div class="card-body text-center">
|
||||
<i class="fas fa-users fa-2x mb-2"></i>
|
||||
<h4><?php echo number_format($stats['total_users'], 0, ',', '.'); ?></h4>
|
||||
<p class="mb-0">Aktive Konten</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-info text-white">
|
||||
<div class="card-body text-center">
|
||||
<i class="fas fa-exchange-alt fa-2x mb-2"></i>
|
||||
<h4><?php echo number_format($stats['total_transactions'], 0, ',', '.'); ?></h4>
|
||||
<p class="mb-0">Gesamt Transaktionen</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<div class="card bg-warning text-white">
|
||||
<div class="card-body text-center">
|
||||
<i class="fas fa-chart-line fa-2x mb-2"></i>
|
||||
<h4>L$ <?php echo number_format($stats['daily_volume'], 0, ',', '.'); ?></h4>
|
||||
<p class="mb-0">24h Volumen</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Detailstatistiken -->
|
||||
<div class="row mt-3">
|
||||
<div class="col-md-8">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-chart-area"></i> Transaktionsübersicht</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Transaktionstyp</th>
|
||||
<th>Anzahl (30 Tage)</th>
|
||||
<th>Volumen (30 Tage)</th>
|
||||
<th>Durchschnitt</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$transactionTypes = getTransactionTypes($con, null, 30);
|
||||
while ($type = mysqli_fetch_assoc($transactionTypes)):
|
||||
?>
|
||||
<tr>
|
||||
<td><?php echo htmlspecialchars($type['type']); ?></td>
|
||||
<td><?php echo number_format($type['count'], 0, ',', '.'); ?></td>
|
||||
<td>L$ <?php echo number_format($type['total_amount'], 0, ',', '.'); ?></td>
|
||||
<td>L$ <?php echo number_format($type['total_amount'] / $type['count'], 0, ',', '.'); ?></td>
|
||||
</tr>
|
||||
<?php endwhile; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-chart-pie"></i> Weitere Statistiken</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between">
|
||||
<span>Durchschnittskontostand:</span>
|
||||
<strong>L$ <?php echo number_format($stats['avg_balance'], 0, ',', '.'); ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$weeklyVolume = mysqli_fetch_row(mysqli_query($con, "SELECT SUM(amount) FROM transactions WHERE time > (UNIX_TIMESTAMP() - (7*86400))"))[0] ?? 0;
|
||||
$monthlyVolume = mysqli_fetch_row(mysqli_query($con, "SELECT SUM(amount) FROM transactions WHERE time > (UNIX_TIMESTAMP() - (30*86400))"))[0] ?? 0;
|
||||
?>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between">
|
||||
<span>7-Tage Volumen:</span>
|
||||
<strong>L$ <?php echo number_format($weeklyVolume, 0, ',', '.'); ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="d-flex justify-content-between">
|
||||
<span>30-Tage Volumen:</span>
|
||||
<strong>L$ <?php echo number_format($monthlyVolume, 0, ',', '.'); ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<a href="economy.php?action=leaderboard" class="btn btn-warning btn-sm">
|
||||
<i class="fas fa-trophy"></i> Ranglisten anzeigen
|
||||
</a>
|
||||
<a href="economy.php?action=recent" class="btn btn-info btn-sm">
|
||||
<i class="fas fa-clock"></i> Neueste Transaktionen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Neueste Aktivitäten -->
|
||||
<div class="row mt-3">
|
||||
<div class="col-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-activity"></i> Neueste Grid-Aktivitäten</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$recentActivities = getRecentTransactions($con, 10);
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<?php while ($activity = mysqli_fetch_assoc($recentActivities)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card bg-light">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between align-items-start mb-2">
|
||||
<span class="badge bg-info"><?php echo htmlspecialchars($activity['type']); ?></span>
|
||||
<small class="text-muted"><?php echo date('H:i', $activity['time']); ?></small>
|
||||
</div>
|
||||
|
||||
<h6 class="card-title">L$ <?php echo number_format($activity['amount'], 0, ',', '.'); ?></h6>
|
||||
|
||||
<p class="card-text small">
|
||||
<strong>Von:</strong> <?php echo htmlspecialchars($activity['FromFirstName'] ? $activity['FromFirstName'] . ' ' . $activity['FromLastName'] : 'System'); ?><br>
|
||||
<strong>An:</strong> <?php echo htmlspecialchars($activity['ToFirstName'] ? $activity['ToFirstName'] . ' ' . $activity['ToLastName'] : 'System'); ?>
|
||||
</p>
|
||||
|
||||
<?php if ($activity['description']): ?>
|
||||
<p class="card-text small text-muted">
|
||||
<?php echo htmlspecialchars($activity['description']); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Geld senden Modal -->
|
||||
<div class="modal fade" id="sendMoneyModal" tabindex="-1">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title"><i class="fas fa-paper-plane"></i> Geld senden</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||||
</div>
|
||||
<form id="sendMoneyForm">
|
||||
<div class="modal-body">
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Empfänger (Vor- und Nachname):</label>
|
||||
<input type="text" class="form-control" id="recipient" placeholder="z.B. Max Mustermann" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Betrag (L$):</label>
|
||||
<input type="number" class="form-control" id="amount" min="1" max="<?php echo $myBalance['balance'] ?? 0; ?>" required>
|
||||
<small class="text-muted">Verfügbar: L$ <?php echo number_format($myBalance['balance'] ?? 0, 0, ',', '.'); ?></small>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Verwendungszweck (optional):</label>
|
||||
<input type="text" class="form-control" id="description" placeholder="z.B. Zahlung für...">
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Abbrechen</button>
|
||||
<button type="submit" class="btn btn-success">Geld senden</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card {
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.badge {
|
||||
font-size: 0.75em;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Economy Functions
|
||||
function showSendMoneyModal() {
|
||||
new bootstrap.Modal(document.getElementById('sendMoneyModal')).show();
|
||||
}
|
||||
|
||||
function showRequestMoneyModal() {
|
||||
alert('Geld-Anfrage-Feature wird bald verfügbar sein!');
|
||||
}
|
||||
|
||||
function exportTransactions() {
|
||||
window.open('economy_export.php?action=export_transactions&user=<?php echo $currentUserId; ?>', '_blank');
|
||||
}
|
||||
|
||||
// Send Money Form
|
||||
document.getElementById('sendMoneyForm')?.addEventListener('submit', function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const recipient = document.getElementById('recipient').value;
|
||||
const amount = document.getElementById('amount').value;
|
||||
const description = document.getElementById('description').value;
|
||||
|
||||
if (confirm(`Möchten Sie L$ ${amount} an ${recipient} senden?`)) {
|
||||
// AJAX-Call für Geldtransfer
|
||||
fetch('economy_api.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action: 'send_money',
|
||||
recipient: recipient,
|
||||
amount: amount,
|
||||
description: description
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert('Geld wurde erfolgreich gesendet!');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Fehler: ' + data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Ein Fehler ist aufgetreten.');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Auto-refresh für Dashboard (alle 60 Sekunden)
|
||||
if (window.location.href.includes('action=dashboard') || !window.location.href.includes('action=')) {
|
||||
setInterval(function() {
|
||||
location.reload();
|
||||
}, 60000);
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php
|
||||
mysqli_close($con);
|
||||
include_once "include/footerModern.php";
|
||||
?>
|
||||
+683
@@ -0,0 +1,683 @@
|
||||
<?php
|
||||
$title = "Freundessystem";
|
||||
include_once "include/config.php";
|
||||
include_once "include/" . HEADER_FILE;
|
||||
|
||||
// Datenbankverbindung
|
||||
$con = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
|
||||
if (!$con) {
|
||||
die("Datenbankverbindung fehlgeschlagen: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Funktionen für Freunde
|
||||
function getAllFriends($con, $userId) {
|
||||
$sql = "SELECT f.*,
|
||||
ua1.FirstName as UserFirstName, ua1.LastName as UserLastName,
|
||||
ua2.FirstName as FriendFirstName, ua2.LastName as FriendLastName,
|
||||
gu.Login as LastLogin, gu.Online
|
||||
FROM Friends f
|
||||
LEFT JOIN UserAccounts ua1 ON f.PrincipalID = ua1.PrincipalID
|
||||
LEFT JOIN UserAccounts ua2 ON f.Friend = ua2.PrincipalID
|
||||
LEFT JOIN GridUser gu ON f.Friend = gu.UserID
|
||||
WHERE (f.PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
OR f.Friend = '" . mysqli_real_escape_string($con, $userId) . "')
|
||||
ORDER BY gu.Login DESC, ua2.FirstName ASC";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getFriendRequests($con, $userId) {
|
||||
// Freundschaftsanfragen sind normalerweise in separater Tabelle oder durch Flags markiert
|
||||
// Hier nehmen wir an, dass Flags = 0 eine Anfrage bedeutet
|
||||
$sql = "SELECT f.*,
|
||||
ua1.FirstName as RequesterFirstName, ua1.LastName as RequesterLastName,
|
||||
ua2.FirstName as TargetFirstName, ua2.LastName as TargetLastName
|
||||
FROM Friends f
|
||||
LEFT JOIN UserAccounts ua1 ON f.PrincipalID = ua1.PrincipalID
|
||||
LEFT JOIN UserAccounts ua2 ON f.Friend = ua2.PrincipalID
|
||||
WHERE f.Friend = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
AND f.Flags = 0
|
||||
ORDER BY ua1.FirstName ASC";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getOnlineFriends($con, $userId) {
|
||||
$sql = "SELECT f.*,
|
||||
ua.FirstName, ua.LastName,
|
||||
gu.Login, gu.Logout, gu.Online, gu.Position, gu.LookAt
|
||||
FROM Friends f
|
||||
LEFT JOIN UserAccounts ua ON (
|
||||
CASE
|
||||
WHEN f.PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "' THEN f.Friend = ua.PrincipalID
|
||||
ELSE f.PrincipalID = ua.PrincipalID
|
||||
END
|
||||
)
|
||||
LEFT JOIN GridUser gu ON ua.PrincipalID = gu.UserID
|
||||
WHERE (f.PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
OR f.Friend = '" . mysqli_real_escape_string($con, $userId) . "')
|
||||
AND f.Flags > 0
|
||||
AND gu.Login > (UNIX_TIMESTAMP() - 300) -- Online in den letzten 5 Minuten
|
||||
ORDER BY gu.Login DESC";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function searchUsers($con, $search) {
|
||||
$search = mysqli_real_escape_string($con, $search);
|
||||
$sql = "SELECT ua.PrincipalID, ua.FirstName, ua.LastName,
|
||||
gu.Login, gu.Online,
|
||||
up.profileImage, up.profileAboutText
|
||||
FROM UserAccounts ua
|
||||
LEFT JOIN GridUser gu ON ua.PrincipalID = gu.UserID
|
||||
LEFT JOIN userprofile up ON ua.PrincipalID = up.useruuid
|
||||
WHERE (ua.FirstName LIKE '%$search%' OR ua.LastName LIKE '%$search%')
|
||||
ORDER BY gu.Login DESC, ua.FirstName ASC
|
||||
LIMIT 20";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function areFriends($con, $userId1, $userId2) {
|
||||
$sql = "SELECT COUNT(*) FROM Friends
|
||||
WHERE ((PrincipalID = '" . mysqli_real_escape_string($con, $userId1) . "'
|
||||
AND Friend = '" . mysqli_real_escape_string($con, $userId2) . "')
|
||||
OR (PrincipalID = '" . mysqli_real_escape_string($con, $userId2) . "'
|
||||
AND Friend = '" . mysqli_real_escape_string($con, $userId1) . "'))
|
||||
AND Flags > 0";
|
||||
|
||||
$result = mysqli_query($con, $sql);
|
||||
return $result ? mysqli_fetch_row($result)[0] > 0 : false;
|
||||
}
|
||||
|
||||
function getFriendshipStats($con, $userId) {
|
||||
$totalFriends = mysqli_fetch_row(mysqli_query($con, "
|
||||
SELECT COUNT(*) FROM Friends
|
||||
WHERE (PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
OR Friend = '" . mysqli_real_escape_string($con, $userId) . "')
|
||||
AND Flags > 0
|
||||
"))[0];
|
||||
|
||||
$pendingRequests = mysqli_fetch_row(mysqli_query($con, "
|
||||
SELECT COUNT(*) FROM Friends
|
||||
WHERE Friend = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
AND Flags = 0
|
||||
"))[0];
|
||||
|
||||
$sentRequests = mysqli_fetch_row(mysqli_query($con, "
|
||||
SELECT COUNT(*) FROM Friends
|
||||
WHERE PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
AND Flags = 0
|
||||
"))[0];
|
||||
|
||||
$onlineFriends = mysqli_fetch_row(mysqli_query($con, "
|
||||
SELECT COUNT(*) FROM Friends f
|
||||
LEFT JOIN GridUser gu ON (
|
||||
CASE
|
||||
WHEN f.PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "' THEN f.Friend = gu.UserID
|
||||
ELSE f.PrincipalID = gu.UserID
|
||||
END
|
||||
)
|
||||
WHERE (f.PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
OR f.Friend = '" . mysqli_real_escape_string($con, $userId) . "')
|
||||
AND f.Flags > 0
|
||||
AND gu.Login > (UNIX_TIMESTAMP() - 300)
|
||||
"))[0];
|
||||
|
||||
return [
|
||||
'total' => $totalFriends,
|
||||
'pending' => $pendingRequests,
|
||||
'sent' => $sentRequests,
|
||||
'online' => $onlineFriends
|
||||
];
|
||||
}
|
||||
|
||||
// Parameter verarbeiten
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : 'list';
|
||||
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
|
||||
$userId = isset($_GET['user']) ? $_GET['user'] : '';
|
||||
|
||||
// Dummy-Benutzer-ID für Demo (normalerweise aus Session)
|
||||
$currentUserId = '00000000-0000-0000-0000-000000000001'; // Beispiel-User-ID
|
||||
|
||||
?>
|
||||
|
||||
<div class="container-fluid mt-4">
|
||||
<div class="row">
|
||||
<!-- Sidebar -->
|
||||
<div class="col-md-3">
|
||||
<!-- Freunde suchen -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-search"></i> Neue Freunde finden</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="GET" action="friends.php">
|
||||
<input type="hidden" name="action" value="search">
|
||||
<div class="mb-3">
|
||||
<label for="search" class="form-label">Benutzer suchen:</label>
|
||||
<input type="text" class="form-control" id="search" name="search"
|
||||
value="<?php echo htmlspecialchars($search); ?>"
|
||||
placeholder="Vor- oder Nachname...">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
<i class="fas fa-search"></i> Suchen
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Freunde-Navigation -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-users"></i> Navigation</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-grid gap-2">
|
||||
<a href="friends.php?action=list" class="btn btn-outline-primary btn-sm">
|
||||
<i class="fas fa-list"></i> Alle Freunde
|
||||
</a>
|
||||
<a href="friends.php?action=online" class="btn btn-outline-success btn-sm">
|
||||
<i class="fas fa-circle text-success"></i> Online Freunde
|
||||
</a>
|
||||
<a href="friends.php?action=requests" class="btn btn-outline-warning btn-sm">
|
||||
<i class="fas fa-clock"></i> Anfragen
|
||||
</a>
|
||||
<a href="friends.php?action=search" class="btn btn-outline-info btn-sm">
|
||||
<i class="fas fa-user-plus"></i> Neue Freunde
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiken -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-chart-bar"></i> Freunde-Statistiken</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php $stats = getFriendshipStats($con, $currentUserId); ?>
|
||||
|
||||
<div class="text-center">
|
||||
<div class="mb-2">
|
||||
<h4 class="text-primary"><?php echo number_format($stats['total'], 0, ',', '.'); ?></h4>
|
||||
<small class="text-muted">Gesamt Freunde</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<h4 class="text-success"><?php echo number_format($stats['online'], 0, ',', '.'); ?></h4>
|
||||
<small class="text-muted">Aktuell online</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<h4 class="text-warning"><?php echo number_format($stats['pending'], 0, ',', '.'); ?></h4>
|
||||
<small class="text-muted">Offene Anfragen</small>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-info"><?php echo number_format($stats['sent'], 0, ',', '.'); ?></h4>
|
||||
<small class="text-muted">Gesendete Anfragen</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hauptinhalt -->
|
||||
<div class="col-md-9">
|
||||
<?php if ($action == 'search'): ?>
|
||||
<!-- Benutzersuche -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4><i class="fas fa-user-plus"></i> Neue Freunde finden</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="GET" action="friends.php" class="mb-4">
|
||||
<input type="hidden" name="action" value="search">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<input type="text" class="form-control form-control-lg"
|
||||
name="search"
|
||||
value="<?php echo htmlspecialchars($search); ?>"
|
||||
placeholder="Benutzername eingeben..."
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<button type="submit" class="btn btn-primary btn-lg w-100">
|
||||
<i class="fas fa-search"></i> Suchen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if ($search): ?>
|
||||
<?php
|
||||
$searchResult = searchUsers($con, $search);
|
||||
$searchCount = mysqli_num_rows($searchResult);
|
||||
?>
|
||||
|
||||
<h6><?php echo $searchCount; ?> Benutzer gefunden für "<?php echo htmlspecialchars($search); ?>"</h6>
|
||||
|
||||
<?php if ($searchCount > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($user = mysqli_fetch_assoc($searchResult)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card">
|
||||
<?php if ($user['profileImage'] && $user['profileImage'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $user['profileImage']; ?>"
|
||||
class="card-img-top"
|
||||
alt="Profilbild"
|
||||
style="height: 120px; object-fit: cover;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">
|
||||
<?php echo htmlspecialchars($user['FirstName'] . ' ' . $user['LastName']); ?>
|
||||
<?php if ($user['Login'] && $user['Login'] > (time() - 300)): ?>
|
||||
<span class="badge bg-success ms-1">Online</span>
|
||||
<?php elseif ($user['Login'] && $user['Login'] > (time() - 86400)): ?>
|
||||
<span class="badge bg-warning ms-1">Heute aktiv</span>
|
||||
<?php endif; ?>
|
||||
</h6>
|
||||
|
||||
<?php if ($user['profileAboutText']): ?>
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo htmlspecialchars(substr($user['profileAboutText'], 0, 80) . (strlen($user['profileAboutText']) > 80 ? '...' : '')); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<?php if (areFriends($con, $currentUserId, $user['PrincipalID'])): ?>
|
||||
<span class="btn btn-success btn-sm disabled">
|
||||
<i class="fas fa-check"></i> Bereits Freunde
|
||||
</span>
|
||||
<?php elseif ($user['PrincipalID'] == $currentUserId): ?>
|
||||
<span class="btn btn-secondary btn-sm disabled">
|
||||
<i class="fas fa-user"></i> Das sind Sie
|
||||
</span>
|
||||
<?php else: ?>
|
||||
<button class="btn btn-primary btn-sm" onclick="sendFriendRequest('<?php echo $user['PrincipalID']; ?>')">
|
||||
<i class="fas fa-user-plus"></i> Freundschaftsanfrage senden
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
|
||||
<a href="profile.php?user=<?php echo $user['PrincipalID']; ?>"
|
||||
class="btn btn-outline-info btn-sm">
|
||||
<i class="fas fa-eye"></i> Profil anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-4">
|
||||
<i class="fas fa-user-times fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine Benutzer gefunden</h5>
|
||||
<p class="text-muted">Versuchen Sie es mit anderen Suchbegriffen.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php elseif ($action == 'requests'): ?>
|
||||
<!-- Freundschaftsanfragen -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4><i class="fas fa-clock"></i> Freundschaftsanfragen</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$requestsResult = getFriendRequests($con, $currentUserId);
|
||||
$requestsCount = mysqli_num_rows($requestsResult);
|
||||
?>
|
||||
|
||||
<h6><?php echo $requestsCount; ?> offene Anfragen</h6>
|
||||
|
||||
<?php if ($requestsCount > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($request = mysqli_fetch_assoc($requestsResult)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card border-warning">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<i class="fas fa-clock"></i> Freundschaftsanfrage
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">
|
||||
<?php echo htmlspecialchars($request['RequesterFirstName'] . ' ' . $request['RequesterLastName']); ?>
|
||||
</h6>
|
||||
<p class="text-muted small">möchte Ihr Freund werden.</p>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<button class="btn btn-success btn-sm"
|
||||
onclick="acceptFriendRequest('<?php echo $request['PrincipalID']; ?>')">
|
||||
<i class="fas fa-check"></i> Akzeptieren
|
||||
</button>
|
||||
<button class="btn btn-danger btn-sm"
|
||||
onclick="declineFriendRequest('<?php echo $request['PrincipalID']; ?>')">
|
||||
<i class="fas fa-times"></i> Ablehnen
|
||||
</button>
|
||||
<a href="profile.php?user=<?php echo $request['PrincipalID']; ?>"
|
||||
class="btn btn-outline-info btn-sm">
|
||||
<i class="fas fa-eye"></i> Profil anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-inbox fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine offenen Anfragen</h5>
|
||||
<p class="text-muted">Sie haben derzeit keine Freundschaftsanfragen.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php elseif ($action == 'online'): ?>
|
||||
<!-- Online Freunde -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4><i class="fas fa-circle text-success"></i> Online Freunde</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$onlineResult = getOnlineFriends($con, $currentUserId);
|
||||
$onlineCount = mysqli_num_rows($onlineResult);
|
||||
?>
|
||||
|
||||
<h6><?php echo $onlineCount; ?> Freunde sind aktuell online</h6>
|
||||
|
||||
<?php if ($onlineCount > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($friend = mysqli_fetch_assoc($onlineResult)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card border-success">
|
||||
<div class="card-header bg-success text-white">
|
||||
<i class="fas fa-circle"></i> ONLINE
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">
|
||||
<?php echo htmlspecialchars($friend['FirstName'] . ' ' . $friend['LastName']); ?>
|
||||
</h6>
|
||||
<p class="text-muted small">
|
||||
Online seit: <?php echo date('H:i', $friend['Login']); ?>
|
||||
</p>
|
||||
<?php if ($friend['Position']): ?>
|
||||
<p class="text-muted small">
|
||||
📍 Position: <?php echo htmlspecialchars($friend['Position']); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<button class="btn btn-primary btn-sm"
|
||||
onclick="sendInstantMessage('<?php echo $friend['PrincipalID'] ?? $friend['Friend']; ?>')">
|
||||
<i class="fas fa-envelope"></i> Nachricht senden
|
||||
</button>
|
||||
<a href="profile.php?user=<?php echo $friend['PrincipalID'] ?? $friend['Friend']; ?>"
|
||||
class="btn btn-outline-info btn-sm">
|
||||
<i class="fas fa-eye"></i> Profil anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-user-clock fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine Freunde online</h5>
|
||||
<p class="text-muted">Derzeit sind keine Ihrer Freunde online.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<!-- Alle Freunde -->
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h4><i class="fas fa-users"></i> Meine Freunde</h4>
|
||||
<div>
|
||||
<a href="friends.php?action=online" class="btn btn-success btn-sm">
|
||||
<i class="fas fa-circle"></i> Online (<?php echo $stats['online']; ?>)
|
||||
</a>
|
||||
<a href="friends.php?action=requests" class="btn btn-warning btn-sm">
|
||||
<i class="fas fa-clock"></i> Anfragen (<?php echo $stats['pending']; ?>)
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$friendsResult = getAllFriends($con, $currentUserId);
|
||||
$friendsCount = mysqli_num_rows($friendsResult);
|
||||
?>
|
||||
|
||||
<h6><?php echo $friendsCount; ?> Freunde insgesamt</h6>
|
||||
|
||||
<?php if ($friendsCount > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($friend = mysqli_fetch_assoc($friendsResult)): ?>
|
||||
<?php
|
||||
// Bestimme ob dieser Benutzer der Principal oder der Friend ist
|
||||
$isOnline = $friend['LastLogin'] && $friend['LastLogin'] > (time() - 300);
|
||||
$isRecentlyActive = $friend['LastLogin'] && $friend['LastLogin'] > (time() - 86400);
|
||||
|
||||
$displayName = '';
|
||||
$friendUserId = '';
|
||||
|
||||
if ($friend['PrincipalID'] == $currentUserId) {
|
||||
$displayName = $friend['FriendFirstName'] . ' ' . $friend['FriendLastName'];
|
||||
$friendUserId = $friend['Friend'];
|
||||
} else {
|
||||
$displayName = $friend['UserFirstName'] . ' ' . $friend['UserLastName'];
|
||||
$friendUserId = $friend['PrincipalID'];
|
||||
}
|
||||
?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card <?php echo $isOnline ? 'border-success' : ($isRecentlyActive ? 'border-warning' : ''); ?>">
|
||||
<?php if ($isOnline): ?>
|
||||
<div class="card-header bg-success text-white py-2">
|
||||
<small><i class="fas fa-circle"></i> ONLINE</small>
|
||||
</div>
|
||||
<?php elseif ($isRecentlyActive): ?>
|
||||
<div class="card-header bg-warning text-dark py-2">
|
||||
<small><i class="fas fa-clock"></i> Heute aktiv</small>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-body">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($displayName); ?></h6>
|
||||
|
||||
<?php if ($friend['LastLogin']): ?>
|
||||
<p class="text-muted small">
|
||||
Letzter Login: <?php echo date('d.m.Y H:i', $friend['LastLogin']); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<?php if ($isOnline): ?>
|
||||
<button class="btn btn-primary btn-sm"
|
||||
onclick="sendInstantMessage('<?php echo $friendUserId; ?>')">
|
||||
<i class="fas fa-envelope"></i> Nachricht senden
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
|
||||
<a href="profile.php?user=<?php echo $friendUserId; ?>"
|
||||
class="btn btn-outline-info btn-sm">
|
||||
<i class="fas fa-eye"></i> Profil anzeigen
|
||||
</a>
|
||||
|
||||
<button class="btn btn-outline-danger btn-sm"
|
||||
onclick="removeFriend('<?php echo $friendUserId; ?>', '<?php echo htmlspecialchars($displayName); ?>')">
|
||||
<i class="fas fa-user-times"></i> Freundschaft beenden
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-user-friends fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine Freunde</h5>
|
||||
<p class="text-muted">Sie haben noch keine Freunde hinzugefügt.</p>
|
||||
<a href="friends.php?action=search" class="btn btn-primary">
|
||||
<i class="fas fa-user-plus"></i> Neue Freunde finden
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card {
|
||||
transition: box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.border-success {
|
||||
border-width: 2px !important;
|
||||
}
|
||||
|
||||
.border-warning {
|
||||
border-width: 2px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Friend Management Functions
|
||||
function sendFriendRequest(userId) {
|
||||
if (confirm('Möchten Sie diesem Benutzer eine Freundschaftsanfrage senden?')) {
|
||||
// AJAX-Call um Freundschaftsanfrage zu senden
|
||||
fetch('friends_api.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action: 'send_request',
|
||||
user_id: userId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert('Freundschaftsanfrage wurde gesendet!');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Fehler: ' + data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Ein Fehler ist aufgetreten.');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function acceptFriendRequest(userId) {
|
||||
if (confirm('Möchten Sie diese Freundschaftsanfrage akzeptieren?')) {
|
||||
// AJAX-Call um Freundschaftsanfrage zu akzeptieren
|
||||
fetch('friends_api.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action: 'accept_request',
|
||||
user_id: userId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert('Freundschaftsanfrage wurde akzeptiert!');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Fehler: ' + data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function declineFriendRequest(userId) {
|
||||
if (confirm('Möchten Sie diese Freundschaftsanfrage ablehnen?')) {
|
||||
// AJAX-Call um Freundschaftsanfrage abzulehnen
|
||||
fetch('friends_api.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action: 'decline_request',
|
||||
user_id: userId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert('Freundschaftsanfrage wurde abgelehnt.');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Fehler: ' + data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function removeFriend(userId, userName) {
|
||||
if (confirm('Möchten Sie die Freundschaft mit ' + userName + ' wirklich beenden?')) {
|
||||
// AJAX-Call um Freundschaft zu beenden
|
||||
fetch('friends_api.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action: 'remove_friend',
|
||||
user_id: userId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert('Freundschaft wurde beendet.');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Fehler: ' + data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function sendInstantMessage(userId) {
|
||||
// Weiterleitung zu Message-System (falls vorhanden)
|
||||
window.location.href = 'message.php?action=compose&to=' + userId;
|
||||
}
|
||||
|
||||
// Auto-refresh für Online-Status (alle 30 Sekunden)
|
||||
if (window.location.href.includes('action=online')) {
|
||||
setInterval(function() {
|
||||
location.reload();
|
||||
}, 30000);
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php
|
||||
mysqli_close($con);
|
||||
include_once "include/footerModern.php";
|
||||
?>
|
||||
+694
@@ -0,0 +1,694 @@
|
||||
<?php
|
||||
$title = "Grid-Suche";
|
||||
include_once "include/config.php";
|
||||
include_once "include/" . HEADER_FILE;
|
||||
|
||||
// Datenbankverbindung
|
||||
$con = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
|
||||
if (!$con) {
|
||||
die("Datenbankverbindung fehlgeschlagen: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Suchfunktionen
|
||||
function searchAll($con, $query, $type = 'all') {
|
||||
$results = [
|
||||
'users' => [],
|
||||
'regions' => [],
|
||||
'places' => [],
|
||||
'classifieds' => [],
|
||||
'groups' => [],
|
||||
'events' => []
|
||||
];
|
||||
|
||||
$query = mysqli_real_escape_string($con, $query);
|
||||
|
||||
// Benutzer suchen
|
||||
if ($type == 'all' || $type == 'users') {
|
||||
$sql = "SELECT ua.PrincipalID, ua.FirstName, ua.LastName,
|
||||
up.profileAboutText, up.profileImage, gu.Login
|
||||
FROM UserAccounts ua
|
||||
LEFT JOIN userprofile up ON ua.PrincipalID = up.useruuid
|
||||
LEFT JOIN GridUser gu ON ua.PrincipalID = gu.UserID
|
||||
WHERE (ua.FirstName LIKE '%$query%' OR ua.LastName LIKE '%$query%'
|
||||
OR up.profileAboutText LIKE '%$query%')
|
||||
ORDER BY gu.Login DESC
|
||||
LIMIT 10";
|
||||
$results['users'] = mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
// Regionen suchen
|
||||
if ($type == 'all' || $type == 'regions') {
|
||||
$sql = "SELECT r.*, ua.FirstName as OwnerFirstName, ua.LastName as OwnerLastName
|
||||
FROM regions r
|
||||
LEFT JOIN UserAccounts ua ON r.owner_uuid = ua.PrincipalID
|
||||
WHERE (r.regionName LIKE '%$query%' OR r.serverURI LIKE '%$query%')
|
||||
ORDER BY r.regionName
|
||||
LIMIT 10";
|
||||
$results['regions'] = mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
// Places/Picks suchen
|
||||
if ($type == 'all' || $type == 'places') {
|
||||
$sql = "SELECT p.*, ua.FirstName, ua.LastName
|
||||
FROM userpicks p
|
||||
LEFT JOIN UserAccounts ua ON p.creatoruuid = ua.PrincipalID
|
||||
WHERE (p.name LIKE '%$query%' OR p.description LIKE '%$query%' OR p.simname LIKE '%$query%')
|
||||
AND p.enabled = 1
|
||||
ORDER BY p.toppick DESC, p.name
|
||||
LIMIT 10";
|
||||
$results['places'] = mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
// Klassifizierte Anzeigen suchen
|
||||
if ($type == 'all' || $type == 'classifieds') {
|
||||
$sql = "SELECT c.*, ua.FirstName, ua.LastName
|
||||
FROM classifieds c
|
||||
LEFT JOIN UserAccounts ua ON c.creatoruuid = ua.PrincipalID
|
||||
WHERE (c.name LIKE '%$query%' OR c.description LIKE '%$query%')
|
||||
ORDER BY c.creationdate DESC
|
||||
LIMIT 10";
|
||||
$results['classifieds'] = mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
// Gruppen suchen
|
||||
if ($type == 'all' || $type == 'groups') {
|
||||
$sql = "SELECT og.*, ua.FirstName as OwnerFirstName, ua.LastName as OwnerLastName,
|
||||
COUNT(ogm.PrincipalID) as MemberCount
|
||||
FROM os_groups og
|
||||
LEFT JOIN UserAccounts ua ON og.OwnerID = ua.PrincipalID
|
||||
LEFT JOIN os_groups_membership ogm ON og.GroupID = ogm.GroupID
|
||||
WHERE (og.Name LIKE '%$query%' OR og.Charter LIKE '%$query%')
|
||||
AND og.ShowInList = 1
|
||||
GROUP BY og.GroupID
|
||||
ORDER BY MemberCount DESC
|
||||
LIMIT 10";
|
||||
$results['groups'] = mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
function getPopularSearches($con) {
|
||||
// Simulierte beliebte Suchbegriffe (normalerweise aus Suchlog)
|
||||
return [
|
||||
'Shopping' => 25,
|
||||
'Club' => 18,
|
||||
'Beach' => 15,
|
||||
'Mall' => 12,
|
||||
'Casino' => 10,
|
||||
'Art Gallery' => 8,
|
||||
'Music' => 7,
|
||||
'Dance' => 6
|
||||
];
|
||||
}
|
||||
|
||||
function getSearchSuggestions($con, $query) {
|
||||
$suggestions = [];
|
||||
$query = mysqli_real_escape_string($con, $query);
|
||||
|
||||
// Regionsvorschläge
|
||||
$sql = "SELECT DISTINCT regionName FROM regions WHERE regionName LIKE '$query%' LIMIT 5";
|
||||
$result = mysqli_query($con, $sql);
|
||||
while ($row = mysqli_fetch_assoc($result)) {
|
||||
$suggestions[] = $row['regionName'];
|
||||
}
|
||||
|
||||
// Benutzervorschläge
|
||||
$sql = "SELECT CONCAT(FirstName, ' ', LastName) as fullName FROM UserAccounts
|
||||
WHERE (FirstName LIKE '$query%' OR LastName LIKE '$query%') LIMIT 5";
|
||||
$result = mysqli_query($con, $sql);
|
||||
while ($row = mysqli_fetch_assoc($result)) {
|
||||
$suggestions[] = $row['fullName'];
|
||||
}
|
||||
|
||||
return $suggestions;
|
||||
}
|
||||
|
||||
// Parameter verarbeiten
|
||||
$query = isset($_GET['q']) ? trim($_GET['q']) : '';
|
||||
$type = isset($_GET['type']) ? $_GET['type'] : 'all';
|
||||
$suggestions = isset($_GET['suggestions']) ? true : false;
|
||||
|
||||
// AJAX-Anfrage für Vorschläge
|
||||
if ($suggestions && $query) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(getSearchSuggestions($con, $query));
|
||||
exit;
|
||||
}
|
||||
|
||||
// Suchergebnisse abrufen
|
||||
$results = [];
|
||||
$totalResults = 0;
|
||||
if ($query) {
|
||||
$results = searchAll($con, $query, $type);
|
||||
|
||||
// Ergebnisse zählen
|
||||
foreach ($results as $resultType => $resultSet) {
|
||||
if ($resultSet) {
|
||||
$totalResults += mysqli_num_rows($resultSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="container-fluid mt-4">
|
||||
<div class="row">
|
||||
<!-- Sidebar -->
|
||||
<div class="col-md-3">
|
||||
<!-- Suchfilter -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-filter"></i> Suchfilter</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="GET" action="gridsearch.php">
|
||||
<input type="hidden" name="q" value="<?php echo htmlspecialchars($query); ?>">
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Suchbereich:</label>
|
||||
<select name="type" class="form-select" onchange="this.form.submit()">
|
||||
<option value="all" <?php echo ($type == 'all') ? 'selected' : ''; ?>>Alles durchsuchen</option>
|
||||
<option value="users" <?php echo ($type == 'users') ? 'selected' : ''; ?>>Nur Benutzer</option>
|
||||
<option value="regions" <?php echo ($type == 'regions') ? 'selected' : ''; ?>>Nur Regionen</option>
|
||||
<option value="places" <?php echo ($type == 'places') ? 'selected' : ''; ?>>Nur Orte/Places</option>
|
||||
<option value="classifieds" <?php echo ($type == 'classifieds') ? 'selected' : ''; ?>>Nur Anzeigen</option>
|
||||
<option value="groups" <?php echo ($type == 'groups') ? 'selected' : ''; ?>>Nur Gruppen</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Beliebte Suchbegriffe -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-fire"></i> Beliebte Suchbegriffe</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php $popularSearches = getPopularSearches($con); ?>
|
||||
<div class="d-flex flex-wrap gap-1">
|
||||
<?php foreach ($popularSearches as $term => $count): ?>
|
||||
<a href="gridsearch.php?q=<?php echo urlencode($term); ?>" class="badge bg-primary text-decoration-none">
|
||||
<?php echo htmlspecialchars($term); ?> (<?php echo $count; ?>)
|
||||
</a>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Suchstatistiken -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-chart-bar"></i> Grid-Inhalte</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$contentStats = [
|
||||
'users' => mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM UserAccounts"))[0],
|
||||
'regions' => mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM regions"))[0],
|
||||
'places' => mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM userpicks WHERE enabled = 1"))[0],
|
||||
'classifieds' => mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM classifieds"))[0],
|
||||
'groups' => mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM os_groups WHERE ShowInList = 1"))[0]
|
||||
];
|
||||
?>
|
||||
|
||||
<div class="small">
|
||||
<div class="d-flex justify-content-between mb-1">
|
||||
<span>👤 Benutzer:</span>
|
||||
<strong><?php echo number_format($contentStats['users'], 0, ',', '.'); ?></strong>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-1">
|
||||
<span>🌍 Regionen:</span>
|
||||
<strong><?php echo number_format($contentStats['regions'], 0, ',', '.'); ?></strong>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-1">
|
||||
<span>📍 Orte:</span>
|
||||
<strong><?php echo number_format($contentStats['places'], 0, ',', '.'); ?></strong>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-1">
|
||||
<span>📢 Anzeigen:</span>
|
||||
<strong><?php echo number_format($contentStats['classifieds'], 0, ',', '.'); ?></strong>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between">
|
||||
<span>👥 Gruppen:</span>
|
||||
<strong><?php echo number_format($contentStats['groups'], 0, ',', '.'); ?></strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hauptinhalt -->
|
||||
<div class="col-md-9">
|
||||
<!-- Suchformular -->
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h4><i class="fas fa-search"></i> Grid-Suche</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="GET" action="gridsearch.php">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<input type="text" name="q" class="form-control form-control-lg"
|
||||
value="<?php echo htmlspecialchars($query); ?>"
|
||||
placeholder="Durchsuchen Sie Benutzer, Regionen, Orte, Anzeigen und Gruppen..."
|
||||
id="searchInput"
|
||||
autocomplete="off">
|
||||
<div id="searchSuggestions" class="dropdown-menu w-100" style="display: none;"></div>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<select name="type" class="form-select form-select-lg">
|
||||
<option value="all">Alles</option>
|
||||
<option value="users" <?php echo ($type == 'users') ? 'selected' : ''; ?>>Benutzer</option>
|
||||
<option value="regions" <?php echo ($type == 'regions') ? 'selected' : ''; ?>>Regionen</option>
|
||||
<option value="places" <?php echo ($type == 'places') ? 'selected' : ''; ?>>Orte</option>
|
||||
<option value="classifieds" <?php echo ($type == 'classifieds') ? 'selected' : ''; ?>>Anzeigen</option>
|
||||
<option value="groups" <?php echo ($type == 'groups') ? 'selected' : ''; ?>>Gruppen</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="submit" class="btn btn-primary btn-lg w-100">
|
||||
<i class="fas fa-search"></i> Suchen
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($query && $totalResults > 0): ?>
|
||||
<!-- Suchergebnisse -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-list"></i> Suchergebnisse für "<?php echo htmlspecialchars($query); ?>"</h5>
|
||||
<small class="text-muted"><?php echo number_format($totalResults, 0, ',', '.'); ?> Ergebnisse gefunden</small>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<!-- Benutzer-Ergebnisse -->
|
||||
<?php if (($type == 'all' || $type == 'users') && mysqli_num_rows($results['users']) > 0): ?>
|
||||
<div class="mb-4">
|
||||
<h6><i class="fas fa-users text-primary"></i> Benutzer</h6>
|
||||
<div class="row">
|
||||
<?php while ($user = mysqli_fetch_assoc($results['users'])): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card">
|
||||
<?php if ($user['profileImage'] && $user['profileImage'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $user['profileImage']; ?>"
|
||||
class="card-img-top"
|
||||
alt="Profilbild"
|
||||
style="height: 100px; object-fit: cover;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">
|
||||
<?php echo htmlspecialchars($user['FirstName'] . ' ' . $user['LastName']); ?>
|
||||
<?php if ($user['Login'] && $user['Login'] > (time() - 300)): ?>
|
||||
<span class="badge bg-success ms-1">Online</span>
|
||||
<?php endif; ?>
|
||||
</h6>
|
||||
|
||||
<?php if ($user['profileAboutText']): ?>
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo htmlspecialchars(substr($user['profileAboutText'], 0, 60) . (strlen($user['profileAboutText']) > 60 ? '...' : '')); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<a href="profile.php?user=<?php echo $user['PrincipalID']; ?>"
|
||||
class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-eye"></i> Profil anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Regionen-Ergebnisse -->
|
||||
<?php if (($type == 'all' || $type == 'regions') && mysqli_num_rows($results['regions']) > 0): ?>
|
||||
<div class="mb-4">
|
||||
<h6><i class="fas fa-globe text-success"></i> Regionen</h6>
|
||||
<div class="row">
|
||||
<?php while ($region = mysqli_fetch_assoc($results['regions'])): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($region['regionName']); ?></h6>
|
||||
|
||||
<p class="card-text small">
|
||||
<strong>Position:</strong> <?php echo htmlspecialchars($region['locX'] . ', ' . $region['locY']); ?><br>
|
||||
<strong>Größe:</strong> <?php echo htmlspecialchars($region['sizeX'] . 'x' . $region['sizeY']); ?><br>
|
||||
<?php if ($region['OwnerFirstName']): ?>
|
||||
<strong>Eigentümer:</strong> <?php echo htmlspecialchars($region['OwnerFirstName'] . ' ' . $region['OwnerLastName']); ?>
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
|
||||
<div class="d-grid gap-1">
|
||||
<a href="secondlife://<?php echo htmlspecialchars($region['regionName']); ?>/128/128/25"
|
||||
class="btn btn-success btn-sm">
|
||||
<i class="fas fa-rocket"></i> Teleportieren
|
||||
</a>
|
||||
<a href="maptile.php?region=<?php echo urlencode($region['regionName']); ?>"
|
||||
class="btn btn-outline-info btn-sm">
|
||||
<i class="fas fa-map"></i> Auf Karte anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Places-Ergebnisse -->
|
||||
<?php if (($type == 'all' || $type == 'places') && mysqli_num_rows($results['places']) > 0): ?>
|
||||
<div class="mb-4">
|
||||
<h6><i class="fas fa-map-marker-alt text-info"></i> Orte & Places</h6>
|
||||
<div class="row">
|
||||
<?php while ($place = mysqli_fetch_assoc($results['places'])): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card <?php echo $place['toppick'] ? 'border-warning' : ''; ?>">
|
||||
<?php if ($place['toppick']): ?>
|
||||
<div class="card-header bg-warning text-dark py-1 text-center">
|
||||
<small><i class="fas fa-star"></i> TOP PICK</small>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($place['snapshotuuid'] && $place['snapshotuuid'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $place['snapshotuuid']; ?>"
|
||||
class="card-img-top"
|
||||
alt="Place Bild"
|
||||
style="height: 100px; object-fit: cover;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-body">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($place['name']); ?></h6>
|
||||
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo htmlspecialchars(substr($place['description'], 0, 60) . (strlen($place['description']) > 60 ? '...' : '')); ?>
|
||||
</p>
|
||||
|
||||
<small class="text-muted">
|
||||
von <?php echo htmlspecialchars($place['FirstName'] . ' ' . $place['LastName']); ?>
|
||||
</small>
|
||||
|
||||
<div class="d-grid gap-1 mt-2">
|
||||
<a href="picks.php?action=view&id=<?php echo $place['pickuuid']; ?>"
|
||||
class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-eye"></i> Details anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Anzeigen-Ergebnisse -->
|
||||
<?php if (($type == 'all' || $type == 'classifieds') && mysqli_num_rows($results['classifieds']) > 0): ?>
|
||||
<div class="mb-4">
|
||||
<h6><i class="fas fa-ad text-warning"></i> Klassifizierte Anzeigen</h6>
|
||||
<div class="row">
|
||||
<?php while ($classified = mysqli_fetch_assoc($results['classifieds'])): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card">
|
||||
<?php if ($classified['snapshotuuid'] && $classified['snapshotuuid'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $classified['snapshotuuid']; ?>"
|
||||
class="card-img-top"
|
||||
alt="Anzeigenbild"
|
||||
style="height: 100px; object-fit: cover;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-body">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($classified['name']); ?></h6>
|
||||
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo htmlspecialchars(substr($classified['description'], 0, 60) . (strlen($classified['description']) > 60 ? '...' : '')); ?>
|
||||
</p>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<span class="badge bg-success">L$ <?php echo number_format($classified['priceforlisting'], 0, ',', '.'); ?></span>
|
||||
<small class="text-muted">
|
||||
von <?php echo htmlspecialchars($classified['FirstName'] . ' ' . $classified['LastName']); ?>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="d-grid mt-2">
|
||||
<a href="classifieds.php?action=view&id=<?php echo $classified['classifieduuid']; ?>"
|
||||
class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-eye"></i> Details anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Gruppen-Ergebnisse -->
|
||||
<?php if (($type == 'all' || $type == 'groups') && mysqli_num_rows($results['groups']) > 0): ?>
|
||||
<div class="mb-4">
|
||||
<h6><i class="fas fa-users text-secondary"></i> Gruppen</h6>
|
||||
<div class="row">
|
||||
<?php while ($group = mysqli_fetch_assoc($results['groups'])): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">
|
||||
<?php echo htmlspecialchars($group['Name']); ?>
|
||||
<?php if ($group['OpenEnrollment']): ?>
|
||||
<span class="badge bg-success ms-1">Offen</span>
|
||||
<?php endif; ?>
|
||||
</h6>
|
||||
|
||||
<?php if ($group['Charter']): ?>
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo htmlspecialchars(substr($group['Charter'], 0, 60) . (strlen($group['Charter']) > 60 ? '...' : '')); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<span class="badge bg-primary"><?php echo $group['MemberCount']; ?> Mitglieder</span>
|
||||
<small class="text-muted">
|
||||
von <?php echo htmlspecialchars($group['OwnerFirstName'] . ' ' . $group['OwnerLastName']); ?>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<a href="groups.php?action=view&id=<?php echo $group['GroupID']; ?>"
|
||||
class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-eye"></i> Details anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php elseif ($query && $totalResults == 0): ?>
|
||||
<!-- Keine Ergebnisse -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="fas fa-search fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine Ergebnisse gefunden</h5>
|
||||
<p class="text-muted">
|
||||
Für Ihre Suche nach "<?php echo htmlspecialchars($query); ?>" wurden keine Ergebnisse gefunden.
|
||||
</p>
|
||||
<div class="mt-3">
|
||||
<h6>Suchvorschläge:</h6>
|
||||
<ul class="list-unstyled">
|
||||
<li>• Überprüfen Sie die Rechtschreibung</li>
|
||||
<li>• Verwenden Sie allgemeinere Begriffe</li>
|
||||
<li>• Probieren Sie verschiedene Suchbereiche aus</li>
|
||||
<li>• Nutzen Sie die beliebten Suchbegriffe in der Sidebar</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<!-- Startansicht ohne Suchanfrage -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-body text-center py-5">
|
||||
<i class="fas fa-search fa-3x text-primary mb-3"></i>
|
||||
<h5>Willkommen zur Grid-Suche</h5>
|
||||
<p class="text-muted">
|
||||
Durchsuchen Sie unser gesamtes Grid nach Benutzern, Regionen, interessanten Orten,
|
||||
klassifizierten Anzeigen und Gruppen.
|
||||
</p>
|
||||
|
||||
<!-- Schnellzugriffe -->
|
||||
<div class="row mt-4">
|
||||
<div class="col-md-6 col-lg-3 mb-2">
|
||||
<a href="gridsearch.php?type=users" class="btn btn-outline-primary w-100">
|
||||
<i class="fas fa-users"></i><br>
|
||||
<small>Benutzer durchsuchen</small>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg-3 mb-2">
|
||||
<a href="gridsearch.php?type=regions" class="btn btn-outline-success w-100">
|
||||
<i class="fas fa-globe"></i><br>
|
||||
<small>Regionen entdecken</small>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg-3 mb-2">
|
||||
<a href="gridsearch.php?type=places" class="btn btn-outline-info w-100">
|
||||
<i class="fas fa-map-marker-alt"></i><br>
|
||||
<small>Interessante Orte</small>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-md-6 col-lg-3 mb-2">
|
||||
<a href="gridsearch.php?type=groups" class="btn btn-outline-secondary w-100">
|
||||
<i class="fas fa-users"></i><br>
|
||||
<small>Gruppen beitreten</small>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card {
|
||||
transition: transform 0.2s, box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.card-img-top {
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.card:hover .card-img-top {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
#searchSuggestions {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background-color: var(--bs-primary);
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Search Suggestions
|
||||
let suggestionTimeout;
|
||||
const searchInput = document.getElementById('searchInput');
|
||||
const suggestionsDiv = document.getElementById('searchSuggestions');
|
||||
|
||||
searchInput.addEventListener('input', function() {
|
||||
const query = this.value.trim();
|
||||
|
||||
clearTimeout(suggestionTimeout);
|
||||
|
||||
if (query.length >= 2) {
|
||||
suggestionTimeout = setTimeout(() => {
|
||||
fetch(`gridsearch.php?suggestions=1&q=${encodeURIComponent(query)}`)
|
||||
.then(response => response.json())
|
||||
.then(suggestions => {
|
||||
showSuggestions(suggestions);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error fetching suggestions:', error);
|
||||
});
|
||||
}, 300);
|
||||
} else {
|
||||
hideSuggestions();
|
||||
}
|
||||
});
|
||||
|
||||
function showSuggestions(suggestions) {
|
||||
if (suggestions.length === 0) {
|
||||
hideSuggestions();
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '';
|
||||
suggestions.forEach(suggestion => {
|
||||
html += `<a class="dropdown-item" href="#" onclick="selectSuggestion('${suggestion.replace(/'/g, "\\'")}'); return false;">
|
||||
<i class="fas fa-search me-2"></i>${suggestion}
|
||||
</a>`;
|
||||
});
|
||||
|
||||
suggestionsDiv.innerHTML = html;
|
||||
suggestionsDiv.style.display = 'block';
|
||||
}
|
||||
|
||||
function hideSuggestions() {
|
||||
suggestionsDiv.style.display = 'none';
|
||||
}
|
||||
|
||||
function selectSuggestion(suggestion) {
|
||||
searchInput.value = suggestion;
|
||||
hideSuggestions();
|
||||
searchInput.form.submit();
|
||||
}
|
||||
|
||||
// Hide suggestions when clicking outside
|
||||
document.addEventListener('click', function(e) {
|
||||
if (!searchInput.contains(e.target) && !suggestionsDiv.contains(e.target)) {
|
||||
hideSuggestions();
|
||||
}
|
||||
});
|
||||
|
||||
// Focus search input on page load
|
||||
searchInput.focus();
|
||||
|
||||
// Highlight search terms in results
|
||||
const searchTerm = "<?php echo addslashes($query); ?>";
|
||||
if (searchTerm) {
|
||||
highlightSearchTerms(searchTerm);
|
||||
}
|
||||
|
||||
function highlightSearchTerms(term) {
|
||||
const regex = new RegExp(`(${term})`, 'gi');
|
||||
const textNodes = document.evaluate(
|
||||
"//text()[not(ancestor::script or ancestor::style)]",
|
||||
document,
|
||||
null,
|
||||
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
|
||||
null
|
||||
);
|
||||
|
||||
for (let i = 0; i < textNodes.snapshotLength; i++) {
|
||||
const node = textNodes.snapshotItem(i);
|
||||
if (node.textContent.toLowerCase().includes(term.toLowerCase())) {
|
||||
const parent = node.parentNode;
|
||||
const newContent = node.textContent.replace(regex, '<mark>$1</mark>');
|
||||
parent.innerHTML = parent.innerHTML.replace(node.textContent, newContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<?php
|
||||
mysqli_close($con);
|
||||
include_once "include/footerModern.php";
|
||||
?>
|
||||
+894
@@ -0,0 +1,894 @@
|
||||
<?php
|
||||
$title = "Gruppenverwaltung";
|
||||
include_once "include/config.php";
|
||||
include_once "include/" . HEADER_FILE;
|
||||
|
||||
// Datenbankverbindung
|
||||
$con = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
|
||||
if (!$con) {
|
||||
die("Datenbankverbindung fehlgeschlagen: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Funktionen für Gruppen
|
||||
function getAllGroups($con, $search = null) {
|
||||
$sql = "SELECT og.*, COUNT(ogm.PrincipalID) as MemberCount,
|
||||
ua.FirstName as OwnerFirstName, ua.LastName as OwnerLastName
|
||||
FROM os_groups og
|
||||
LEFT JOIN os_groups_membership ogm ON og.GroupID = ogm.GroupID
|
||||
LEFT JOIN UserAccounts ua ON og.OwnerID = ua.PrincipalID
|
||||
WHERE 1=1";
|
||||
|
||||
if ($search) {
|
||||
$search = mysqli_real_escape_string($con, $search);
|
||||
$sql .= " AND (og.Name LIKE '%$search%' OR og.Charter LIKE '%$search%')";
|
||||
}
|
||||
|
||||
$sql .= " GROUP BY og.GroupID ORDER BY MemberCount DESC, og.Name ASC";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getGroupById($con, $groupId) {
|
||||
$sql = "SELECT og.*, ua.FirstName as OwnerFirstName, ua.LastName as OwnerLastName,
|
||||
COUNT(ogm.PrincipalID) as MemberCount
|
||||
FROM os_groups og
|
||||
LEFT JOIN UserAccounts ua ON og.OwnerID = ua.PrincipalID
|
||||
LEFT JOIN os_groups_membership ogm ON og.GroupID = ogm.GroupID
|
||||
WHERE og.GroupID = '" . mysqli_real_escape_string($con, $groupId) . "'
|
||||
GROUP BY og.GroupID";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getGroupMembers($con, $groupId) {
|
||||
$sql = "SELECT ogm.*, ua.FirstName, ua.LastName, ogr.Title, ogr.Powers,
|
||||
gu.Login as LastLogin
|
||||
FROM os_groups_membership ogm
|
||||
LEFT JOIN UserAccounts ua ON ogm.PrincipalID = ua.PrincipalID
|
||||
LEFT JOIN os_groups_rolemembership ogrm ON ogm.PrincipalID = ogrm.PrincipalID AND ogm.GroupID = ogrm.GroupID
|
||||
LEFT JOIN os_groups_roles ogr ON ogrm.RoleID = ogr.RoleID
|
||||
LEFT JOIN GridUser gu ON ogm.PrincipalID = gu.UserID
|
||||
WHERE ogm.GroupID = '" . mysqli_real_escape_string($con, $groupId) . "'
|
||||
ORDER BY ogr.Powers DESC, ua.FirstName ASC";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getGroupRoles($con, $groupId) {
|
||||
$sql = "SELECT ogr.*, COUNT(ogrm.PrincipalID) as MemberCount
|
||||
FROM os_groups_roles ogr
|
||||
LEFT JOIN os_groups_rolemembership ogrm ON ogr.RoleID = ogrm.RoleID
|
||||
WHERE ogr.GroupID = '" . mysqli_real_escape_string($con, $groupId) . "'
|
||||
GROUP BY ogr.RoleID
|
||||
ORDER BY ogr.Powers DESC, ogr.Title ASC";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getGroupNotices($con, $groupId, $limit = 10) {
|
||||
$sql = "SELECT ogn.*, ua.FirstName, ua.LastName
|
||||
FROM os_groups_notices ogn
|
||||
LEFT JOIN UserAccounts ua ON ogn.AttachmentOwnerID = ua.PrincipalID
|
||||
WHERE ogn.GroupID = '" . mysqli_real_escape_string($con, $groupId) . "'
|
||||
ORDER BY ogn.TMStamp DESC
|
||||
LIMIT " . intval($limit);
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getGroupInvites($con, $groupId) {
|
||||
$sql = "SELECT ogi.*, ua1.FirstName as InviterFirstName, ua1.LastName as InviterLastName,
|
||||
ua2.FirstName as InviteeFirstName, ua2.LastName as InviteeLastName,
|
||||
ogr.Title as RoleName
|
||||
FROM os_groups_invites ogi
|
||||
LEFT JOIN UserAccounts ua1 ON ogi.InviterID = ua1.PrincipalID
|
||||
LEFT JOIN UserAccounts ua2 ON ogi.PrincipalID = ua2.PrincipalID
|
||||
LEFT JOIN os_groups_roles ogr ON ogi.RoleID = ogr.RoleID
|
||||
WHERE ogi.GroupID = '" . mysqli_real_escape_string($con, $groupId) . "'
|
||||
ORDER BY ogi.TMStamp DESC";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getUserGroups($con, $userId) {
|
||||
$sql = "SELECT og.*, ogm.Contribution, ogm.ListInProfile, ogr.Title, ogr.Powers
|
||||
FROM os_groups_membership ogm
|
||||
LEFT JOIN os_groups og ON ogm.GroupID = og.GroupID
|
||||
LEFT JOIN os_groups_rolemembership ogrm ON ogm.PrincipalID = ogrm.PrincipalID AND ogm.GroupID = ogrm.GroupID
|
||||
LEFT JOIN os_groups_roles ogr ON ogrm.RoleID = ogr.RoleID
|
||||
WHERE ogm.PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
ORDER BY og.Name";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getGroupStats($con) {
|
||||
$totalGroups = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM os_groups"))[0];
|
||||
$totalMembers = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM os_groups_membership"))[0];
|
||||
$totalRoles = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM os_groups_roles"))[0];
|
||||
$openGroups = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM os_groups WHERE OpenEnrollment = 1"))[0];
|
||||
|
||||
return [
|
||||
'total_groups' => $totalGroups,
|
||||
'total_members' => $totalMembers,
|
||||
'total_roles' => $totalRoles,
|
||||
'open_groups' => $openGroups
|
||||
];
|
||||
}
|
||||
|
||||
// Parameter verarbeiten
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : 'list';
|
||||
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
|
||||
$groupId = isset($_GET['id']) ? $_GET['id'] : '';
|
||||
$userId = isset($_GET['user']) ? $_GET['user'] : '';
|
||||
|
||||
// Dummy-Benutzer-ID für Demo (normalerweise aus Session)
|
||||
$currentUserId = '00000000-0000-0000-0000-000000000001'; // Beispiel-User-ID
|
||||
|
||||
?>
|
||||
|
||||
<div class="container-fluid mt-4">
|
||||
<div class="row">
|
||||
<!-- Sidebar -->
|
||||
<div class="col-md-3">
|
||||
<!-- Gruppensuche -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-search"></i> Gruppen suchen</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="GET" action="groups.php">
|
||||
<div class="mb-3">
|
||||
<label for="search" class="form-label">Suche:</label>
|
||||
<input type="text" class="form-control" id="search" name="search"
|
||||
value="<?php echo htmlspecialchars($search); ?>"
|
||||
placeholder="Gruppenname oder Beschreibung...">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
<i class="fas fa-search"></i> Suchen
|
||||
</button>
|
||||
<a href="groups.php" class="btn btn-secondary w-100 mt-2">
|
||||
<i class="fas fa-refresh"></i> Alle anzeigen
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Navigation -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-navigation"></i> Navigation</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-grid gap-2">
|
||||
<a href="groups.php?action=list" class="btn btn-outline-primary btn-sm">
|
||||
<i class="fas fa-list"></i> Alle Gruppen
|
||||
</a>
|
||||
<a href="groups.php?action=my_groups" class="btn btn-outline-success btn-sm">
|
||||
<i class="fas fa-user-friends"></i> Meine Gruppen
|
||||
</a>
|
||||
<a href="groups.php?action=open" class="btn btn-outline-info btn-sm">
|
||||
<i class="fas fa-door-open"></i> Offene Gruppen
|
||||
</a>
|
||||
<a href="groups.php?action=popular" class="btn btn-outline-warning btn-sm">
|
||||
<i class="fas fa-fire"></i> Beliebte Gruppen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiken -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-chart-bar"></i> Gruppen-Statistiken</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php $stats = getGroupStats($con); ?>
|
||||
|
||||
<div class="text-center">
|
||||
<div class="mb-2">
|
||||
<h4 class="text-primary"><?php echo number_format($stats['total_groups'], 0, ',', '.'); ?></h4>
|
||||
<small class="text-muted">Gesamt Gruppen</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<h4 class="text-success"><?php echo number_format($stats['total_members'], 0, ',', '.'); ?></h4>
|
||||
<small class="text-muted">Gesamt Mitglieder</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<h4 class="text-warning"><?php echo number_format($stats['total_roles'], 0, ',', '.'); ?></h4>
|
||||
<small class="text-muted">Gesamt Rollen</small>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-info"><?php echo number_format($stats['open_groups'], 0, ',', '.'); ?></h4>
|
||||
<small class="text-muted">Offene Gruppen</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hauptinhalt -->
|
||||
<div class="col-md-9">
|
||||
<?php if ($action == 'view' && $groupId): ?>
|
||||
<!-- Detail-Ansicht einer Gruppe -->
|
||||
<?php
|
||||
$result = getGroupById($con, $groupId);
|
||||
$group = mysqli_fetch_assoc($result);
|
||||
|
||||
if ($group):
|
||||
?>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<div class="row align-items-center">
|
||||
<div class="col">
|
||||
<h4 class="mb-0">
|
||||
<i class="fas fa-users"></i>
|
||||
<?php echo htmlspecialchars($group['Name']); ?>
|
||||
</h4>
|
||||
<small>
|
||||
Gegründet von: <?php echo htmlspecialchars($group['OwnerFirstName'] . ' ' . $group['OwnerLastName']); ?>
|
||||
| Mitglieder: <?php echo number_format($group['MemberCount'], 0, ',', '.'); ?>
|
||||
</small>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<a href="groups.php" class="btn btn-light">
|
||||
<i class="fas fa-arrow-left"></i> Zurück zur Liste
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Gruppen Tabs -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<ul class="nav nav-tabs card-header-tabs" id="groupTabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-bs-toggle="tab" href="#info">
|
||||
<i class="fas fa-info-circle"></i> Info
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-bs-toggle="tab" href="#members">
|
||||
<i class="fas fa-users"></i> Mitglieder (<?php echo $group['MemberCount']; ?>)
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-bs-toggle="tab" href="#roles">
|
||||
<i class="fas fa-user-tag"></i> Rollen
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-bs-toggle="tab" href="#notices">
|
||||
<i class="fas fa-bullhorn"></i> Nachrichten
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-bs-toggle="tab" href="#invites">
|
||||
<i class="fas fa-envelope"></i> Einladungen
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<!-- Info Tab -->
|
||||
<div class="tab-pane fade show active" id="info">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<h5>Gruppencharter:</h5>
|
||||
<?php if ($group['Charter']): ?>
|
||||
<p class="text-justify"><?php echo nl2br(htmlspecialchars($group['Charter'])); ?></p>
|
||||
<?php else: ?>
|
||||
<p class="text-muted fst-italic">Keine Gruppenbeschreibung verfügbar.</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<h5 class="mt-4">Gruppendetails:</h5>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<ul class="list-unstyled">
|
||||
<li><strong>Eigentümer:</strong> <?php echo htmlspecialchars($group['OwnerFirstName'] . ' ' . $group['OwnerLastName']); ?></li>
|
||||
<li><strong>Gegründet:</strong> <?php echo date('d.m.Y', $group['FoundedBy']); ?></li>
|
||||
<li><strong>Mitgliedsbeitrag:</strong> L$ <?php echo number_format($group['MembershipFee'], 0, ',', '.'); ?></li>
|
||||
<li><strong>Gruppe öffnen für:</strong>
|
||||
<span class="badge bg-<?php echo $group['OpenEnrollment'] ? 'success' : 'danger'; ?>">
|
||||
<?php echo $group['OpenEnrollment'] ? 'Alle' : 'Nur Einladung'; ?>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<ul class="list-unstyled">
|
||||
<li><strong>Mitglieder:</strong> <?php echo number_format($group['MemberCount'], 0, ',', '.'); ?></li>
|
||||
<li><strong>Anzahl Rollen:</strong>
|
||||
<?php
|
||||
$roleCount = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM os_groups_roles WHERE GroupID = '" . mysqli_real_escape_string($con, $groupId) . "'"))[0];
|
||||
echo $roleCount;
|
||||
?>
|
||||
</li>
|
||||
<li><strong>In Suche anzeigen:</strong>
|
||||
<span class="badge bg-<?php echo $group['ShowInList'] ? 'success' : 'warning'; ?>">
|
||||
<?php echo $group['ShowInList'] ? 'Ja' : 'Nein'; ?>
|
||||
</span>
|
||||
</li>
|
||||
<li><strong>Gruppe veröffentlicht:</strong>
|
||||
<span class="badge bg-<?php echo $group['AllowPublish'] ? 'success' : 'secondary'; ?>">
|
||||
<?php echo $group['AllowPublish'] ? 'Ja' : 'Nein'; ?>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<!-- Gruppe beitreten/verlassen -->
|
||||
<div class="card bg-light">
|
||||
<div class="card-body text-center">
|
||||
<?php if ($group['OpenEnrollment']): ?>
|
||||
<h6 class="card-title">Gruppe beitreten</h6>
|
||||
<p class="card-text">Diese Gruppe steht allen offen.</p>
|
||||
<?php if ($group['MembershipFee'] > 0): ?>
|
||||
<p class="text-warning">
|
||||
<i class="fas fa-coins"></i>
|
||||
Mitgliedsbeitrag: L$ <?php echo number_format($group['MembershipFee'], 0, ',', '.'); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<button class="btn btn-success" onclick="joinGroup('<?php echo $groupId; ?>')">
|
||||
<i class="fas fa-user-plus"></i> Gruppe beitreten
|
||||
</button>
|
||||
<?php else: ?>
|
||||
<h6 class="card-title">Geschlossene Gruppe</h6>
|
||||
<p class="card-text">Diese Gruppe ist nur auf Einladung zugänglich.</p>
|
||||
<button class="btn btn-warning" onclick="requestInvite('<?php echo $groupId; ?>')">
|
||||
<i class="fas fa-envelope"></i> Einladung anfragen
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Gruppen-Statistiken -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h6><i class="fas fa-chart-pie"></i> Gruppenstatistiken</h6>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$activeMembers = mysqli_fetch_row(mysqli_query($con, "
|
||||
SELECT COUNT(DISTINCT ogm.PrincipalID)
|
||||
FROM os_groups_membership ogm
|
||||
LEFT JOIN GridUser gu ON ogm.PrincipalID = gu.UserID
|
||||
WHERE ogm.GroupID = '" . mysqli_real_escape_string($con, $groupId) . "'
|
||||
AND gu.Login > (UNIX_TIMESTAMP() - (7*86400))
|
||||
"))[0];
|
||||
|
||||
$recentNotices = mysqli_fetch_row(mysqli_query($con, "
|
||||
SELECT COUNT(*) FROM os_groups_notices
|
||||
WHERE GroupID = '" . mysqli_real_escape_string($con, $groupId) . "'
|
||||
AND TMStamp > (UNIX_TIMESTAMP() - (30*86400))
|
||||
"))[0];
|
||||
?>
|
||||
|
||||
<div class="text-center">
|
||||
<div class="mb-2">
|
||||
<h5 class="text-success"><?php echo $activeMembers; ?></h5>
|
||||
<small class="text-muted">Aktiv (7 Tage)</small>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="text-info"><?php echo $recentNotices; ?></h5>
|
||||
<small class="text-muted">Nachrichten (30 Tage)</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Members Tab -->
|
||||
<div class="tab-pane fade" id="members">
|
||||
<?php
|
||||
$membersResult = getGroupMembers($con, $groupId);
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<?php while ($member = mysqli_fetch_assoc($membersResult)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">
|
||||
<?php echo htmlspecialchars($member['FirstName'] . ' ' . $member['LastName']); ?>
|
||||
<?php if ($member['LastLogin'] && $member['LastLogin'] > (time() - 300)): ?>
|
||||
<span class="badge bg-success ms-1">Online</span>
|
||||
<?php endif; ?>
|
||||
</h6>
|
||||
|
||||
<?php if ($member['Title']): ?>
|
||||
<p class="text-primary mb-2">
|
||||
<i class="fas fa-user-tag"></i> <?php echo htmlspecialchars($member['Title']); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($member['Contribution']): ?>
|
||||
<p class="text-success mb-2">
|
||||
<i class="fas fa-coins"></i> Beitrag: L$ <?php echo number_format($member['Contribution'], 0, ',', '.'); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="d-grid gap-1">
|
||||
<a href="profile.php?user=<?php echo $member['PrincipalID']; ?>"
|
||||
class="btn btn-outline-info btn-sm">
|
||||
<i class="fas fa-eye"></i> Profil
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Roles Tab -->
|
||||
<div class="tab-pane fade" id="roles">
|
||||
<?php
|
||||
$rolesResult = getGroupRoles($con, $groupId);
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<?php while ($role = mysqli_fetch_assoc($rolesResult)): ?>
|
||||
<div class="col-md-6 mb-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">
|
||||
<?php echo htmlspecialchars($role['Title']); ?>
|
||||
<span class="badge bg-secondary ms-2"><?php echo $role['MemberCount']; ?> Mitglieder</span>
|
||||
</h6>
|
||||
|
||||
<?php if ($role['Description']): ?>
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo htmlspecialchars($role['Description']); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="mt-2">
|
||||
<small class="text-muted">
|
||||
<strong>Berechtigungen:</strong> <?php echo $role['Powers']; ?>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Notices Tab -->
|
||||
<div class="tab-pane fade" id="notices">
|
||||
<?php
|
||||
$noticesResult = getGroupNotices($con, $groupId);
|
||||
?>
|
||||
|
||||
<div class="row">
|
||||
<?php while ($notice = mysqli_fetch_assoc($noticesResult)): ?>
|
||||
<div class="col-12 mb-3">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0">
|
||||
<i class="fas fa-bullhorn"></i>
|
||||
<?php echo htmlspecialchars($notice['Subject']); ?>
|
||||
</h6>
|
||||
<small class="text-muted">
|
||||
<?php echo date('d.m.Y H:i', $notice['TMStamp']); ?>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p><?php echo nl2br(htmlspecialchars($notice['Message'])); ?></p>
|
||||
|
||||
<?php if ($notice['FirstName'] && $notice['LastName']): ?>
|
||||
<div class="text-end">
|
||||
<small class="text-muted">
|
||||
Von: <?php echo htmlspecialchars($notice['FirstName'] . ' ' . $notice['LastName']); ?>
|
||||
</small>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Invites Tab -->
|
||||
<div class="tab-pane fade" id="invites">
|
||||
<?php
|
||||
$invitesResult = getGroupInvites($con, $groupId);
|
||||
$inviteCount = mysqli_num_rows($invitesResult);
|
||||
?>
|
||||
|
||||
<h6><?php echo $inviteCount; ?> offene Einladungen</h6>
|
||||
|
||||
<?php if ($inviteCount > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($invite = mysqli_fetch_assoc($invitesResult)): ?>
|
||||
<div class="col-md-6 mb-3">
|
||||
<div class="card border-warning">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<i class="fas fa-envelope"></i> Einladung
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">
|
||||
<?php echo htmlspecialchars($invite['InviteeFirstName'] . ' ' . $invite['InviteeLastName']); ?>
|
||||
</h6>
|
||||
<p class="text-muted small">
|
||||
Eingeladen von: <?php echo htmlspecialchars($invite['InviterFirstName'] . ' ' . $invite['InviterLastName']); ?>
|
||||
</p>
|
||||
<?php if ($invite['RoleName']): ?>
|
||||
<p class="text-info small">
|
||||
Rolle: <?php echo htmlspecialchars($invite['RoleName']); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<small class="text-muted">
|
||||
Eingeladen am: <?php echo date('d.m.Y H:i', $invite['TMStamp']); ?>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-4">
|
||||
<i class="fas fa-inbox fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine offenen Einladungen</h5>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<div class="alert alert-warning">
|
||||
<i class="fas fa-exclamation-triangle"></i> Gruppe nicht gefunden.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php elseif ($action == 'my_groups'): ?>
|
||||
<!-- Meine Gruppen -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4><i class="fas fa-user-friends"></i> Meine Gruppen</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$myGroupsResult = getUserGroups($con, $currentUserId);
|
||||
$myGroupsCount = mysqli_num_rows($myGroupsResult);
|
||||
?>
|
||||
|
||||
<h6><?php echo $myGroupsCount; ?> Gruppen-Mitgliedschaften</h6>
|
||||
|
||||
<?php if ($myGroupsCount > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($group = mysqli_fetch_assoc($myGroupsResult)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($group['Name']); ?></h6>
|
||||
|
||||
<?php if ($group['Title']): ?>
|
||||
<p class="text-primary mb-2">
|
||||
<i class="fas fa-user-tag"></i> <?php echo htmlspecialchars($group['Title']); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($group['Charter']): ?>
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo htmlspecialchars(substr($group['Charter'], 0, 80) . (strlen($group['Charter']) > 80 ? '...' : '')); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<?php if ($group['Contribution']): ?>
|
||||
<span class="badge bg-success">L$ <?php echo number_format($group['Contribution'], 0, ',', '.'); ?></span>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($group['ListInProfile']): ?>
|
||||
<span class="badge bg-info">Im Profil</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<a href="groups.php?action=view&id=<?php echo $group['GroupID']; ?>"
|
||||
class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-eye"></i> Details anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-users fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine Gruppenmitgliedschaften</h5>
|
||||
<p class="text-muted">Sie sind noch kein Mitglied in einer Gruppe.</p>
|
||||
<a href="groups.php?action=open" class="btn btn-primary">
|
||||
<i class="fas fa-search"></i> Gruppen durchsuchen
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php elseif ($action == 'open'): ?>
|
||||
<!-- Offene Gruppen -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4><i class="fas fa-door-open"></i> Offene Gruppen</h4>
|
||||
<p class="mb-0 text-muted">Gruppen, die jeder beitreten kann</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$openGroupsResult = mysqli_query($con, "
|
||||
SELECT og.*, COUNT(ogm.PrincipalID) as MemberCount,
|
||||
ua.FirstName as OwnerFirstName, ua.LastName as OwnerLastName
|
||||
FROM os_groups og
|
||||
LEFT JOIN os_groups_membership ogm ON og.GroupID = ogm.GroupID
|
||||
LEFT JOIN UserAccounts ua ON og.OwnerID = ua.PrincipalID
|
||||
WHERE og.OpenEnrollment = 1 AND og.ShowInList = 1
|
||||
GROUP BY og.GroupID
|
||||
ORDER BY MemberCount DESC, og.Name ASC
|
||||
");
|
||||
$openCount = mysqli_num_rows($openGroupsResult);
|
||||
?>
|
||||
|
||||
<h6><?php echo $openCount; ?> offene Gruppen gefunden</h6>
|
||||
|
||||
<?php if ($openCount > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($group = mysqli_fetch_assoc($openGroupsResult)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card border-success">
|
||||
<div class="card-header bg-success text-white">
|
||||
<i class="fas fa-door-open"></i> Beitritt möglich
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($group['Name']); ?></h6>
|
||||
|
||||
<?php if ($group['Charter']): ?>
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo htmlspecialchars(substr($group['Charter'], 0, 100) . (strlen($group['Charter']) > 100 ? '...' : '')); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<span class="badge bg-info"><?php echo $group['MemberCount']; ?> Mitglieder</span>
|
||||
<?php if ($group['MembershipFee'] > 0): ?>
|
||||
<span class="badge bg-warning">L$ <?php echo number_format($group['MembershipFee'], 0, ',', '.'); ?></span>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-success">Kostenlos</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<button class="btn btn-success btn-sm" onclick="joinGroup('<?php echo $group['GroupID']; ?>')">
|
||||
<i class="fas fa-user-plus"></i> Beitreten
|
||||
</button>
|
||||
<a href="groups.php?action=view&id=<?php echo $group['GroupID']; ?>"
|
||||
class="btn btn-outline-primary btn-sm">
|
||||
<i class="fas fa-eye"></i> Details
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-door-closed fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine offenen Gruppen</h5>
|
||||
<p class="text-muted">Derzeit sind keine Gruppen für den öffentlichen Beitritt verfügbar.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<!-- Standard Gruppenliste -->
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h4><i class="fas fa-users"></i> Alle Gruppen</h4>
|
||||
<?php if ($search): ?>
|
||||
<span class="badge bg-info">
|
||||
Suche: "<?php echo htmlspecialchars($search); ?>"
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$result = getAllGroups($con, $search);
|
||||
$count = mysqli_num_rows($result);
|
||||
?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6><?php echo $count; ?> Gruppen gefunden</h6>
|
||||
<div>
|
||||
<a href="groups.php?action=open" class="btn btn-success btn-sm">
|
||||
<i class="fas fa-door-open"></i> Offene Gruppen
|
||||
</a>
|
||||
<a href="groups.php?action=popular" class="btn btn-warning btn-sm">
|
||||
<i class="fas fa-fire"></i> Beliebte Gruppen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($count > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($group = mysqli_fetch_assoc($result)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card h-100">
|
||||
<div class="card-body d-flex flex-column">
|
||||
<h6 class="card-title">
|
||||
<?php echo htmlspecialchars($group['Name']); ?>
|
||||
<?php if ($group['OpenEnrollment']): ?>
|
||||
<span class="badge bg-success ms-1">Offen</span>
|
||||
<?php endif; ?>
|
||||
</h6>
|
||||
|
||||
<?php if ($group['Charter']): ?>
|
||||
<p class="card-text text-muted small flex-grow-1">
|
||||
<?php echo htmlspecialchars(substr($group['Charter'], 0, 100) . (strlen($group['Charter']) > 100 ? '...' : '')); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="mt-auto">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<span class="badge bg-primary"><?php echo $group['MemberCount']; ?> Mitglieder</span>
|
||||
<small class="text-muted">
|
||||
von <?php echo htmlspecialchars($group['OwnerFirstName'] . ' ' . $group['OwnerLastName']); ?>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<a href="groups.php?action=view&id=<?php echo $group['GroupID']; ?>"
|
||||
class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-eye"></i> Details anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-users fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine Gruppen gefunden</h5>
|
||||
<p class="text-muted">
|
||||
<?php if ($search): ?>
|
||||
Versuchen Sie es mit anderen Suchbegriffen.
|
||||
<?php else: ?>
|
||||
Es wurden noch keine Gruppen erstellt.
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card {
|
||||
transition: box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.border-success, .border-warning {
|
||||
border-width: 2px !important;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link.active {
|
||||
background-color: var(--bs-body-bg);
|
||||
border-color: var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Group Management Functions
|
||||
function joinGroup(groupId) {
|
||||
if (confirm('Möchten Sie dieser Gruppe beitreten?')) {
|
||||
// AJAX-Call um Gruppe beizutreten
|
||||
fetch('groups_api.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action: 'join_group',
|
||||
group_id: groupId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert('Sie sind der Gruppe erfolgreich beigetreten!');
|
||||
location.reload();
|
||||
} else {
|
||||
alert('Fehler: ' + data.message);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error:', error);
|
||||
alert('Ein Fehler ist aufgetreten.');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function requestInvite(groupId) {
|
||||
if (confirm('Möchten Sie eine Einladung für diese Gruppe anfragen?')) {
|
||||
// AJAX-Call um Einladung anzufragen
|
||||
fetch('groups_api.php', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
action: 'request_invite',
|
||||
group_id: groupId
|
||||
})
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
alert('Einladungsanfrage wurde gesendet!');
|
||||
} else {
|
||||
alert('Fehler: ' + data.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Tab-Hash Navigation
|
||||
if (window.location.hash) {
|
||||
let hash = window.location.hash;
|
||||
let tabTrigger = document.querySelector(`a[href="${hash}"]`);
|
||||
if (tabTrigger) {
|
||||
let tab = new bootstrap.Tab(tabTrigger);
|
||||
tab.show();
|
||||
}
|
||||
}
|
||||
|
||||
// Hash zu URL hinzufügen beim Tab-Wechsel
|
||||
document.querySelectorAll('a[data-bs-toggle="tab"]').forEach(function(tabEl) {
|
||||
tabEl.addEventListener('shown.bs.tab', function(event) {
|
||||
let hash = event.target.getAttribute('href');
|
||||
if (history.pushState) {
|
||||
history.pushState(null, null, hash);
|
||||
} else {
|
||||
location.hash = hash;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php
|
||||
mysqli_close($con);
|
||||
include_once "include/footerModern.php";
|
||||
?>
|
||||
@@ -0,0 +1,480 @@
|
||||
<?php
|
||||
$title = "Benutzer-Favoriten (Picks)";
|
||||
include_once "include/config.php";
|
||||
include_once "include/" . HEADER_FILE;
|
||||
|
||||
// Datenbankverbindung
|
||||
$con = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
|
||||
if (!$con) {
|
||||
die("Datenbankverbindung fehlgeschlagen: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Funktionen für Picks
|
||||
function getAllPicks($con, $search = null, $user = null) {
|
||||
$sql = "SELECT p.*, u.FirstName, u.LastName, r.regionName
|
||||
FROM userpicks p
|
||||
LEFT JOIN UserAccounts u ON p.creatoruuid = u.PrincipalID
|
||||
LEFT JOIN regions r ON SUBSTRING_INDEX(p.simname, ' ', 1) = r.regionName
|
||||
WHERE 1=1";
|
||||
|
||||
if ($user) {
|
||||
$sql .= " AND p.creatoruuid = '" . mysqli_real_escape_string($con, $user) . "'";
|
||||
}
|
||||
|
||||
if ($search) {
|
||||
$search = mysqli_real_escape_string($con, $search);
|
||||
$sql .= " AND (p.name LIKE '%$search%' OR p.description LIKE '%$search%' OR p.simname LIKE '%$search%')";
|
||||
}
|
||||
|
||||
$sql .= " ORDER BY p.toppick DESC, p.name ASC";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getPickById($con, $pickuuid) {
|
||||
$sql = "SELECT p.*, u.FirstName, u.LastName, r.regionName, r.serverURI
|
||||
FROM userpicks p
|
||||
LEFT JOIN UserAccounts u ON p.creatoruuid = u.PrincipalID
|
||||
LEFT JOIN regions r ON SUBSTRING_INDEX(p.simname, ' ', 1) = r.regionName
|
||||
WHERE p.pickuuid = '" . mysqli_real_escape_string($con, $pickuuid) . "'";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getTopPicks($con, $limit = 6) {
|
||||
$sql = "SELECT p.*, u.FirstName, u.LastName, r.regionName
|
||||
FROM userpicks p
|
||||
LEFT JOIN UserAccounts u ON p.creatoruuid = u.PrincipalID
|
||||
LEFT JOIN regions r ON SUBSTRING_INDEX(p.simname, ' ', 1) = r.regionName
|
||||
WHERE p.toppick = 1
|
||||
ORDER BY RAND()
|
||||
LIMIT " . intval($limit);
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getUserPicks($con, $userId) {
|
||||
return getAllPicks($con, null, $userId);
|
||||
}
|
||||
|
||||
// Aktionen verarbeiten
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : 'list';
|
||||
$search = isset($_GET['search']) ? trim($_GET['search']) : '';
|
||||
$pickId = isset($_GET['id']) ? $_GET['id'] : '';
|
||||
$userId = isset($_GET['user']) ? $_GET['user'] : '';
|
||||
|
||||
?>
|
||||
|
||||
<div class="container-fluid mt-4">
|
||||
<div class="row">
|
||||
<!-- Sidebar -->
|
||||
<div class="col-md-3">
|
||||
<!-- Suchformular -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-search"></i> Picks durchsuchen</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="GET" action="picks.php">
|
||||
<div class="mb-3">
|
||||
<label for="search" class="form-label">Suche:</label>
|
||||
<input type="text" class="form-control" id="search" name="search"
|
||||
value="<?php echo htmlspecialchars($search); ?>"
|
||||
placeholder="Name, Beschreibung oder Ort...">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
<i class="fas fa-search"></i> Suchen
|
||||
</button>
|
||||
<a href="picks.php" class="btn btn-secondary w-100 mt-2">
|
||||
<i class="fas fa-refresh"></i> Alle anzeigen
|
||||
</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Navigation -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-navigation"></i> Navigation</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="d-grid gap-2">
|
||||
<a href="picks.php" class="btn btn-outline-primary btn-sm">
|
||||
<i class="fas fa-list"></i> Alle Picks
|
||||
</a>
|
||||
<a href="picks.php?action=top" class="btn btn-outline-warning btn-sm">
|
||||
<i class="fas fa-star"></i> Top Picks
|
||||
</a>
|
||||
<a href="picks.php?action=recent" class="btn btn-outline-info btn-sm">
|
||||
<i class="fas fa-clock"></i> Neueste
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Statistiken -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-chart-bar"></i> Statistiken</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$totalPicks = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM userpicks"))[0];
|
||||
$topPicks = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM userpicks WHERE toppick = 1"))[0];
|
||||
$activePickers = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(DISTINCT creatoruuid) FROM userpicks"))[0];
|
||||
?>
|
||||
|
||||
<div class="text-center">
|
||||
<div class="mb-2">
|
||||
<h4 class="text-primary"><?php echo number_format($totalPicks, 0, ',', '.'); ?></h4>
|
||||
<small class="text-muted">Gesamt Picks</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<h4 class="text-warning"><?php echo number_format($topPicks, 0, ',', '.'); ?></h4>
|
||||
<small class="text-muted">Top Picks</small>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-info"><?php echo number_format($activePickers, 0, ',', '.'); ?></h4>
|
||||
<small class="text-muted">Aktive Benutzer</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hauptinhalt -->
|
||||
<div class="col-md-9">
|
||||
<?php if ($action == 'view' && $pickId): ?>
|
||||
<!-- Detail-Ansicht eines Picks -->
|
||||
<?php
|
||||
$result = getPickById($con, $pickId);
|
||||
$pick = mysqli_fetch_assoc($result);
|
||||
|
||||
if ($pick):
|
||||
?>
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h4>
|
||||
<i class="fas fa-<?php echo $pick['toppick'] ? 'star text-warning' : 'map-marker-alt'; ?>"></i>
|
||||
<?php echo htmlspecialchars($pick['name']); ?>
|
||||
<?php if ($pick['toppick']): ?>
|
||||
<span class="badge bg-warning text-dark ms-2">TOP PICK</span>
|
||||
<?php endif; ?>
|
||||
</h4>
|
||||
<a href="picks.php" class="btn btn-secondary">
|
||||
<i class="fas fa-arrow-left"></i> Zurück
|
||||
</a>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<h5>Beschreibung:</h5>
|
||||
<p class="text-justify"><?php echo nl2br(htmlspecialchars($pick['description'])); ?></p>
|
||||
|
||||
<div class="row mt-4">
|
||||
<div class="col-md-6">
|
||||
<h6>Details:</h6>
|
||||
<ul class="list-unstyled">
|
||||
<li><strong>Ersteller:</strong> <?php echo htmlspecialchars($pick['FirstName'] . ' ' . $pick['LastName']); ?></li>
|
||||
<li><strong>Position:</strong> <?php echo htmlspecialchars($pick['simname']); ?></li>
|
||||
<li><strong>Global Position:</strong> <?php echo htmlspecialchars($pick['posglobal']); ?></li>
|
||||
<li><strong>Original Name:</strong> <?php echo htmlspecialchars($pick['originalname']); ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h6>Status:</h6>
|
||||
<ul class="list-unstyled">
|
||||
<li><strong>Typ:</strong>
|
||||
<?php if ($pick['toppick']): ?>
|
||||
<span class="badge bg-warning">Top Pick</span>
|
||||
<?php else: ?>
|
||||
<span class="badge bg-info">Normal Pick</span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<li><strong>Aktiviert:</strong>
|
||||
<span class="badge bg-<?php echo $pick['enabled'] ? 'success' : 'danger'; ?>">
|
||||
<?php echo $pick['enabled'] ? 'Ja' : 'Nein'; ?>
|
||||
</span>
|
||||
</li>
|
||||
<li><strong>Sort Order:</strong> <?php echo $pick['sortorder']; ?></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<!-- Snapshot-Bild falls vorhanden -->
|
||||
<?php if ($pick['snapshotuuid'] && $pick['snapshotuuid'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<div class="text-center mb-3">
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $pick['snapshotuuid']; ?>"
|
||||
class="img-fluid rounded"
|
||||
alt="Pick Bild"
|
||||
style="max-height: 200px;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Teleport-Button -->
|
||||
<div class="d-grid">
|
||||
<a href="secondlife://<?php echo htmlspecialchars($pick['simname']); ?>"
|
||||
class="btn btn-success btn-lg">
|
||||
<i class="fas fa-rocket"></i> Teleportieren
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Auf Karte anzeigen -->
|
||||
<div class="d-grid mt-2">
|
||||
<a href="maptile.php?region=<?php echo urlencode(explode(' ', $pick['simname'])[0]); ?>"
|
||||
class="btn btn-info">
|
||||
<i class="fas fa-map"></i> Auf Karte anzeigen
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Weitere Picks vom Benutzer -->
|
||||
<div class="d-grid mt-2">
|
||||
<a href="picks.php?user=<?php echo urlencode($pick['creatoruuid']); ?>"
|
||||
class="btn btn-outline-primary">
|
||||
<i class="fas fa-user"></i> Weitere Picks von diesem Benutzer
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="alert alert-warning">
|
||||
<i class="fas fa-exclamation-triangle"></i> Pick nicht gefunden.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php elseif ($action == 'top'): ?>
|
||||
<!-- Top Picks Ansicht -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4><i class="fas fa-star text-warning"></i> Top Picks</h4>
|
||||
<p class="mb-0 text-muted">Die beliebtesten und hervorgehobenen Orte unseres Grids</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$result = mysqli_query($con, "SELECT p.*, u.FirstName, u.LastName FROM userpicks p LEFT JOIN UserAccounts u ON p.creatoruuid = u.PrincipalID WHERE p.toppick = 1 ORDER BY p.name");
|
||||
$count = mysqli_num_rows($result);
|
||||
?>
|
||||
|
||||
<div class="mb-3">
|
||||
<h6><?php echo $count; ?> Top Picks gefunden</h6>
|
||||
</div>
|
||||
|
||||
<?php if ($count > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($row = mysqli_fetch_assoc($result)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-4">
|
||||
<div class="card h-100 border-warning">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<i class="fas fa-star"></i> TOP PICK
|
||||
</div>
|
||||
|
||||
<?php if ($row['snapshotuuid'] && $row['snapshotuuid'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $row['snapshotuuid']; ?>"
|
||||
class="card-img-top"
|
||||
alt="Pick Bild"
|
||||
style="height: 150px; object-fit: cover;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-body d-flex flex-column">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($row['name']); ?></h6>
|
||||
<p class="card-text text-muted small flex-grow-1">
|
||||
<?php echo htmlspecialchars(substr($row['description'], 0, 100) . (strlen($row['description']) > 100 ? '...' : '')); ?>
|
||||
</p>
|
||||
|
||||
<div class="mt-auto">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<small class="text-muted">
|
||||
<?php echo htmlspecialchars(explode(' ', $row['simname'])[0]); ?>
|
||||
</small>
|
||||
<small class="text-muted">
|
||||
von <?php echo htmlspecialchars($row['FirstName'] . ' ' . $row['LastName']); ?>
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<a href="picks.php?action=view&id=<?php echo $row['pickuuid']; ?>"
|
||||
class="btn btn-warning btn-sm">
|
||||
<i class="fas fa-eye"></i> Details anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-star fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine Top Picks gefunden</h5>
|
||||
<p class="text-muted">Es wurden noch keine Top Picks erstellt.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<!-- Standard Pick-Liste -->
|
||||
<div class="card">
|
||||
<div class="card-header d-flex justify-content-between align-items-center">
|
||||
<h4><i class="fas fa-map-marker-alt"></i>
|
||||
<?php if ($userId): ?>
|
||||
Picks von Benutzer
|
||||
<?php else: ?>
|
||||
Alle Benutzer-Favoriten (Picks)
|
||||
<?php endif; ?>
|
||||
</h4>
|
||||
<?php if ($search): ?>
|
||||
<span class="badge bg-info">
|
||||
Suche: "<?php echo htmlspecialchars($search); ?>"
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
if ($userId) {
|
||||
$result = getUserPicks($con, $userId);
|
||||
$userResult = mysqli_query($con, "SELECT FirstName, LastName FROM UserAccounts WHERE PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "'");
|
||||
$user = mysqli_fetch_assoc($userResult);
|
||||
} else {
|
||||
$result = getAllPicks($con, $search);
|
||||
}
|
||||
$count = mysqli_num_rows($result);
|
||||
?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h6>
|
||||
<?php echo $count; ?> Picks gefunden
|
||||
<?php if ($userId && $user): ?>
|
||||
von <?php echo htmlspecialchars($user['FirstName'] . ' ' . $user['LastName']); ?>
|
||||
<?php endif; ?>
|
||||
</h6>
|
||||
<?php if ($userId): ?>
|
||||
<a href="picks.php" class="btn btn-secondary btn-sm">
|
||||
<i class="fas fa-arrow-left"></i> Alle Picks
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<?php if ($count > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($row = mysqli_fetch_assoc($result)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-4">
|
||||
<div class="card h-100 <?php echo $row['toppick'] ? 'border-warning' : ''; ?>">
|
||||
<?php if ($row['toppick']): ?>
|
||||
<div class="card-header bg-warning text-dark text-center">
|
||||
<i class="fas fa-star"></i> TOP PICK
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($row['snapshotuuid'] && $row['snapshotuuid'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $row['snapshotuuid']; ?>"
|
||||
class="card-img-top"
|
||||
alt="Pick Bild"
|
||||
style="height: 150px; object-fit: cover;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-body d-flex flex-column">
|
||||
<h6 class="card-title">
|
||||
<?php echo htmlspecialchars($row['name']); ?>
|
||||
<?php if (!$row['enabled']): ?>
|
||||
<small class="text-muted">(deaktiviert)</small>
|
||||
<?php endif; ?>
|
||||
</h6>
|
||||
<p class="card-text text-muted small flex-grow-1">
|
||||
<?php echo htmlspecialchars(substr($row['description'], 0, 100) . (strlen($row['description']) > 100 ? '...' : '')); ?>
|
||||
</p>
|
||||
|
||||
<div class="mt-auto">
|
||||
<div class="d-flex justify-content-between align-items-center mb-2">
|
||||
<small class="text-muted">
|
||||
📍 <?php echo htmlspecialchars(explode(' ', $row['simname'])[0]); ?>
|
||||
</small>
|
||||
<?php if (!$userId): ?>
|
||||
<small class="text-muted">
|
||||
von <?php echo htmlspecialchars($row['FirstName'] . ' ' . $row['LastName']); ?>
|
||||
</small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="d-grid">
|
||||
<a href="picks.php?action=view&id=<?php echo $row['pickuuid']; ?>"
|
||||
class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-eye"></i> Details anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-map-marker-alt fa-3x text-muted mb-3"></i>
|
||||
<h5>Keine Picks gefunden</h5>
|
||||
<p class="text-muted">
|
||||
<?php if ($search): ?>
|
||||
Versuchen Sie es mit anderen Suchbegriffen.
|
||||
<?php elseif ($userId): ?>
|
||||
Dieser Benutzer hat noch keine Picks erstellt.
|
||||
<?php else: ?>
|
||||
Es wurden noch keine Picks erstellt.
|
||||
<?php endif; ?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card-img-top {
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.card:hover .card-img-top {
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.card {
|
||||
transition: box-shadow 0.2s;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.border-warning {
|
||||
border-width: 2px !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Auto-Submit für Suchfeld (verzögert)
|
||||
let searchTimeout;
|
||||
document.getElementById('search').addEventListener('input', function() {
|
||||
clearTimeout(searchTimeout);
|
||||
searchTimeout = setTimeout(() => {
|
||||
if (this.value.length >= 3 || this.value.length === 0) {
|
||||
this.form.submit();
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php
|
||||
mysqli_close($con);
|
||||
include_once "include/footerModern.php";
|
||||
?>
|
||||
+708
@@ -0,0 +1,708 @@
|
||||
<?php
|
||||
$title = "Benutzerprofile";
|
||||
include_once "include/config.php";
|
||||
include_once "include/" . HEADER_FILE;
|
||||
|
||||
// Datenbankverbindung
|
||||
$con = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD, DB_NAME);
|
||||
if (!$con) {
|
||||
die("Datenbankverbindung fehlgeschlagen: " . mysqli_connect_error());
|
||||
}
|
||||
|
||||
// Funktionen für Profile
|
||||
function getUserProfile($con, $userId) {
|
||||
$sql = "SELECT ua.*, up.*, gu.Login as LastLogin, gu.Logout as LastLogout
|
||||
FROM UserAccounts ua
|
||||
LEFT JOIN userprofile up ON ua.PrincipalID = up.useruuid
|
||||
LEFT JOIN GridUser gu ON ua.PrincipalID = gu.UserID
|
||||
WHERE ua.PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "'";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getUserByName($con, $firstName, $lastName) {
|
||||
$sql = "SELECT PrincipalID FROM UserAccounts
|
||||
WHERE FirstName = '" . mysqli_real_escape_string($con, $firstName) . "'
|
||||
AND LastName = '" . mysqli_real_escape_string($con, $lastName) . "'";
|
||||
|
||||
$result = mysqli_query($con, $sql);
|
||||
return $result ? mysqli_fetch_assoc($result) : null;
|
||||
}
|
||||
|
||||
function getPartnerInfo($con, $partnerUuid) {
|
||||
if (!$partnerUuid || $partnerUuid == '00000000-0000-0000-0000-000000000000') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$sql = "SELECT FirstName, LastName FROM UserAccounts
|
||||
WHERE PrincipalID = '" . mysqli_real_escape_string($con, $partnerUuid) . "'";
|
||||
|
||||
$result = mysqli_query($con, $sql);
|
||||
return $result ? mysqli_fetch_assoc($result) : null;
|
||||
}
|
||||
|
||||
function getUserPicks($con, $userId, $limit = 6) {
|
||||
$sql = "SELECT * FROM userpicks
|
||||
WHERE creatoruuid = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
AND enabled = 1
|
||||
ORDER BY toppick DESC, name ASC
|
||||
LIMIT " . intval($limit);
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getUserClassifieds($con, $userId, $limit = 6) {
|
||||
$sql = "SELECT * FROM classifieds
|
||||
WHERE creatoruuid = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
ORDER BY creationdate DESC
|
||||
LIMIT " . intval($limit);
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
function getFriendCount($con, $userId) {
|
||||
$sql = "SELECT COUNT(*) FROM Friends
|
||||
WHERE PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
OR Friend = '" . mysqli_real_escape_string($con, $userId) . "'";
|
||||
|
||||
$result = mysqli_query($con, $sql);
|
||||
return $result ? mysqli_fetch_row($result)[0] : 0;
|
||||
}
|
||||
|
||||
function getUserGroups($con, $userId) {
|
||||
$sql = "SELECT ogm.GroupID, og.Name as GroupName, og.Charter, ogm.Contribution,
|
||||
ogm.ListInProfile, ogr.Powers, ogr.Title
|
||||
FROM os_groups_membership ogm
|
||||
LEFT JOIN os_groups og ON ogm.GroupID = og.GroupID
|
||||
LEFT JOIN os_groups_rolemembership ogrm ON ogm.PrincipalID = ogrm.PrincipalID AND ogm.GroupID = ogrm.GroupID
|
||||
LEFT JOIN os_groups_roles ogr ON ogrm.RoleID = ogr.RoleID
|
||||
WHERE ogm.PrincipalID = '" . mysqli_real_escape_string($con, $userId) . "'
|
||||
AND ogm.ListInProfile = 1
|
||||
ORDER BY og.Name";
|
||||
|
||||
return mysqli_query($con, $sql);
|
||||
}
|
||||
|
||||
// Parameter verarbeiten
|
||||
$action = isset($_GET['action']) ? $_GET['action'] : 'search';
|
||||
$userId = isset($_GET['user']) ? $_GET['user'] : '';
|
||||
$firstName = isset($_GET['firstname']) ? trim($_GET['firstname']) : '';
|
||||
$lastName = isset($_GET['lastname']) ? trim($_GET['lastname']) : '';
|
||||
|
||||
// Benutzer über Namen suchen
|
||||
if ($firstName && $lastName && !$userId) {
|
||||
$userResult = getUserByName($con, $firstName, $lastName);
|
||||
if ($userResult) {
|
||||
$userId = $userResult['PrincipalID'];
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="container-fluid mt-4">
|
||||
<div class="row">
|
||||
<!-- Sidebar -->
|
||||
<div class="col-md-3">
|
||||
<!-- Benutzer suchen -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-search"></i> Benutzer suchen</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="GET" action="profile.php">
|
||||
<div class="mb-3">
|
||||
<label for="firstname" class="form-label">Vorname:</label>
|
||||
<input type="text" class="form-control" id="firstname" name="firstname"
|
||||
value="<?php echo htmlspecialchars($firstName); ?>"
|
||||
placeholder="Vorname eingeben">
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="lastname" class="form-label">Nachname:</label>
|
||||
<input type="text" class="form-control" id="lastname" name="lastname"
|
||||
value="<?php echo htmlspecialchars($lastName); ?>"
|
||||
placeholder="Nachname eingeben">
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary w-100">
|
||||
<i class="fas fa-search"></i> Profil suchen
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Kürzlich angesehene Profile -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-history"></i> Beliebte Profile</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$popularUsers = mysqli_query($con, "
|
||||
SELECT ua.PrincipalID, ua.FirstName, ua.LastName,
|
||||
COUNT(up.useruuid) as profile_completeness
|
||||
FROM UserAccounts ua
|
||||
LEFT JOIN userprofile up ON ua.PrincipalID = up.useruuid
|
||||
WHERE up.useruuid IS NOT NULL
|
||||
GROUP BY ua.PrincipalID
|
||||
ORDER BY profile_completeness DESC, ua.FirstName ASC
|
||||
LIMIT 5
|
||||
");
|
||||
?>
|
||||
|
||||
<div class="list-group list-group-flush">
|
||||
<?php while ($user = mysqli_fetch_assoc($popularUsers)): ?>
|
||||
<a href="profile.php?user=<?php echo $user['PrincipalID']; ?>"
|
||||
class="list-group-item list-group-item-action">
|
||||
<i class="fas fa-user"></i>
|
||||
<?php echo htmlspecialchars($user['FirstName'] . ' ' . $user['LastName']); ?>
|
||||
</a>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Grid Statistiken -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h5><i class="fas fa-chart-bar"></i> Grid Statistiken</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<?php
|
||||
$totalUsers = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM UserAccounts"))[0];
|
||||
$profilesWithPics = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM userprofile WHERE profileImage != '00000000-0000-0000-0000-000000000000'"))[0];
|
||||
$partneredUsers = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM userprofile WHERE profilePartner != '00000000-0000-0000-0000-000000000000'"))[0];
|
||||
$activeToday = mysqli_fetch_row(mysqli_query($con, "SELECT COUNT(*) FROM GridUser WHERE Login > (UNIX_TIMESTAMP() - 86400)"))[0];
|
||||
?>
|
||||
|
||||
<div class="text-center">
|
||||
<div class="mb-2">
|
||||
<h5 class="text-primary"><?php echo number_format($totalUsers, 0, ',', '.'); ?></h5>
|
||||
<small class="text-muted">Gesamt Benutzer</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<h5 class="text-success"><?php echo number_format($profilesWithPics, 0, ',', '.'); ?></h5>
|
||||
<small class="text-muted">Profile mit Bildern</small>
|
||||
</div>
|
||||
<div class="mb-2">
|
||||
<h5 class="text-warning"><?php echo number_format($partneredUsers, 0, ',', '.'); ?></h5>
|
||||
<small class="text-muted">Partnerschaften</small>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="text-info"><?php echo number_format($activeToday, 0, ',', '.'); ?></h5>
|
||||
<small class="text-muted">Heute aktiv</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Hauptinhalt -->
|
||||
<div class="col-md-9">
|
||||
<?php if ($userId): ?>
|
||||
<!-- Profil-Ansicht -->
|
||||
<?php
|
||||
$result = getUserProfile($con, $userId);
|
||||
$profile = mysqli_fetch_assoc($result);
|
||||
|
||||
if ($profile):
|
||||
$partner = getPartnerInfo($con, $profile['profilePartner']);
|
||||
$friendCount = getFriendCount($con, $userId);
|
||||
?>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<div class="row align-items-center">
|
||||
<div class="col">
|
||||
<h4 class="mb-0">
|
||||
<i class="fas fa-user"></i>
|
||||
<?php echo htmlspecialchars($profile['FirstName'] . ' ' . $profile['LastName']); ?>
|
||||
</h4>
|
||||
<?php if ($profile['LastLogin']): ?>
|
||||
<small>
|
||||
Letzter Login: <?php echo date('d.m.Y H:i', $profile['LastLogin']); ?>
|
||||
<?php if ($profile['LastLogin'] > (time() - 300)): ?>
|
||||
<span class="badge bg-success ms-2">ONLINE</span>
|
||||
<?php elseif ($profile['LastLogin'] > (time() - 86400)): ?>
|
||||
<span class="badge bg-warning ms-2">Heute aktiv</span>
|
||||
<?php endif; ?>
|
||||
</small>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<a href="profile.php" class="btn btn-light">
|
||||
<i class="fas fa-search"></i> Anderen Benutzer suchen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Profile Tabs -->
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<ul class="nav nav-tabs card-header-tabs" id="profileTabs">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" data-bs-toggle="tab" href="#about">
|
||||
<i class="fas fa-info-circle"></i> Über mich
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-bs-toggle="tab" href="#picks">
|
||||
<i class="fas fa-map-marker-alt"></i> Picks
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-bs-toggle="tab" href="#classifieds">
|
||||
<i class="fas fa-ad"></i> Anzeigen
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" data-bs-toggle="tab" href="#groups">
|
||||
<i class="fas fa-users"></i> Gruppen
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="tab-content">
|
||||
<!-- About Tab -->
|
||||
<div class="tab-pane fade show active" id="about">
|
||||
<div class="row">
|
||||
<div class="col-md-8">
|
||||
<!-- Über mich Text -->
|
||||
<div class="mb-4">
|
||||
<h5>Über mich:</h5>
|
||||
<?php if ($profile['profileAboutText']): ?>
|
||||
<p class="text-justify"><?php echo nl2br(htmlspecialchars($profile['profileAboutText'])); ?></p>
|
||||
<?php else: ?>
|
||||
<p class="text-muted fst-italic">Keine Informationen verfügbar.</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- First Life -->
|
||||
<?php if ($profile['profileFirstText']): ?>
|
||||
<div class="mb-4">
|
||||
<h5>First Life:</h5>
|
||||
<p class="text-justify"><?php echo nl2br(htmlspecialchars($profile['profileFirstText'])); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Partner Information -->
|
||||
<?php if ($partner): ?>
|
||||
<div class="mb-4">
|
||||
<h5>Partner:</h5>
|
||||
<div class="alert alert-info">
|
||||
<i class="fas fa-heart text-danger"></i>
|
||||
Partnerschaft mit
|
||||
<a href="profile.php?user=<?php echo $profile['profilePartner']; ?>" class="alert-link">
|
||||
<?php echo htmlspecialchars($partner['FirstName'] . ' ' . $partner['LastName']); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Skills und Interessen -->
|
||||
<?php if ($profile['profileSkillsMask'] || $profile['profileSkillsText']): ?>
|
||||
<div class="mb-4">
|
||||
<h5>Skills & Interessen:</h5>
|
||||
<?php if ($profile['profileSkillsText']): ?>
|
||||
<p><?php echo nl2br(htmlspecialchars($profile['profileSkillsText'])); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php if ($profile['profileSkillsMask']): ?>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<?php
|
||||
// Skills Mask zu lesbaren Skills konvertieren (vereinfacht)
|
||||
$skills = ['Building', 'Texturing', 'Scripting', 'Clothing', 'Photography', 'Modeling'];
|
||||
foreach ($skills as $index => $skill) {
|
||||
if ($profile['profileSkillsMask'] & (1 << $index)) {
|
||||
echo '<span class="badge bg-secondary">' . $skill . '</span>';
|
||||
}
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Sprachen -->
|
||||
<?php if ($profile['profileLanguages']): ?>
|
||||
<div class="mb-4">
|
||||
<h5>Sprachen:</h5>
|
||||
<p><?php echo htmlspecialchars($profile['profileLanguages']); ?></p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<!-- Profilbild -->
|
||||
<?php if ($profile['profileImage'] && $profile['profileImage'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<div class="text-center mb-4">
|
||||
<h6>Profilbild:</h6>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $profile['profileImage']; ?>"
|
||||
class="img-fluid rounded"
|
||||
alt="Profilbild"
|
||||
style="max-height: 250px;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- First Life Bild -->
|
||||
<?php if ($profile['profileFirstImage'] && $profile['profileFirstImage'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<div class="text-center mb-4">
|
||||
<h6>First Life Bild:</h6>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $profile['profileFirstImage']; ?>"
|
||||
class="img-fluid rounded"
|
||||
alt="First Life Bild"
|
||||
style="max-height: 200px;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Schnelle Statistiken -->
|
||||
<div class="card bg-light">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">Profil-Statistiken</h6>
|
||||
<ul class="list-unstyled mb-0">
|
||||
<li><strong>Freunde:</strong> <?php echo number_format($friendCount, 0, ',', '.'); ?></li>
|
||||
<li><strong>Account erstellt:</strong>
|
||||
<?php echo $profile['Created'] ? date('d.m.Y', $profile['Created']) : 'Unbekannt'; ?>
|
||||
</li>
|
||||
<?php if ($profile['profileWantToMask']): ?>
|
||||
<li><strong>Möchte:</strong>
|
||||
<?php
|
||||
$wantTo = [];
|
||||
if ($profile['profileWantToMask'] & 1) $wantTo[] = 'Bauen';
|
||||
if ($profile['profileWantToMask'] & 2) $wantTo[] = 'Erkunden';
|
||||
if ($profile['profileWantToMask'] & 4) $wantTo[] = 'Freunde treffen';
|
||||
if ($profile['profileWantToMask'] & 8) $wantTo[] = 'Unterhalten';
|
||||
echo implode(', ', $wantTo);
|
||||
?>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Picks Tab -->
|
||||
<div class="tab-pane fade" id="picks">
|
||||
<?php
|
||||
$picksResult = getUserPicks($con, $userId);
|
||||
$picksCount = mysqli_num_rows($picksResult);
|
||||
?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h5><?php echo $picksCount; ?> Picks von diesem Benutzer</h5>
|
||||
<a href="picks.php?user=<?php echo urlencode($userId); ?>" class="btn btn-primary">
|
||||
<i class="fas fa-external-link-alt"></i> Alle Picks anzeigen
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php if ($picksCount > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($pick = mysqli_fetch_assoc($picksResult)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card h-100 <?php echo $pick['toppick'] ? 'border-warning' : ''; ?>">
|
||||
<?php if ($pick['toppick']): ?>
|
||||
<div class="card-header bg-warning text-dark text-center py-1">
|
||||
<small><i class="fas fa-star"></i> TOP PICK</small>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($pick['snapshotuuid'] && $pick['snapshotuuid'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $pick['snapshotuuid']; ?>"
|
||||
class="card-img-top"
|
||||
alt="Pick Bild"
|
||||
style="height: 120px; object-fit: cover;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-body">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($pick['name']); ?></h6>
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo htmlspecialchars(substr($pick['description'], 0, 80) . (strlen($pick['description']) > 80 ? '...' : '')); ?>
|
||||
</p>
|
||||
<a href="picks.php?action=view&id=<?php echo $pick['pickuuid']; ?>" class="btn btn-sm btn-outline-primary">
|
||||
Details
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-map-marker-alt fa-3x text-muted mb-3"></i>
|
||||
<h6>Keine Picks vorhanden</h6>
|
||||
<p class="text-muted">Dieser Benutzer hat noch keine Picks erstellt.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Classifieds Tab -->
|
||||
<div class="tab-pane fade" id="classifieds">
|
||||
<?php
|
||||
$classifiedsResult = getUserClassifieds($con, $userId);
|
||||
$classifiedsCount = mysqli_num_rows($classifiedsResult);
|
||||
?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h5><?php echo $classifiedsCount; ?> Klassifizierte Anzeigen</h5>
|
||||
<a href="classifieds.php?user=<?php echo urlencode($userId); ?>" class="btn btn-primary">
|
||||
<i class="fas fa-external-link-alt"></i> Alle Anzeigen anzeigen
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php if ($classifiedsCount > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($classified = mysqli_fetch_assoc($classifiedsResult)): ?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card h-100">
|
||||
<?php if ($classified['snapshotuuid'] && $classified['snapshotuuid'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $classified['snapshotuuid']; ?>"
|
||||
class="card-img-top"
|
||||
alt="Anzeigenbild"
|
||||
style="height: 120px; object-fit: cover;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-body">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($classified['name']); ?></h6>
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo htmlspecialchars(substr($classified['description'], 0, 80) . (strlen($classified['description']) > 80 ? '...' : '')); ?>
|
||||
</p>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<span class="badge bg-success">L$ <?php echo number_format($classified['priceforlisting'], 0, ',', '.'); ?></span>
|
||||
<a href="classifieds.php?action=view&id=<?php echo $classified['classifieduuid']; ?>" class="btn btn-sm btn-outline-primary">
|
||||
Details
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-ad fa-3x text-muted mb-3"></i>
|
||||
<h6>Keine Anzeigen vorhanden</h6>
|
||||
<p class="text-muted">Dieser Benutzer hat noch keine klassifizierten Anzeigen erstellt.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<!-- Groups Tab -->
|
||||
<div class="tab-pane fade" id="groups">
|
||||
<?php
|
||||
$groupsResult = getUserGroups($con, $userId);
|
||||
$groupsCount = mysqli_num_rows($groupsResult);
|
||||
?>
|
||||
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h5><?php echo $groupsCount; ?> Gruppen-Mitgliedschaften</h5>
|
||||
<a href="groups.php?user=<?php echo urlencode($userId); ?>" class="btn btn-primary">
|
||||
<i class="fas fa-external-link-alt"></i> Alle Gruppen anzeigen
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<?php if ($groupsCount > 0): ?>
|
||||
<div class="row">
|
||||
<?php while ($group = mysqli_fetch_assoc($groupsResult)): ?>
|
||||
<div class="col-md-6 mb-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($group['GroupName']); ?></h6>
|
||||
<?php if ($group['Title']): ?>
|
||||
<p class="text-primary mb-2"><strong><?php echo htmlspecialchars($group['Title']); ?></strong></p>
|
||||
<?php endif; ?>
|
||||
<?php if ($group['Charter']): ?>
|
||||
<p class="card-text text-muted small">
|
||||
<?php echo htmlspecialchars(substr($group['Charter'], 0, 100) . (strlen($group['Charter']) > 100 ? '...' : '')); ?>
|
||||
</p>
|
||||
<?php endif; ?>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<?php if ($group['Contribution']): ?>
|
||||
<span class="badge bg-info">L$ <?php echo number_format($group['Contribution'], 0, ',', '.'); ?></span>
|
||||
<?php endif; ?>
|
||||
<a href="groups.php?action=view&id=<?php echo $group['GroupID']; ?>" class="btn btn-sm btn-outline-primary">
|
||||
Details
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
<?php else: ?>
|
||||
<div class="text-center py-5">
|
||||
<i class="fas fa-users fa-3x text-muted mb-3"></i>
|
||||
<h6>Keine Gruppen-Mitgliedschaften</h6>
|
||||
<p class="text-muted">Dieser Benutzer ist in keinen öffentlichen Gruppen.</p>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
<div class="alert alert-warning">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
Benutzer nicht gefunden oder kein Profil verfügbar.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php else: ?>
|
||||
<!-- Suchansicht -->
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h4><i class="fas fa-search"></i> Benutzerprofile durchsuchen</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
<div class="col-md-8 mx-auto">
|
||||
<p class="text-center text-muted mb-4">
|
||||
Geben Sie den Namen eines Benutzers ein, um sein Profil anzuzeigen.
|
||||
</p>
|
||||
|
||||
<form method="GET" action="profile.php" class="mb-4">
|
||||
<div class="row">
|
||||
<div class="col-md-5">
|
||||
<input type="text" class="form-control form-control-lg"
|
||||
name="firstname"
|
||||
placeholder="Vorname"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<input type="text" class="form-control form-control-lg"
|
||||
name="lastname"
|
||||
placeholder="Nachname"
|
||||
required>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<button type="submit" class="btn btn-primary btn-lg w-100">
|
||||
<i class="fas fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if ($firstName && $lastName && !$userId): ?>
|
||||
<div class="alert alert-warning">
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
Benutzer "<?php echo htmlspecialchars($firstName . ' ' . $lastName); ?>" nicht gefunden.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Beispiel-Profile anzeigen -->
|
||||
<hr class="my-4">
|
||||
<h5 class="text-center mb-4">Kürzlich aktive Benutzer mit Profilen</h5>
|
||||
|
||||
<div class="row">
|
||||
<?php
|
||||
$recentUsers = mysqli_query($con, "
|
||||
SELECT ua.PrincipalID, ua.FirstName, ua.LastName,
|
||||
up.profileAboutText, up.profileImage, gu.Login
|
||||
FROM UserAccounts ua
|
||||
LEFT JOIN userprofile up ON ua.PrincipalID = up.useruuid
|
||||
LEFT JOIN GridUser gu ON ua.PrincipalID = gu.UserID
|
||||
WHERE up.useruuid IS NOT NULL
|
||||
AND (up.profileAboutText IS NOT NULL OR up.profileImage != '00000000-0000-0000-0000-000000000000')
|
||||
ORDER BY gu.Login DESC
|
||||
LIMIT 6
|
||||
");
|
||||
|
||||
while ($user = mysqli_fetch_assoc($recentUsers)):
|
||||
?>
|
||||
<div class="col-md-6 col-lg-4 mb-3">
|
||||
<div class="card">
|
||||
<?php if ($user['profileImage'] && $user['profileImage'] != '00000000-0000-0000-0000-000000000000'): ?>
|
||||
<img src="<?php echo GRID_ASSETS_SERVER . $user['profileImage']; ?>"
|
||||
class="card-img-top"
|
||||
alt="Profilbild"
|
||||
style="height: 150px; object-fit: cover;"
|
||||
onerror="this.src='<?php echo ASSET_FEHLT; ?>';">
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="card-body">
|
||||
<h6 class="card-title"><?php echo htmlspecialchars($user['FirstName'] . ' ' . $user['LastName']); ?></h6>
|
||||
<p class="card-text text-muted small">
|
||||
<?php
|
||||
if ($user['profileAboutText']) {
|
||||
echo htmlspecialchars(substr($user['profileAboutText'], 0, 80) . (strlen($user['profileAboutText']) > 80 ? '...' : ''));
|
||||
} else {
|
||||
echo "Vollständiges Profil verfügbar";
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
<a href="profile.php?user=<?php echo $user['PrincipalID']; ?>" class="btn btn-primary btn-sm w-100">
|
||||
<i class="fas fa-eye"></i> Profil anzeigen
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endwhile; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.card-img-top {
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.card:hover .card-img-top {
|
||||
transform: scale(1.02);
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link {
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.nav-tabs .nav-link.active {
|
||||
background-color: var(--bs-body-bg);
|
||||
border-color: var(--bs-border-color) var(--bs-border-color) var(--bs-body-bg);
|
||||
}
|
||||
|
||||
.text-justify {
|
||||
text-align: justify;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
// Tab-Hash Navigation
|
||||
if (window.location.hash) {
|
||||
let hash = window.location.hash;
|
||||
let tabTrigger = document.querySelector(`a[href="${hash}"]`);
|
||||
if (tabTrigger) {
|
||||
let tab = new bootstrap.Tab(tabTrigger);
|
||||
tab.show();
|
||||
}
|
||||
}
|
||||
|
||||
// Hash zu URL hinzufügen beim Tab-Wechsel
|
||||
document.querySelectorAll('a[data-bs-toggle="tab"]').forEach(function(tabEl) {
|
||||
tabEl.addEventListener('shown.bs.tab', function(event) {
|
||||
let hash = event.target.getAttribute('href');
|
||||
if (history.pushState) {
|
||||
history.pushState(null, null, hash);
|
||||
} else {
|
||||
location.hash = hash;
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php
|
||||
mysqli_close($con);
|
||||
include_once "include/footerModern.php";
|
||||
?>
|
||||
Reference in New Issue
Block a user