282 lines
12 KiB
PHP
282 lines
12 KiB
PHP
<?php
|
||
require_once 'config.php';
|
||
|
||
if (!isset($_SESSION['user_id'])) {
|
||
header('Location: login.php');
|
||
exit;
|
||
}
|
||
|
||
try {
|
||
$stmt = $pdo->prepare("SELECT * FROM images WHERE user_id = ? ORDER BY uploaded_at DESC");
|
||
$stmt->execute([$_SESSION['user_id']]);
|
||
$userImages = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||
} catch(PDOException $e) {
|
||
$userImages = [];
|
||
}
|
||
|
||
try {
|
||
$stmt = $pdo->prepare("SELECT api_key FROM users WHERE id = ?");
|
||
$stmt->execute([$_SESSION['user_id']]);
|
||
$user = $stmt->fetch(PDO::FETCH_ASSOC);
|
||
} catch(PDOException $e) {
|
||
$user = ['api_key' => null];
|
||
}
|
||
|
||
$success = $_SESSION['success'] ?? '';
|
||
$error = $_SESSION['error'] ?? '';
|
||
unset($_SESSION['success'], $_SESSION['error']);
|
||
|
||
try {
|
||
$stmt = $pdo->prepare("SELECT COUNT(*) as total FROM images WHERE user_id = ?");
|
||
$stmt->execute([$_SESSION['user_id']]);
|
||
$totalImages = $stmt->fetch(PDO::FETCH_ASSOC)['total'];
|
||
|
||
$stmt = $pdo->prepare("SELECT COUNT(*) as public FROM images WHERE user_id = ? AND is_public = 1");
|
||
$stmt->execute([$_SESSION['user_id']]);
|
||
$publicImages = $stmt->fetch(PDO::FETCH_ASSOC)['public'];
|
||
|
||
$stmt = $pdo->prepare("SELECT SUM(views) as total_views FROM images WHERE user_id = ?");
|
||
$stmt->execute([$_SESSION['user_id']]);
|
||
$totalViews = $stmt->fetch(PDO::FETCH_ASSOC)['total_views'] ?: 0;
|
||
|
||
$stmt = $pdo->prepare("SELECT SUM(file_size) as total_size FROM images WHERE user_id = ?");
|
||
$stmt->execute([$_SESSION['user_id']]);
|
||
$totalSize = $stmt->fetch(PDO::FETCH_ASSOC)['total_size'] ?: 0;
|
||
|
||
} catch(PDOException $e) {
|
||
$totalImages = $publicImages = $totalViews = $totalSize = 0;
|
||
}
|
||
?>
|
||
<!DOCTYPE html>
|
||
<html lang="<?php echo $lang; ?>" data-theme="<?php echo $currentUserSettings['dark_mode'] ? 'dark' : 'light'; ?>">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title><?php echo t('dashboard'); ?> - <?php echo SITE_NAME; ?></title>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
|
||
<link rel="stylesheet" href="css/style.css">
|
||
</head>
|
||
<body>
|
||
<?php include 'components/navbar.php'; ?>
|
||
|
||
<div class="container">
|
||
<div class="stats-grid">
|
||
<div class="stat-card card users">
|
||
<div class="stat-number"><?php echo $totalImages; ?></div>
|
||
<div class="stat-label"><?php echo t('total_images'); ?></div>
|
||
<small><?php echo t('public_images'); ?>: <?php echo $publicImages; ?></small>
|
||
</div>
|
||
<div class="stat-card card images">
|
||
<div class="stat-number"><?php echo $publicImages; ?></div>
|
||
<div class="stat-label"><?php echo t('public_images'); ?></div>
|
||
<small><?php echo t('private'); ?>: <?php echo $totalImages - $publicImages; ?></small>
|
||
</div>
|
||
<div class="stat-card card storage">
|
||
<div class="stat-number"><?php echo $totalViews; ?></div>
|
||
<div class="stat-label"><?php echo t('total_views'); ?></div>
|
||
<small><?php echo t('total_engagement'); ?></small>
|
||
</div>
|
||
<div class="stat-card card feedbacks">
|
||
<div class="stat-number"><?php echo formatFileSize($totalSize); ?></div>
|
||
<div class="stat-label"><?php echo t('storage_used'); ?></div>
|
||
<small><?php echo t('total_size'); ?></small>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="dashboard-header">
|
||
<h1><i class="fas fa-th-large"></i> <?php echo t('my_gallery'); ?></h1>
|
||
<a href="upload.php" class="btn btn-primary">
|
||
<i class="fas fa-cloud-upload-alt"></i> <?php echo t('upload_new'); ?>
|
||
</a>
|
||
</div>
|
||
|
||
<?php if($success): ?>
|
||
<div class="alert alert-success">
|
||
<i class="fas fa-check-circle"></i> <?php echo $success; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<?php if($error): ?>
|
||
<div class="alert alert-error">
|
||
<i class="fas fa-exclamation-triangle"></i> <?php echo $error; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<div class="gallery-actions">
|
||
<div class="search-box">
|
||
<input type="text" id="searchInput" placeholder="<?php echo t('search_placeholder'); ?>" onkeyup="searchImages()">
|
||
<select id="filterSelect" onchange="filterImages()">
|
||
<option value="all"><?php echo t('all_images'); ?></option>
|
||
<option value="public"><?php echo t('public'); ?></option>
|
||
<option value="private"><?php echo t('private'); ?></option>
|
||
</select>
|
||
</div>
|
||
<div>
|
||
<span><?php echo t('sort'); ?>:</span>
|
||
<select id="sortSelect" onchange="sortImages()">
|
||
<option value="newest"><?php echo t('sort_newest'); ?></option>
|
||
<option value="oldest"><?php echo t('sort_oldest'); ?></option>
|
||
<option value="views"><?php echo t('sort_views'); ?></option>
|
||
<option value="name"><?php echo t('sort_name'); ?></option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<?php if(empty($userImages)): ?>
|
||
<div class="empty-state card">
|
||
<h3><i class="fas fa-images"></i> <?php echo t('no_images'); ?></h3>
|
||
<p><?php echo t('upload_first'); ?></p>
|
||
<a href="upload.php" class="btn btn-primary">
|
||
<i class="fas fa-cloud-upload-alt"></i> <?php echo t('upload'); ?>
|
||
</a>
|
||
</div>
|
||
<?php else: ?>
|
||
<div class="gallery" id="imageGallery">
|
||
<?php foreach($userImages as $image): ?>
|
||
<div class="gallery-item card" data-title="<?php echo htmlspecialchars($image['title'] ?: ''); ?>" data-public="<?php echo $image['is_public']; ?>" data-views="<?php echo $image['views']; ?>">
|
||
<a href="view-image.php?id=<?php echo $image['id']; ?>">
|
||
<img src="uploads/<?php echo $image['filename']; ?>"
|
||
alt="<?php echo htmlspecialchars($image['title'] ?: t('untitled')); ?>"
|
||
loading="lazy">
|
||
</a>
|
||
<div class="image-info">
|
||
<div class="image-title">
|
||
<?php echo htmlspecialchars($image['title'] ?: t('untitled')); ?>
|
||
</div>
|
||
<div class="image-meta">
|
||
<small><i class="fas fa-calendar"></i> <?php echo date('m-d H:i', strtotime($image['uploaded_at'])); ?></small>
|
||
<small><i class="fas fa-eye"></i> <?php echo $image['views']; ?></small>
|
||
<small><i class="fas fa-weight"></i> <?php echo formatFileSize($image['file_size'] ?? 0); ?></small>
|
||
</div>
|
||
<div class="image-actions">
|
||
<span class="status-badge <?php echo $image['is_public'] ? 'status-public' : 'status-private'; ?>">
|
||
<?php echo $image['is_public'] ? t('public') : t('private'); ?>
|
||
</span>
|
||
<div class="action-buttons">
|
||
<button class="btn btn-sm"
|
||
onclick="copyToClipboard('<?php echo SITE_URL . '/uploads/' . $image['filename']; ?>')">
|
||
<i class="fas fa-copy"></i> <?php echo t('copy'); ?>
|
||
</button>
|
||
<a href="view-image.php?id=<?php echo $image['id']; ?>" class="btn btn-sm">
|
||
<i class="fas fa-eye"></i> <?php echo t('view'); ?>
|
||
</a>
|
||
<a href="delete-image.php?id=<?php echo $image['id']; ?>"
|
||
class="btn btn-sm btn-danger"
|
||
onclick="return confirm('<?php echo t('confirm_delete_image'); ?>')">
|
||
<i class="fas fa-trash"></i> <?php echo t('delete'); ?>
|
||
</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<?php endforeach; ?>
|
||
</div>
|
||
<?php endif; ?>
|
||
|
||
<div class="api-section mt-3">
|
||
<h2><i class="fas fa-code"></i> <?php echo t('api_management'); ?></h2>
|
||
<div class="api-card card">
|
||
<p><?php echo t('api_migrated_message'); ?></p>
|
||
<a href="api-docs.php" class="btn btn-primary">
|
||
<i class="fas fa-book"></i> <?php echo t('view_api_docs'); ?>
|
||
</a>
|
||
|
||
<?php if(!empty($user['api_key'])): ?>
|
||
<div class="mt-2">
|
||
<label><strong><i class="fas fa-key"></i> <?php echo t('your_api_key'); ?>:</strong></label>
|
||
<div class="api-key-input">
|
||
<input type="text" value="<?php echo $user['api_key']; ?>" id="apiKey" readonly>
|
||
<button onclick="copyApiKey()" class="btn">
|
||
<i class="fas fa-copy"></i> <?php echo t('copy'); ?>
|
||
</button>
|
||
</div>
|
||
<small><?php echo t('keep_secret'); ?></small>
|
||
</div>
|
||
<?php endif; ?>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
function copyApiKey() {
|
||
const apiKey = document.getElementById('apiKey');
|
||
apiKey.select();
|
||
document.execCommand('copy');
|
||
alert('<?php echo t('api_key_copied'); ?>');
|
||
}
|
||
|
||
function copyToClipboard(text) {
|
||
if (navigator.clipboard) {
|
||
navigator.clipboard.writeText(text).then(() => {
|
||
alert('<?php echo t('copied_to_clipboard'); ?>');
|
||
});
|
||
} else {
|
||
const textArea = document.createElement('textarea');
|
||
textArea.value = text;
|
||
document.body.appendChild(textArea);
|
||
textArea.select();
|
||
document.execCommand('copy');
|
||
document.body.removeChild(textArea);
|
||
alert('<?php echo t('copied_to_clipboard'); ?>');
|
||
}
|
||
}
|
||
|
||
function searchImages() {
|
||
const searchTerm = document.getElementById('searchInput').value.toLowerCase();
|
||
const items = document.querySelectorAll('.gallery-item');
|
||
|
||
items.forEach(item => {
|
||
const title = item.getAttribute('data-title').toLowerCase();
|
||
if (title.includes(searchTerm)) {
|
||
item.style.display = 'block';
|
||
} else {
|
||
item.style.display = 'none';
|
||
}
|
||
});
|
||
}
|
||
|
||
function filterImages() {
|
||
const filter = document.getElementById('filterSelect').value;
|
||
const items = document.querySelectorAll('.gallery-item');
|
||
|
||
items.forEach(item => {
|
||
const isPublic = item.getAttribute('data-public');
|
||
if (filter === 'all' ||
|
||
(filter === 'public' && isPublic === '1') ||
|
||
(filter === 'private' && isPublic === '0')) {
|
||
item.style.display = 'block';
|
||
} else {
|
||
item.style.display = 'none';
|
||
}
|
||
});
|
||
}
|
||
|
||
function sortImages() {
|
||
const sortBy = document.getElementById('sortSelect').value;
|
||
const gallery = document.getElementById('imageGallery');
|
||
const items = Array.from(document.querySelectorAll('.gallery-item'));
|
||
|
||
items.sort((a, b) => {
|
||
switch(sortBy) {
|
||
case 'newest':
|
||
return 0;
|
||
case 'oldest':
|
||
return 1;
|
||
case 'views':
|
||
const viewsA = parseInt(a.getAttribute('data-views'));
|
||
const viewsB = parseInt(b.getAttribute('data-views'));
|
||
return viewsB - viewsA;
|
||
case 'name':
|
||
const nameA = a.getAttribute('data-title').toLowerCase();
|
||
const nameB = b.getAttribute('data-title').toLowerCase();
|
||
return nameA.localeCompare(nameB);
|
||
default:
|
||
return 0;
|
||
}
|
||
});
|
||
|
||
items.forEach(item => gallery.appendChild(item));
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|