credit abis

This commit is contained in:
root
2026-03-27 00:14:49 +07:00
parent f89fcbee1c
commit 937033ea07
6 changed files with 265 additions and 75 deletions

View File

@@ -9,7 +9,10 @@
<link rel="stylesheet" href="public/css/style.css">
</head>
<body>
<script>if(localStorage.getItem('theme') === 'dark') document.body.classList.add('dark-mode');</script>
<script>
if(localStorage.getItem('theme') === 'dark') document.body.classList.add('dark-mode');
if(localStorage.getItem('sidebar_collapsed') === '1') document.body.classList.add('sidebar-collapsed');
</script>
<div id="toast"></div>
<!-- Profile Picture Modal -->
@@ -82,41 +85,97 @@
</div>
</div>
<div class="app-container">
<aside class="sidebar">
<h2 style="display:flex; align-items:center; gap:8px;">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>
TaskManager
</h2>
<nav style="display:flex; flex-direction:column; gap:0.5rem;">
<a href="?action=dashboard" class="nav-link <?= $action=='dashboard'?'active':'' ?>">
<span style="display:flex;align-items:center;gap:0.6rem;"><i class="fa fa-gauge-high" style="width:16px;"></i> Dashboard</span>
</a>
<a href="?action=tasks" class="nav-link <?= $action=='tasks'?'active':'' ?>">
<span style="display:flex;align-items:center;gap:0.6rem;"><i class="fa fa-list-check" style="width:16px;"></i> Tasks</span>
</a>
<a href="?action=notes" class="nav-link <?= $action=='notes'?'active':'' ?>">
<span style="display:flex;align-items:center;gap:0.6rem;"><i class="fa fa-note-sticky" style="width:16px;"></i> Notes</span>
</a>
<a href="?action=passwords" class="nav-link <?= $action=='passwords'?'active':'' ?>">
<span style="display:flex;align-items:center;gap:0.6rem;"><i class="fa fa-lock" style="width:16px;"></i> Passwords</span>
</a>
<a href="?action=projects" class="nav-link <?= $action=='projects'?'active':'' ?>">
<span style="display:flex;align-items:center;gap:0.6rem;"><i class="fa fa-folder-open" style="width:16px;"></i> Projects</span>
</a>
<a href="?action=notifications" class="nav-link <?= $action=='notifications'?'active':'' ?>">
<span style="display:flex;align-items:center;gap:0.6rem;"><i class="fa fa-bell" style="width:16px;"></i> Notifications</span>
<!-- Notifications Modal -->
<?php
// Fetch notifications for popup
$notif_list = [];
try {
$stmt_n = $pdo->prepare("SELECT * FROM notifications WHERE user_id=? ORDER BY created_at DESC LIMIT 30");
$stmt_n->execute([$user_id]);
$notif_list = $stmt_n->fetchAll();
} catch(Exception $e) {}
?>
<div class="modal-overlay" id="notifications-modal">
<div class="modal-content" style="max-width:460px; max-height:80vh; display:flex; flex-direction:column; padding:0; overflow:hidden;">
<div style="display:flex; justify-content:space-between; align-items:center; padding:1.25rem 1.5rem; border-bottom:1px solid var(--border);">
<h3 style="font-size:1.05rem; font-weight:700;"><i class="fa fa-bell" style="color:var(--primary);"></i> Notifications</h3>
<div style="display:flex; gap:0.5rem; align-items:center;">
<?php if($unread_notifications > 0): ?>
<span class="badge"><?= $unread_notifications ?></span>
<form method="POST" id="mark-all-read-form" style="display:inline;">
<input type="hidden" name="mark_all_read" value="1">
<input type="hidden" name="redirect_to" value="<?= htmlspecialchars($action) ?>">
<button type="submit" class="btn btn-sm btn-secondary" style="font-size:0.75rem;">Mark all read</button>
</form>
<?php endif; ?>
<button onclick="document.getElementById('notifications-modal').classList.remove('active')" style="background:none;border:none;color:var(--text-light);cursor:pointer;font-size:1.2rem;padding:4px;">×</button>
</div>
</div>
<div style="overflow-y:auto; flex:1; padding:0.75rem 0;">
<?php if(empty($notif_list)): ?>
<div style="text-align:center; padding:2.5rem 1rem; color:var(--text-light);">
<i class="fa fa-bell-slash" style="font-size:2rem; display:block; margin-bottom:0.75rem;"></i>
No notifications yet.
</div>
<?php else: foreach($notif_list as $n):
$t = strtotime($n['created_at']);
$diff = time()-$t;
$ago = $diff<60?'just now':($diff<3600?floor($diff/60).'m ago':($diff<86400?floor($diff/3600).'h ago':floor($diff/86400).'d ago'));
?>
<div style="display:flex; align-items:flex-start; gap:0.75rem; padding:0.65rem 1.5rem; border-bottom:1px solid var(--border); transition:background 0.15s; <?= !$n['is_read']?'background:rgba(var(--primary-rgb),0.04);':'' ?>">
<div style="width:8px; height:8px; border-radius:50%; background:<?= !$n['is_read']?'var(--primary)':'transparent' ?>; margin-top:6px; flex-shrink:0;"></div>
<div style="flex:1; min-width:0;">
<div style="font-size:0.875rem; color:var(--text); <?= !$n['is_read']?'font-weight:500;':'' ?>"><?= htmlspecialchars($n['message']) ?></div>
<div style="font-size:0.72rem; color:var(--text-light); margin-top:3px;"><?= $ago ?></div>
</div>
</div>
<?php endforeach; endif; ?>
</div>
</div>
</div>
<div class="app-container">
<!-- Sidebar -->
<aside class="sidebar" id="sidebar">
<!-- Toggle button on the edge -->
<button class="sidebar-toggle-btn" id="sidebar-toggle-btn" onclick="toggleSidebar()" title="Collapse / Expand">
<i class="fa fa-chevron-left" id="sidebar-toggle-icon"></i>
</button>
<h2 class="sidebar-brand">
<svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="flex-shrink:0;"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline></svg>
<span class="sidebar-label sidebar-brand-text">TaskManager</span>
</h2>
<nav style="display:flex; flex-direction:column; gap:0.25rem;">
<a href="?action=dashboard" class="nav-link <?= $action=='dashboard'?'active':'' ?>" title="Dashboard">
<i class="fa fa-gauge-high nav-icon"></i>
<span class="sidebar-label">Dashboard</span>
</a>
<a href="?action=tasks" class="nav-link <?= $action=='tasks'?'active':'' ?>" title="Tasks">
<i class="fa fa-list-check nav-icon"></i>
<span class="sidebar-label">Tasks</span>
</a>
<a href="?action=notes" class="nav-link <?= $action=='notes'?'active':'' ?>" title="Notes">
<i class="fa fa-note-sticky nav-icon"></i>
<span class="sidebar-label">Notes</span>
</a>
<a href="?action=passwords" class="nav-link <?= $action=='passwords'?'active':'' ?>" title="Passwords">
<i class="fa fa-lock nav-icon"></i>
<span class="sidebar-label">Passwords</span>
</a>
<a href="?action=projects" class="nav-link <?= $action=='projects'?'active':'' ?>" title="Projects">
<i class="fa fa-folder-open nav-icon"></i>
<span class="sidebar-label">Projects</span>
</a>
<?php if(!empty($_SESSION['is_admin'])): ?>
<a href="?action=admin" class="nav-link <?= $action=='admin'?'active':'' ?>">
<span style="display:flex;align-items:center;gap:0.6rem;"><i class="fa fa-shield-halved" style="width:16px;"></i> Admin Panel</span>
<a href="?action=admin" class="nav-link <?= $action=='admin'?'active':'' ?>" title="Admin Panel">
<i class="fa fa-shield-halved nav-icon"></i>
<span class="sidebar-label">Admin Panel</span>
</a>
<?php endif; ?>
</nav>
</aside>
<main class="main-content">
<!-- Top Bar -->
<div style="display:flex; justify-content:flex-end; align-items:center; gap:0.75rem; margin-bottom:1.5rem;">
@@ -128,17 +187,24 @@
<!-- User Avatar Dropdown -->
<div class="user-dropdown-wrap" id="user-dropdown-wrap">
<button class="user-avatar-btn" id="user-avatar-btn" onclick="toggleUserDropdown()" title="<?= htmlspecialchars($current_user['username']) ?>">
<?php
try { $pdo->exec("ALTER TABLE users ADD COLUMN profile_pic TEXT DEFAULT NULL"); } catch(Exception $e) {}
$pic_top = $current_user['profile_pic'] ?? null;
?>
<?php if($pic_top && file_exists($pic_top)): ?>
<img src="<?= htmlspecialchars($pic_top) ?>?v=<?= time() ?>" alt="avatar" style="width:100%; height:100%; object-fit:cover; border-radius:50%;">
<?php else: ?>
<?= strtoupper(mb_substr($current_user['username'],0,1)) ?>
<!-- Avatar with notification badge -->
<div style="position:relative; display:inline-flex;">
<button class="user-avatar-btn" id="user-avatar-btn" onclick="toggleUserDropdown()" title="<?= htmlspecialchars($current_user['username']) ?>">
<?php
try { $pdo->exec("ALTER TABLE users ADD COLUMN profile_pic TEXT DEFAULT NULL"); } catch(Exception $e) {}
$pic_top = $current_user['profile_pic'] ?? null;
?>
<?php if($pic_top && file_exists($pic_top)): ?>
<img src="<?= htmlspecialchars($pic_top) ?>?v=<?= time() ?>" alt="avatar" style="width:100%; height:100%; object-fit:cover; border-radius:50%;">
<?php else: ?>
<?= strtoupper(mb_substr($current_user['username'],0,1)) ?>
<?php endif; ?>
</button>
<?php if($unread_notifications > 0): ?>
<span class="avatar-notif-badge" onclick="openNotifications()"><?= $unread_notifications > 9 ? '9+' : $unread_notifications ?></span>
<?php endif; ?>
</button>
</div>
<div class="user-dropdown-menu" id="user-dropdown-menu">
<div class="user-dropdown-header">
<div class="user-dropdown-name"><?= htmlspecialchars($current_user['username']) ?></div>
@@ -149,6 +215,14 @@
<?php endif; ?>
</div>
<div class="user-dropdown-divider"></div>
<button class="user-dropdown-item" onclick="openNotifications()">
<i class="fa fa-bell"></i>
Notifications
<?php if($unread_notifications > 0): ?>
<span class="badge" style="margin-left:auto; font-size:0.65rem;"><?= $unread_notifications ?></span>
<?php endif; ?>
</button>
<div class="user-dropdown-divider"></div>
<button class="user-dropdown-item" onclick="document.getElementById('profile-pic-modal').classList.add('active'); closeUserDropdown();">
<i class="fa fa-image"></i> Set Profile Picture
</button>
@@ -162,8 +236,6 @@
</div>
</div>
</div>
<?php if (isset($pw_msg) && $pw_msg === 'success'): ?>
<script>document.addEventListener('DOMContentLoaded',()=>{ document.getElementById('change-pw-modal').classList.add('active'); });</script>
<?php elseif(isset($pw_msg) && $pw_msg): ?>
<?php if (isset($pw_msg) && $pw_msg): ?>
<script>document.addEventListener('DOMContentLoaded',()=>{ document.getElementById('change-pw-modal').classList.add('active'); });</script>
<?php endif; ?>