churchtube/profile.php

219 lines
11 KiB
PHP

<?php
require_once 'includes/db.php';
require_once 'includes/auth.php';
if (!isLoggedIn()) {
header('Location: login.php');
exit;
}
$user_id = $_SESSION['user_id'];
$success = '';
$error = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['change_password'])) {
$old_pass = $_POST['old_password'];
$new_pass = $_POST['new_password'];
$confirm_pass = $_POST['confirm_password'];
$stmt = $pdo->prepare("SELECT password FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user = $stmt->fetch();
if (password_verify($old_pass, $user['password'])) {
if ($new_pass === $confirm_pass) {
if (strlen($new_pass) >= 6) {
$hashed = password_hash($new_pass, PASSWORD_DEFAULT);
$pdo->prepare("UPDATE users SET password = ? WHERE id = ?")->execute([$hashed, $user_id]);
$success = "Password changed successfully!";
} else {
$error = "New password must be at least 6 characters.";
}
} else {
$error = "New passwords do not match.";
}
} else {
$error = "Incorrect current password.";
}
}
if (isset($_POST['update_avatar'])) {
if (isset($_FILES['avatar']) && $_FILES['avatar']['error'] === 0) {
$ext = strtolower(pathinfo($_FILES['avatar']['name'], PATHINFO_EXTENSION));
$allowed = ['jpg', 'jpeg', 'png', 'webp'];
if (in_array($ext, $allowed)) {
$filename = 'avatar_' . $user_id . '_' . time() . '.' . $ext;
if (move_uploaded_file($_FILES['avatar']['tmp_name'], 'uploads/' . $filename)) {
// Delete old avatar if exists
$stmt = $pdo->prepare("SELECT avatar_url FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$old = $stmt->fetchColumn();
if ($old && strpos($old, 'uploads/') === 0) @unlink($old);
$avatar_url = 'uploads/' . $filename;
$pdo->prepare("UPDATE users SET avatar_url = ? WHERE id = ?")->execute([$avatar_url, $user_id]);
$success = "Avatar updated!";
}
} else {
$error = "Invalid image format.";
}
}
}
}
// Get user data
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = ?");
$stmt->execute([$user_id]);
$user_data = $stmt->fetch();
$avatar = $user_data['avatar_url'] ?: '';
// Get bookmarks
$stmt = $pdo->prepare("SELECT v.* FROM videos v JOIN bookmarks b ON v.id = b.video_id WHERE b.user_id = ? ORDER BY b.created_at DESC");
$stmt->execute([$user_id]);
$bookmarks = $stmt->fetchAll();
require_once 'includes/header.php';
?>
<div style="max-width: 1000px; margin: 40px auto; padding: 0 24px; display: grid; grid-template-columns: 300px 1fr; gap: 40px;">
<!-- Sidebar -->
<div>
<div style="background: var(--bg-card); padding: 24px; border-radius: 16px; border: 1px solid var(--glass-border); position: sticky; top: 100px;">
<div style="text-align: center; margin-bottom: 24px;">
<div style="width: 100px; height: 100px; background: var(--primary-color); border-radius: 50%; display: flex; align-items: center; justify-content: center; margin: 0 auto 16px; overflow: hidden; border: 3px solid var(--glass-border);">
<?php if ($avatar): ?>
<img src="<?= htmlspecialchars($avatar) ?>" style="width: 100%; height: 100%; object-fit: cover;">
<?php else: ?>
<span style="font-size: 2.5rem; color: white;"><?= strtoupper(substr($_SESSION['username'], 0, 1)) ?></span>
<?php endif; ?>
</div>
<h3><?= htmlspecialchars($_SESSION['username']) ?></h3>
<p style="color: var(--text-muted); font-size: 0.9rem;">Member since <?= date('M Y', strtotime($user_data['created_at'])) ?></p>
</div>
<form method="POST" enctype="multipart/form-data" style="margin-bottom: 24px;">
<input type="hidden" name="update_avatar" value="1">
<label class="btn" style="background: var(--glass); font-size: 0.8rem; cursor: pointer; display: block; text-align: center;">
<i class="fas fa-camera"></i> Change Avatar
<input type="file" name="avatar" style="display: none;" onchange="this.form.submit()">
</label>
</form>
<div style="display: flex; flex-direction: column; gap: 8px;">
<a href="#bookmarks" class="btn" style="background: var(--glass); justify-content: flex-start;"><i class="fas fa-bookmark" style="width: 20px;"></i> My Bookmarks</a>
<a href="#security" class="btn" style="background: var(--glass); justify-content: flex-start;"><i class="fas fa-shield-alt" style="width: 20px;"></i> Security</a>
<a href="logout.php" class="btn" style="background: rgba(255,64,129,0.1); color: #ff4081; justify-content: flex-start;"><i class="fas fa-sign-out-alt" style="width: 20px;"></i> Logout</a>
</div>
</div>
</div>
<!-- Main Content -->
<div>
<!-- Bookmarks Section -->
<section id="bookmarks" style="margin-bottom: 60px;">
<h2 style="margin-bottom: 24px;">My Bookmarks</h2>
<?php
$stmt = $pdo->prepare("SELECT v.*, b.video_timestamp FROM videos v JOIN bookmarks b ON v.id = b.video_id WHERE b.user_id = ? ORDER BY b.created_at DESC");
$stmt->execute([$user_id]);
$bookmarks = $stmt->fetchAll();
function formatTime($seconds) {
if ($seconds <= 0) return "";
$mins = floor($seconds / 60);
$secs = floor($seconds % 60);
return sprintf("%d:%02d", $mins, $secs);
}
?>
<?php if (empty($bookmarks)): ?>
<div style="background: var(--bg-card); padding: 40px; border-radius: 16px; border: 1px solid var(--glass-border); text-align: center; color: var(--text-muted);">
<i class="fas fa-bookmark" style="font-size: 3rem; margin-bottom: 16px; display: block;"></i>
<p>You haven't bookmarked any sermons yet.</p>
</div>
<?php else: ?>
<div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 20px;">
<?php foreach ($bookmarks as $v):
$time_str = formatTime($v['video_timestamp']);
?>
<div style="background: var(--bg-card); border-radius: 12px; border: 1px solid var(--glass-border); overflow: hidden; position: relative;">
<a href="watch.php?id=<?= $v['id'] ?><?= $v['video_timestamp'] > 0 ? '&t='.$v['video_timestamp'] : '' ?>" style="text-decoration: none; color: inherit;">
<div style="height: 150px; background-image: url('<?= $v['thumbnail_url'] ?: 'assets/images/default_thumb.png' ?>'); background-size: cover; background-position: center; position: relative;">
<?php if ($time_str): ?>
<div style="position: absolute; bottom: 8px; right: 8px; background: rgba(0,0,0,0.8); color: white; padding: 2px 6px; border-radius: 4px; font-size: 0.75rem;">
At <?= $time_str ?>
</div>
<?php endif; ?>
</div>
<div style="padding: 12px;">
<h4 style="margin-bottom: 4px; font-size: 0.95rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;"><?= htmlspecialchars($v['title']) ?></h4>
<div style="font-size: 0.8rem; color: var(--text-muted);">
Saved on <?= date('M d, Y', strtotime($v['created_at'])) ?>
</div>
</div>
</a>
<button onclick="removeBookmark(<?= $v['id'] ?>)" style="position: absolute; top: 8px; right: 8px; background: rgba(255,64,129,0.9); color: white; border: none; width: 28px; height: 28px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 10px rgba(0,0,0,0.3);">
<i class="fas fa-times"></i>
</button>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</section>
<script>
async function removeBookmark(id) {
if (!confirm('Remove this bookmark?')) return;
const res = await fetch('api/toggle_bookmark.php', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: `video_id=${id}`
});
const data = await res.json();
if (data.success) {
location.reload();
}
}
</script>
<!-- Security Section -->
<section id="security">
<h2 style="margin-bottom: 24px;">Security</h2>
<div style="background: var(--bg-card); padding: 32px; border-radius: 16px; border: 1px solid var(--glass-border);">
<h3>Change Password</h3>
<p style="color: var(--text-muted); margin-bottom: 24px; font-size: 0.9rem;">Keep your account secure by using a strong password.</p>
<?php if ($success): ?>
<div style="background: rgba(76,175,80,0.1); color: #4caf50; padding: 12px; border-radius: 8px; margin-bottom: 20px; border: 1px solid rgba(76,175,80,0.2);">
<?= $success ?>
</div>
<?php endif; ?>
<?php if ($error): ?>
<div style="background: rgba(255,64,129,0.1); color: #ff4081; padding: 12px; border-radius: 8px; margin-bottom: 20px; border: 1px solid rgba(255,64,129,0.2);">
<?= $error ?>
</div>
<?php endif; ?>
<form method="POST">
<input type="hidden" name="change_password" value="1">
<div class="form-group">
<label class="form-label">Current Password</label>
<input type="password" name="old_password" class="form-control" required>
</div>
<div class="form-group">
<label class="form-label">New Password</label>
<input type="password" name="new_password" class="form-control" required minlength="6">
</div>
<div class="form-group">
<label class="form-label">Confirm New Password</label>
<input type="password" name="confirm_password" class="form-control" required minlength="6">
</div>
<button type="submit" class="btn btn-primary" style="margin-top: 12px;">Update Password</button>
</form>
</div>
</section>
</div>
</div>
<?php require_once 'includes/footer.php'; ?>