Sindbad~EG File Manager
<?php
require_once '../config/config.php';
require_once '../classes/MemberAuth.php';
// Check if member is logged in
if (!MemberAuth::isMemberLoggedIn()) {
redirect('../login.php');
}
$pageTitle = "Member Portal - " . APP_NAME;
$db = Database::getInstance()->getConnection();
$success = '';
$error = '';
// Get current member data
$currentMember = MemberAuth::getCurrentMember();
if (!$currentMember) {
redirect('../login.php');
}
// Get member details from members table
$stmt = $db->prepare("
SELECT m.*, a.area_name, d.district_name, ass.assembly_name
FROM members m
LEFT JOIN areas a ON m.area_id = a.id
LEFT JOIN districts d ON m.district_id = d.id
LEFT JOIN assemblies ass ON m.assembly_id = ass.id
WHERE m.id = :member_id
");
$stmt->execute(['member_id' => $currentMember['member_id']]);
$memberDetails = $stmt->fetch();
// Load latest transfer request for this member (if any)
$latestTransferRequest = null;
try {
$stmt = $db->prepare("SELECT r.*,
fa.area_name AS from_area_name,
fd.district_name AS from_district_name,
fas.assembly_name AS from_assembly_name,
ta.area_name AS to_area_name,
td.district_name AS to_district_name,
tas.assembly_name AS to_assembly_name
FROM member_transfer_requests r
LEFT JOIN areas fa ON r.from_area_id = fa.id
LEFT JOIN districts fd ON r.from_district_id = fd.id
LEFT JOIN assemblies fas ON r.from_assembly_id = fas.id
LEFT JOIN areas ta ON r.to_area_id = ta.id
LEFT JOIN districts td ON r.to_district_id = td.id
LEFT JOIN assemblies tas ON r.to_assembly_id = tas.id
WHERE r.member_id = :member_id
ORDER BY r.created_at DESC
LIMIT 1");
$stmt->execute(['member_id' => $currentMember['member_id']]);
$latestTransferRequest = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (Exception $e) {
$latestTransferRequest = null;
}
// Load member conversations
$memberConversations = [];
try {
$stmt = $db->prepare("SELECT c.id, c.created_at,
(SELECT message_text FROM chat_messages WHERE conversation_id = c.id ORDER BY id DESC LIMIT 1) AS last_message,
(SELECT created_at FROM chat_messages WHERE conversation_id = c.id ORDER BY id DESC LIMIT 1) AS last_message_time,
(SELECT COUNT(*) FROM chat_messages WHERE conversation_id = c.id AND is_read = 0 AND sender_type = 'admin') AS unread_count
FROM chat_conversations c
WHERE c.member_id = :member_id AND c.type IN ('public', 'member_admin')
ORDER BY (last_message_time IS NULL), last_message_time DESC, c.created_at DESC");
$stmt->execute(['member_id' => $currentMember['member_id']]);
$memberConversations = $stmt->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
$memberConversations = [];
}
// Handle form submissions
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (isset($_POST['update_profile'])) {
try {
// Handle profile photo upload
$profilePhoto = $currentMember['profile_photo'];
if (isset($_FILES['profile_photo']) && $_FILES['profile_photo']['error'] === UPLOAD_ERR_OK) {
$uploadDir = '../uploads/member_photos/';
if (!is_dir($uploadDir)) {
mkdir($uploadDir, 0755, true);
}
$fileExtension = strtolower(pathinfo($_FILES['profile_photo']['name'], PATHINFO_EXTENSION));
$allowedExtensions = ['jpg', 'jpeg', 'png', 'gif'];
if (in_array($fileExtension, $allowedExtensions)) {
$fileName = 'member_' . $currentMember['id'] . '_' . time() . '.' . $fileExtension;
$filePath = $uploadDir . $fileName;
if (move_uploaded_file($_FILES['profile_photo']['tmp_name'], $filePath)) {
$profilePhoto = 'uploads/member_photos/' . $fileName;
// Delete old photo if exists
if ($currentMember['profile_photo'] && file_exists('../' . $currentMember['profile_photo'])) {
unlink('../' . $currentMember['profile_photo']);
}
}
}
}
// Update member details
$stmt = $db->prepare("
UPDATE members SET
phone = :phone,
address_line1 = :address,
city = :city,
occupation = :occupation
WHERE id = :member_id
");
$stmt->execute([
'phone' => $_POST['phone'] ?? '',
'address' => $_POST['address'] ?? '',
'city' => $_POST['city'] ?? '',
'occupation' => $_POST['occupation'] ?? '',
'member_id' => $currentMember['member_id']
]);
// Update member account
$memberAuth = new MemberAuth();
$memberAuth->updateMemberAccount($currentMember['id'], [
'phone' => $_POST['phone'] ?? '',
'profile_photo' => $profilePhoto
]);
$success = "Profile updated successfully!";
// Refresh member data
$currentMember = MemberAuth::getCurrentMember();
$stmt = $db->prepare("
SELECT m.*, a.area_name, d.district_name, ass.assembly_name
FROM members m
LEFT JOIN areas a ON m.area_id = a.id
LEFT JOIN districts d ON m.district_id = d.id
LEFT JOIN assemblies ass ON m.assembly_id = ass.id
WHERE m.id = :member_id
");
$stmt->execute(['member_id' => $currentMember['member_id']]);
$memberDetails = $stmt->fetch();
} catch (Exception $e) {
$error = "Error updating profile: " . $e->getMessage();
}
}
if (isset($_POST['update_account'])) {
try {
$memberAuth = new MemberAuth();
$updateData = [];
if (!empty($_POST['email']) && $_POST['email'] !== $currentMember['email']) {
$updateData['email'] = $_POST['email'];
}
if (!empty($_POST['new_password'])) {
if ($_POST['new_password'] !== $_POST['confirm_password']) {
throw new Exception("Passwords do not match");
}
$updateData['password'] = $_POST['new_password'];
}
if (!empty($updateData)) {
$result = $memberAuth->updateMemberAccount($currentMember['id'], $updateData);
if ($result['success']) {
$success = "Account details updated successfully!";
$currentMember = MemberAuth::getCurrentMember();
} else {
$error = $result['message'];
}
} else {
$error = "No changes to update";
}
} catch (Exception $e) {
$error = "Error updating account: " . $e->getMessage();
}
}
}
// Get settings for theme colors
$stmt = $db->query("SELECT * FROM general_settings ORDER BY id DESC LIMIT 1");
$settings = $stmt->fetch();
$settings = array_merge([
'site_title' => APP_NAME,
'theme_primary_color' => '#3B82F6',
'theme_secondary_color' => '#10B981'
], $settings ?: []);
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?php echo $pageTitle; ?></title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
:root {
--primary-color: <?php echo $settings['theme_primary_color']; ?>;
--secondary-color: <?php echo $settings['theme_secondary_color']; ?>;
}
.bg-primary { background-color: var(--primary-color); }
.bg-secondary { background-color: var(--secondary-color); }
.text-primary { color: var(--primary-color); }
.text-secondary { color: var(--secondary-color); }
.border-primary { border-color: var(--primary-color); }
.gradient-bg { background: linear-gradient(135deg, #1E40AF 0%, #9333EA 50%, #F97316 100%); }
.card-hover { transition: all 0.3s ease; }
.card-hover:hover { transform: translateY(-2px); box-shadow: 0 12px 20px -5px rgba(0,0,0,0.1); }
</style>
</head>
<body class="bg-gray-50">
<!-- Member Portal Header -->
<header class="bg-white shadow-lg sticky top-0 z-50">
<div class="container mx-auto px-4">
<div class="flex items-center justify-between h-16">
<div class="flex items-center space-x-3">
<div class="w-10 h-10 rounded-xl flex items-center justify-center gradient-bg">
<i class="fas fa-church text-white"></i>
</div>
<div>
<h1 class="text-lg font-bold text-gray-800"><?php echo htmlspecialchars($settings['site_title']); ?></h1>
<p class="text-xs text-gray-500">Member Portal</p>
</div>
</div>
<nav class="hidden md:flex items-center space-x-6">
<a href="dashboard.php" class="text-gray-700 hover:text-blue-600 transition">
<i class="fas fa-home mr-1"></i>Dashboard
</a>
<a href="profile.php" class="text-blue-600 font-medium border-b-2 border-blue-600 pb-1">
<i class="fas fa-user mr-1"></i>Profile
</a>
<a href="messages.php" class="text-gray-700 hover:text-blue-600 transition">
<i class="fas fa-comments mr-1"></i>Messages
</a>
<a href="event-checkin.php" class="text-gray-700 hover:text-green-600 transition">
<i class="fas fa-qrcode mr-1"></i>Event Check-in
</a>
<a href="transfer_request.php" class="text-gray-700 hover:text-blue-600 transition">
<i class="fas fa-exchange-alt mr-1"></i>Transfer
</a>
</nav>
<div class="flex items-center space-x-3">
<span class="text-sm text-gray-600 hidden md:block">Welcome, <?php echo htmlspecialchars($memberDetails['first_name'] ?? 'Member'); ?></span>
<a href="../logout.php?member=1" class="text-gray-600 hover:text-red-600 transition">
<i class="fas fa-sign-out-alt mr-1"></i>Logout
</a>
</div>
</div>
</div>
</header>
<div class="container mx-auto px-4 py-8">
<div class="max-w-6xl mx-auto">
<!-- Page Header -->
<div class="mb-8">
<a href="dashboard.php" class="text-sm text-blue-600 hover:text-blue-800 mb-2 inline-block">
<i class="fas fa-arrow-left mr-1"></i>Back to Dashboard
</a>
<h1 class="text-3xl font-bold text-gray-800">
<i class="fas fa-user mr-2 text-blue-500"></i>Profile Management
</h1>
<p class="text-gray-600 mt-2">Manage your profile, account settings, and view your information</p>
</div>
<!-- Messages -->
<?php if ($success): ?>
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded-lg mb-6">
<i class="fas fa-check-circle mr-2"></i><?php echo $success; ?>
</div>
<?php endif; ?>
<?php if ($error): ?>
<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded-lg mb-6">
<i class="fas fa-exclamation-circle mr-2"></i><?php echo $error; ?>
</div>
<?php endif; ?>
<!-- Profile Details (Full Page - No Tabs) -->
<div class="bg-white rounded-xl shadow-lg p-8">
<form method="POST" enctype="multipart/form-data" class="space-y-6">
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Profile Photo -->
<div class="lg:col-span-1">
<div class="text-center">
<div class="mb-4">
<?php if ($currentMember['profile_photo']): ?>
<img src="../<?php echo htmlspecialchars($currentMember['profile_photo']); ?>"
alt="Profile Photo"
class="w-32 h-32 rounded-full mx-auto object-cover border-4 border-primary">
<?php else: ?>
<div class="w-32 h-32 rounded-full mx-auto bg-gray-300 flex items-center justify-center border-4 border-primary">
<i class="fas fa-user text-4xl text-gray-600"></i>
</div>
<?php endif; ?>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Profile Photo</label>
<input type="file" name="profile_photo" accept="image/*"
class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:text-sm file:font-semibold file:bg-primary file:text-white hover:file:bg-opacity-80">
</div>
</div>
</div>
<!-- Profile Information -->
<div class="lg:col-span-2 space-y-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">First Name</label>
<input type="text" value="<?php echo htmlspecialchars($memberDetails['first_name'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg bg-gray-100" readonly>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Last Name</label>
<input type="text" value="<?php echo htmlspecialchars($memberDetails['last_name'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg bg-gray-100" readonly>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Email</label>
<input type="email" value="<?php echo htmlspecialchars($memberDetails['email'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg bg-gray-100" readonly>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Phone</label>
<input type="tel" name="phone" value="<?php echo htmlspecialchars($memberDetails['phone'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Date of Birth</label>
<input type="date" value="<?php echo htmlspecialchars($memberDetails['date_of_birth'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg bg-gray-100" readonly>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Gender</label>
<input type="text" value="<?php echo htmlspecialchars($memberDetails['gender'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg bg-gray-100" readonly>
</div>
<div class="md:col-span-2">
<label class="block text-sm font-medium text-gray-700 mb-2">Address</label>
<input type="text" name="address" value="<?php echo htmlspecialchars($memberDetails['address_line1'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">City</label>
<input type="text" name="city" value="<?php echo htmlspecialchars($memberDetails['city'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Occupation</label>
<input type="text" name="occupation" value="<?php echo htmlspecialchars($memberDetails['occupation'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-primary">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">Area</label>
<input type="text" value="<?php echo htmlspecialchars($memberDetails['area_name'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg bg-gray-100" readonly>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">District</label>
<input type="text" value="<?php echo htmlspecialchars($memberDetails['district_name'] ?? ''); ?>"
class="w-full px-4 py-2 border border-gray-300 rounded-lg bg-gray-100" readonly>
</div>
</div>
<div class="flex justify-end">
<button type="submit" name="update_profile" class="bg-primary text-white px-6 py-2 rounded-lg hover:opacity-90 transition">
<i class="fas fa-save mr-2"></i>Update Profile
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- Footer -->
<footer class="bg-gray-800 text-white py-6 mt-12">
<div class="container mx-auto px-4 text-center">
<p class="text-sm text-gray-400">
© <?php echo date('Y'); ?> <?php echo htmlspecialchars($settings['site_title']); ?>. All rights reserved.
</p>
</div>
</footer>
<?php
// Include Chat Hub Widget (Admin Chat + AI Chatbot)
if (file_exists(__DIR__ . '/../includes/chat-hub-widget.php')) {
include '../includes/chat-hub-widget.php';
}
?>
</body>
</html>
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists