This commit is contained in:
ManfredAabye
2025-10-21 10:16:21 +02:00
committed by GitHub
parent fe3e34616b
commit d8ea909b77
7 changed files with 4614 additions and 0 deletions
+379
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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";
?>
+480
View File
@@ -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
View File
@@ -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";
?>