<!-- Additional styles to ensure dropdown works on all pages -->
<style>
.user-dropdown {
position: relative;
z-index: 1051; /* Ensure dropdown container has high z-index */
}
.user-dropdown-menu {
position: absolute;
top: 100%;
right: 0;
background: white;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
padding: 10px 0;
min-width: 200px;
z-index: 1052; /* Higher than parent */
display: none;
margin-top: 10px;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, visibility 0.3s, transform 0.3s;
transform: translateY(-10px);
}
.user-dropdown-menu.show {
display: block !important;
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.user-dropdown-menu a {
display: block;
padding: 10px 20px;
color: var(--dark-color);
text-decoration: none;
transition: all var(--transition-speed);
}
.user-dropdown-menu a:hover {
background: var(--light-color);
color: var(--primary-color);
}
.user-dropdown-menu a i {
margin-right: 10px;
width: 20px;
text-align: center;
}
.dropdown-divider {
height: 0;
margin: 0.5rem 0;
overflow: hidden;
border-top: 1px solid #e9ecef;
}
.dropdown-item {
display: block;
width: 100%;
padding: 0.25rem 1.5rem;
clear: both;
font-weight: 400;
color: #212529;
text-align: inherit;
white-space: nowrap;
background-color: transparent;
border: 0;
}
/* Notification styles */
.notification-badge {
position: absolute;
top: -5px;
right: -5px;
padding: 0.15rem 0.4rem;
border-radius: 50%;
font-size: 0.65rem;
background: var(--danger-color);
color: white;
font-weight: 600;
}
.notifications-dropdown {
position: relative;
margin-right: 20px;
}
.notifications-icon {
width: 35px;
height: 35px;
display: flex;
align-items: center;
justify-content: center;
background: rgba(78, 115, 223, 0.1);
border-radius: 50%;
cursor: pointer;
transition: all var(--transition-speed);
}
.notifications-icon:hover {
background: rgba(78, 115, 223, 0.2);
transform: translateY(-2px);
}
.notifications-icon i {
color: var(--primary-color);
font-size: 1rem;
}
.notifications-dropdown-menu {
position: absolute;
top: 100%;
right: 0;
background: white;
border-radius: 10px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
padding: 0;
min-width: 320px;
z-index: 1052;
display: none;
margin-top: 10px;
opacity: 0;
visibility: hidden;
transition: opacity 0.3s, visibility 0.3s, transform 0.3s;
transform: translateY(-10px);
}
.notifications-dropdown-menu.show {
display: block !important;
opacity: 1;
visibility: visible;
transform: translateY(0);
}
.notifications-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 15px;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
.notifications-header h6 {
margin: 0;
font-weight: 600;
}
.mark-all-read {
font-size: 0.8rem;
color: var(--primary-color);
cursor: pointer;
transition: all 0.2s;
}
.mark-all-read:hover {
text-decoration: underline;
}
.notifications-list {
max-height: 350px;
overflow-y: auto;
padding: 0;
margin: 0;
list-style: none;
}
.notifications-list li {
padding: 12px 15px;
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
position: relative;
transition: all var(--transition-speed);
}
.notifications-list li:hover {
background-color: rgba(0, 0, 0, 0.02);
}
.notifications-list li.unread {
background-color: rgba(78, 115, 223, 0.05);
}
.notifications-list li.unread:before {
content: '';
position: absolute;
left: 5px;
top: 50%;
transform: translateY(-50%);
width: 8px;
height: 8px;
border-radius: 50%;
background-color: var(--primary-color);
}
.notification-item {
display: flex;
align-items: center;
cursor: pointer;
}
.notification-icon {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
margin-right: 15px;
background-color: rgba(78, 115, 223, 0.1);
}
.notification-icon.success { background-color: rgba(28, 200, 138, 0.1); }
.notification-icon.success i { color: var(--success-color); }
.notification-icon.warning { background-color: rgba(246, 194, 62, 0.1); }
.notification-icon.warning i { color: var(--warning-color); }
flex: 1;
}
.notification-title {
font-size: 0.85rem;
font-weight: 600;
margin-bottom: 3px;
color: var(--dark-color);
}
.notification-desc {
font-size: 0.75rem;
color: var(--secondary-color);
margin-bottom: 0;
}
.notification-time {
font-size: 0.7rem;
color: var(--secondary-color);
margin-top: 3px;
}
.notifications-footer {
text-align: center;
padding: 10px;
border-top: 1px solid rgba(0, 0, 0, 0.05);
}
.view-all {
font-size: 0.85rem;
color: var(--primary-color);
font-weight: 600;
text-decoration: none;
transition: all var(--transition-speed);
}
.view-all:hover {
color: var(--primary-dark);
text-decoration: underline;
}
/* Ensure animation works */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
<!-- Topbar -->
<div class="topbar">
<div class="d-flex align-items-center">
<button type="button" class="btn btn-light me-3 d-flex align-items-center justify-content-center" id="topbarSidebarToggler" aria-label="Toggle Sidebar">
<i class="fas fa-bars"></i>
</button>
<h4 class="slideInLeft"><?php echo ucfirst(str_replace('.php', '', $current_page)); ?></h4>
</div>
<div class="d-flex align-items-center">
<!-- <div class="search-box me-4">
<i class="fas fa-search"></i>
<input type="text" class="form-control" placeholder="Search...">
</div> -->
<!-- Notifications Dropdown -->
<div class="notifications-dropdown me-3">
<div class="notifications-icon" id="notificationsDropdownToggle">
<i class="fas fa-bell"></i>
<?php
// Get unread notifications count from database - this is a placeholder
// You'll need to implement the actual query
$unread_count = 2; // Placeholder value
if ($unread_count > 0):
?>
<span class="notification-badge"><?php echo $unread_count; ?></span>
<?php endif; ?>
</div>
<div class="notifications-dropdown-menu" id="notificationsDropdownMenu">
<div class="notifications-header">
<h6>Notifications</h6>
<span class="mark-all-read">Mark all as read</span>
</div>
<ul class="notifications-list">
<li class="unread">
<div class="notification-item">
<div class="notification-icon info">
<i class="fas fa-book"></i>
</div>
<div class="notification-content">
<div class="notification-title">New Course Material</div>
<div class="notification-desc">New material added to Web Development course</div>
<div class="notification-time">2 hours ago</div>
</div>
</div>
</li>
<li class="unread">
<div class="notification-item">
<div class="notification-icon warning">
<i class="fas fa-exclamation-triangle"></i>
</div>
<div class="notification-content">
<div class="notification-title">Assignment Due</div>
<div class="notification-desc">Python assignment is due tomorrow</div>
<div class="notification-time">5 hours ago</div>
</div>
</div>
</li>
<li>
<div class="notification-item">
<div class="notification-icon success">
<i class="fas fa-check-circle"></i>
</div>
<div class="notification-content">
<div class="notification-title">Assignment Graded</div>
<div class="notification-desc">Your Java assignment has been graded</div>
<div class="notification-time">Yesterday</div>
</div>
</div>
</li>
<li>
<div class="notification-item">
<div class="notification-icon danger">
<i class="fas fa-times-circle"></i>
</div>
<div class="notification-content">
<div class="notification-title">Payment Reminder</div>
<div class="notification-desc">Monthly payment is due in 3 days</div>
<div class="notification-time">2 days ago</div>
</div>
</div>
</li>
</ul>
<div class="notifications-footer">
<a href="notifications.php" class="view-all">View All Notifications</a>
</div>
</div>
</div>
<div class="user-dropdown">
<div class="user-profile" id="userDropdownToggle" style="cursor: pointer;">
<div class="user-image">
<?php
// Get user profile image
$profileImage = '../assets/img/default-avatar.png'; // Default image
if (isset($_SESSION['user_id'])) {
$userId = $_SESSION['user_id'];
// First check if the profile_image column exists in the users table
$checkColumn = $conn->query("SHOW COLUMNS FROM users LIKE 'profile_image'");
if ($checkColumn && $checkColumn->num_rows > 0) {
// Column exists, proceed with the select
$stmt = $conn->prepare("SELECT profile_image FROM users WHERE id = ?");
$stmt->bind_param("i", $userId);
$stmt->execute();
$result = $stmt->get_result();
if ($row = $result->fetch_assoc()) {
if (!empty($row['profile_image'])) {
$profileImage = '../' . $row['profile_image'];
}
}
$stmt->close();
} else {
// Profile image column doesn't exist, we need to add it
error_log("profile_image column missing in users table. Please run the update_users_table.php script.");
}
}
?>
<img src="<?php echo formatUrl($profileImage); ?>" alt="User">
</div>
<div class="user-info">
<div class="user-name"><?php echo htmlspecialchars($_SESSION['username'] ?? 'Admin'); ?></div>
<div class="user-role"><?php echo get_role_display_name($_SESSION['role']); ?></div>
</div>
<i class="fas fa-chevron-down ms-2 text-muted"></i>
</div>
<div class="user-dropdown-menu" id="userDropdownMenu">
<a href="profile.php"><i class="fas fa-user"></i> Profile</a>
<a href="settings.php"><i class="fas fa-cog"></i> Settings</a>
<div class="dropdown-divider"></div>
<div class="dropdown-item text-muted">
<small><i class="fas fa-user-tag me-1"></i> <?php echo get_role_display_name($_SESSION['role'] ?? 'admin'); ?></small>
</div>
<div class="dropdown-divider"></div>
<a href="../logout.php"><i class="fas fa-sign-out-alt"></i> Logout</a>
</div>
</div>
</div>
</div>
<script>
// Ensure dropdown functionality works on all pages
document.addEventListener('DOMContentLoaded', function() {
// User dropdown toggle
const userDropdownToggle = document.getElementByClassName("user-dropdown-toggle");
const userDropdownMenu = document.getElementByClassName("user-dropdown-menu");
if(userDropdownToggle && userDropdownMenu) {
// Initialize dropdown position
const positionDropdown = function() {
const rect = userDropdownToggle.getBoundingClientRect();
userDropdownMenu.style.position = 'absolute';
userDropdownMenu.style.top = (rect.height + 5) + 'px';
userDropdownMenu.style.right = '0';
};
// Position dropdown initially
positionDropdown();
// Add click event with stopPropagation to prevent document click from immediately closing it
userDropdownToggle.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
userDropdownMenu.classList.toggle('show');
// Reposition dropdown when showing
if(userDropdownMenu.classList.contains('show')) {
positionDropdown();
}
});
// Close the dropdown when clicking outside
document.addEventListener('click', function(e) {
if (userDropdownMenu.classList.contains('show') &&
!userDropdownToggle.contains(e.target) &&
!userDropdownMenu.contains(e.target)) {
userDropdownMenu.classList.remove('show');
}
});
// Ensure dropdown is properly positioned on window resize
window.addEventListener('resize', function() {
if (userDropdownMenu.classList.contains('show')) {
positionDropdown();
}
});
// Add keyboard accessibility for dropdown
userDropdownToggle.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
userDropdownMenu.classList.toggle('show');
// Reposition dropdown when showing
if(userDropdownMenu.classList.contains('show')) {
positionDropdown();
}
}
});
// Add escape key to close dropdown
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && userDropdownMenu.classList.contains('show')) {
userDropdownMenu.classList.remove('show');
}
});
} else {
console.error('User dropdown elements not found');
}
});
document.addEventListener('DOMContentLoaded', function() {
// Notifications dropdown toggle
const notificationsToggle = document.getElementById("notificationsDropdownToggle");
const notificationsMenu = document.getElementById("notificationsDropdownMenu");
if(notificationsToggle && notificationsMenu) {
// Initialize dropdown position
const positionNotifications = function() {
const rect = notificationsToggle.getBoundingClientRect();
notificationsMenu.style.position = 'absolute';
notificationsMenu.style.top = (rect.height + 5) + 'px';
notificationsMenu.style.right = '0';
};
// Position dropdown initially
positionNotifications();
// Add click event with stopPropagation
notificationsToggle.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
notificationsMenu.classList.toggle('show');
// Reposition dropdown when showing
if(notificationsMenu.classList.contains('show')) {
positionNotifications();
}
});
// Close the dropdown when clicking outside
document.addEventListener('click', function(e) {
if (notificationsMenu.classList.contains('show') &&
!notificationsToggle.contains(e.target) &&
!notificationsMenu.contains(e.target)) {
notificationsMenu.classList.remove('show');
}
});
// Ensure dropdown is properly positioned on window resize
window.addEventListener('resize', function() {
if (notificationsMenu.classList.contains('show')) {
positionNotifications();
}
});
// Handle mark all as read click
const markAllRead = document.querySelector('.mark-all-read');
if (markAllRead) {
markAllRead.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
// Remove unread class from all notifications
document.querySelectorAll('.notifications-list li.unread').forEach(el => {
el.classList.remove('unread');
});
// Remove notification badge
const badge = document.querySelector('.notification-badge');
if (badge) {
badge.remove();
}
// Here you would also make an AJAX call to update the database
console.log('Marked all notifications as read');
});
}
} else {
console.error('Notifications dropdown elements not found');
}
});
</script>