Skip to content

Commit ddee254

Browse files
committed
feat(frontend/ui): Add user avatar section to sidebar
- Updated `sidebar.ejs` to include a user avatar section with user name and username. - Implemented logic to fetch and display user data including avatar, name, and username. - Added a mini-menu for quick access to account, settings, and logout options. - Included necessary scripts to handle sidebar toggle and user data fetching.
1 parent 4be4a1a commit ddee254

File tree

3 files changed

+148
-75
lines changed

3 files changed

+148
-75
lines changed

frontend/src/views/components/sidebar.ejs

+146-75
Original file line numberDiff line numberDiff line change
@@ -5,83 +5,129 @@
55
</svg>
66
</button>
77

8-
<aside id="sidebar" class="fixed top-0 left-0 z-40 w-64 h-screen transition-transform -translate-x-full sm:translate-x-0" aria-label="Sidebar">
9-
<div class="h-full px-3 py-4 overflow-y-auto bg-dark">
10-
<a href="/" class="flex items-center ps-2.5 mb-5">
11-
<img src="/img/logo-l.png" class="h-20 me-3" alt="GradeAnalyzer Logo" />
12-
</a>
13-
<ul class="space-y-2 font-medium">
14-
<li>
15-
<a href="/dashboard" class="flex items-center p-2 text-white rounded-lg group hover:bg-gray-700">
16-
<svg class="w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
17-
<path d="M13.5 2c-.178 0-.356.013-.492.022l-.074.005a1 1 0 0 0-.934.998V11a1 1 0 0 0 1 1h7.975a1 1 0 0 0 .998-.934l.005-.074A7.04 7.04 0 0 0 22 10.5 8.5 8.5 0 0 0 13.5 2Z" />
18-
<path d="M11 6.025a1 1 0 0 0-1.065-.998 8.5 8.5 0 1 0 9.038 9.039A1 1 0 0 0 17.975 13H11V6.025Z" />
19-
</svg>
20-
<span class="ms-3">Dashboard</span>
21-
</a>
22-
</li>
23-
<li>
24-
<button type="button" class="flex items-center w-full p-2 text-base text-white transition duration-75 rounded-lg group hover:bg-gray-700" aria-controls="sidebar-user-menu" data-collapse-toggle="sidebar-user-menu">
25-
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
26-
<path fill-rule="evenodd" d="M12 4a4 4 0 1 0 0 8 4 4 0 0 0 0-8Zm-2 9a4 4 0 0 0-4 4v1a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-1a4 4 0 0 0-4-4h-4Z" clip-rule="evenodd" />
27-
</svg>
28-
<span class="flex-1 ms-3 text-left rtl:text-right whitespace-nowrap">User</span>
29-
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
30-
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4" />
31-
</svg>
32-
</button>
33-
<ul id="sidebar-user-menu" class="hidden py-2 space-y-2">
34-
<li>
35-
<a href="/user" class="flex items-center w-full p-2 text-white transition duration-75 rounded-lg pl-11 group hover:bg-gray-700">
36-
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
37-
<path fill-rule="evenodd" d="M12 20a7.966 7.966 0 0 1-5.002-1.756l.002.001v-.683c0-1.794 1.492-3.25 3.333-3.25h3.334c1.84 0 3.333 1.456 3.333 3.25v.683A7.966 7.966 0 0 1 12 20ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10c0 5.5-4.44 9.963-9.932 10h-.138C6.438 21.962 2 17.5 2 12Zm10-5c-1.84 0-3.333 1.455-3.333 3.25S10.159 13.5 12 13.5c1.84 0 3.333-1.455 3.333-3.25S13.841 7 12 7Z" clip-rule="evenodd" />
38-
</svg>
39-
<span class="flex-1 ms-3 whitespace-nowrap">Profile</span>
40-
</a>
41-
</li>
42-
<li>
43-
<a href="/user/account" class="flex items-center w-full p-2 text-white transition duration-75 rounded-lg pl-11 group hover:bg-gray-700">
44-
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
45-
<path fill-rule="evenodd" d="M17 10v1.126c.367.095.714.24 1.032.428l.796-.797 1.415 1.415-.797.796c.188.318.333.665.428 1.032H21v2h-1.126c-.095.367-.24.714-.428 1.032l.797.796-1.415 1.415-.796-.797a3.979 3.979 0 0 1-1.032.428V20h-2v-1.126a3.977 3.977 0 0 1-1.032-.428l-.796.797-1.415-1.415.797-.796A3.975 3.975 0 0 1 12.126 16H11v-2h1.126c.095-.367.24-.714.428-1.032l-.797-.796 1.415-1.415.796.797A3.977 3.977 0 0 1 15 11.126V10h2Zm.406 3.578.016.016c.354.358.574.85.578 1.392v.028a2 2 0 0 1-3.409 1.406l-.01-.012a2 2 0 0 1 2.826-2.83ZM5 8a4 4 0 1 1 7.938.703 7.029 7.029 0 0 0-3.235 3.235A4 4 0 0 1 5 8Zm4.29 5H7a4 4 0 0 0-4 4v1a2 2 0 0 0 2 2h6.101A6.979 6.979 0 0 1 9 15c0-.695.101-1.366.29-2Z" clip-rule="evenodd" />
46-
</svg>
47-
<span class="flex-1 ms-3 whitespace-nowrap">Account</span>
48-
</a>
49-
</li>
50-
<li>
51-
<a href="/user/settings" class="flex items-center w-full p-2 text-white transition duration-75 rounded-lg pl-11 group hover:bg-gray-700">
52-
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 48 48">
53-
<path d="M41.5 10H35.5" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
54-
<path d="M27.5 6V14" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
55-
<path d="M27.5 10L5.5 10" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
56-
<path d="M13.5 24H5.5" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
57-
<path d="M21.5 20V28" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
58-
<path d="M43.5 24H21.5" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
59-
<path d="M41.5 38H35.5" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
60-
<path d="M27.5 34V42" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
61-
<path d="M27.5 38H5.5" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
62-
</svg>
63-
<span class="flex-1 ms-3 whitespace-nowrap">Settings</span>
64-
</a>
65-
</li>
66-
<li>
67-
<a href="/user/security" class="flex items-center w-full p-2 text-white transition duration-75 rounded-lg pl-11 group hover:bg-gray-700">
68-
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
69-
<path fill-rule="evenodd" d="M11.644 3.066a1 1 0 0 1 .712 0l7 2.666A1 1 0 0 1 20 6.68a17.694 17.694 0 0 1-2.023 7.98 17.406 17.406 0 0 1-5.402 6.158 1 1 0 0 1-1.15 0 17.405 17.405 0 0 1-5.403-6.157A17.695 17.695 0 0 1 4 6.68a1 1 0 0 1 .644-.949l7-2.666Zm4.014 7.187a1 1 0 0 0-1.316-1.506l-3.296 2.884-.839-.838a1 1 0 0 0-1.414 1.414l1.5 1.5a1 1 0 0 0 1.366.046l4-3.5Z" clip-rule="evenodd" />
70-
</svg>
71-
<span class="flex-1 ms-3 whitespace-nowrap">Security</span>
8+
<aside id="sidebar" class="fixed top-0 left-0 z-40 w-64 h-screen transition-transform -translate-x-full sm:translate-x-0 bg-dark" aria-label="Sidebar">
9+
<div class="h-full flex flex-col justify-between">
10+
<div class="px-3 py-4 overflow-y-auto">
11+
<a href="/" class="flex items-center ps-2.5 mb-5">
12+
<img src="/img/logo-l.png" class="h-20 me-3" alt="GradeAnalyzer Logo" />
13+
</a>
14+
<ul class="space-y-2 font-medium">
15+
<li>
16+
<a href="/dashboard" class="flex items-center p-2 text-white rounded-lg group hover:bg-gray-700">
17+
<svg class="w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
18+
<path d="M13.5 2c-.178 0-.356.013-.492.022l-.074.005a1 1 0 0 0-.934.998V11a1 1 0 0 0 1 1h7.975a1 1 0 0 0 .998-.934l.005-.074A7.04 7.04 0 0 0 22 10.5 8.5 8.5 0 0 0 13.5 2Z" />
19+
<path d="M11 6.025a1 1 0 0 0-1.065-.998 8.5 8.5 0 1 0 9.038 9.039A1 1 0 0 0 17.975 13H11V6.025Z" />
20+
</svg>
21+
<span class="ms-3">Dashboard</span>
22+
</a>
23+
</li>
24+
<li>
25+
<button type="button" class="flex items-center w-full p-2 text-base text-white transition duration-75 rounded-lg group hover:bg-gray-700" aria-controls="sidebar-user-menu" data-collapse-toggle="sidebar-user-menu">
26+
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
27+
<path fill-rule="evenodd" d="M12 4a4 4 0 1 0 0 8 4 4 0 0 0 0-8Zm-2 9a4 4 0 0 0-4 4v1a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2v-1a4 4 0 0 0-4-4h-4Z" clip-rule="evenodd" />
28+
</svg>
29+
<span class="flex-1 ms-3 text-left rtl:text-right whitespace-nowrap">User</span>
30+
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 10 6">
31+
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 4 4 4-4" />
32+
</svg>
33+
</button>
34+
<ul id="sidebar-user-menu" class="hidden py-2 space-y-2">
35+
<li>
36+
<a href="/user" class="flex items-center w-full p-2 text-white transition duration-75 rounded-lg pl-11 group hover:bg-gray-700">
37+
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
38+
<path fill-rule="evenodd" d="M12 20a7.966 7.966 0 0 1-5.002-1.756l.002.001v-.683c0-1.794 1.492-3.25 3.333-3.25h3.334c1.84 0 3.333 1.456 3.333 3.25v.683A7.966 7.966 0 0 1 12 20ZM2 12C2 6.477 6.477 2 12 2s10 4.477 10 10c0 5.5-4.44 9.963-9.932 10h-.138C6.438 21.962 2 17.5 2 12Zm10-5c-1.84 0-3.333 1.455-3.333 3.25S10.159 13.5 12 13.5c1.84 0 3.333-1.455 3.333-3.25S13.841 7 12 7Z" clip-rule="evenodd" />
39+
</svg>
40+
<span class="flex-1 ms-3 whitespace-nowrap">Profile</span>
41+
</a>
42+
</li>
43+
<li>
44+
<a href="/user/account" class="flex items-center w-full p-2 text-white transition duration-75 rounded-lg pl-11 group hover:bg-gray-700">
45+
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
46+
<path fill-rule="evenodd" d="M17 10v1.126c.367.095.714.24 1.032.428l.796-.797 1.415 1.415-.797.796c.188.318.333.665.428 1.032H21v2h-1.126c-.095.367-.24.714-.428 1.032l.797.796-1.415 1.415-.796-.797a3.979 3.979 0 0 1-1.032.428V20h-2v-1.126a3.977 3.977 0 0 1-1.032-.428l-.796.797-1.415-1.415.797-.796A3.975 3.975 0 0 1 12.126 16H11v-2h1.126c.095-.367.24-.714.428-1.032l-.797-.796 1.415-1.415.796.797A3.977 3.977 0 0 1 15 11.126V10h2Zm.406 3.578.016.016c.354.358.574.85.578 1.392v.028a2 2 0 0 1-3.409 1.406l-.01-.012a2 2 0 0 1 2.826-2.83ZM5 8a4 4 0 1 1 7.938.703 7.029 7.029 0 0 0-3.235 3.235A4 4 0 0 1 5 8Zm4.29 5H7a4 4 0 0 0-4 4v1a2 2 0 0 0 2 2h6.101A6.979 6.979 0 0 1 9 15c0-.695.101-1.366.29-2Z" clip-rule="evenodd" />
47+
</svg>
48+
<span class="flex-1 ms-3 whitespace-nowrap">Account</span>
49+
</a>
50+
</li>
51+
<li>
52+
<a href="/user/settings" class="flex items-center w-full p-2 text-white transition duration-75 rounded-lg pl-11 group hover:bg-gray-700">
53+
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 48 48">
54+
<path d="M41.5 10H35.5" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
55+
<path d="M27.5 6V14" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
56+
<path d="M27.5 10L5.5 10" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
57+
<path d="M13.5 24H5.5" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
58+
<path d="M21.5 20V28" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
59+
<path d="M43.5 24H21.5" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
60+
<path d="M41.5 38H35.5" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
61+
<path d="M27.5 34V42" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
62+
<path d="M27.5 38H5.5" stroke="currentColor" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" />
63+
</svg>
64+
<span class="flex-1 ms-3 whitespace-nowrap">Settings</span>
65+
</a>
66+
</li>
67+
<li>
68+
<a href="/user/security" class="flex items-center w-full p-2 text-white transition duration-75 rounded-lg pl-11 group hover:bg-gray-700">
69+
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 24 24">
70+
<path fill-rule="evenodd" d="M11.644 3.066a1 1 0 0 1 .712 0l7 2.666A1 1 0 0 1 20 6.68a17.694 17.694 0 0 1-2.023 7.98 17.406 17.406 0 0 1-5.402 6.158 1 1 0 0 1-1.15 0 17.405 17.405 0 0 1-5.403-6.157A17.695 17.695 0 0 1 4 6.68a1 1 0 0 1 .644-.949l7-2.666Zm4.014 7.187a1 1 0 0 0-1.316-1.506l-3.296 2.884-.839-.838a1 1 0 0 0-1.414 1.414l1.5 1.5a1 1 0 0 0 1.366.046l4-3.5Z" clip-rule="evenodd" />
71+
</svg>
72+
<span class="flex-1 ms-3 whitespace-nowrap">Security</span>
73+
</a>
74+
</li>
75+
<li>
76+
<a href="/user/logout" class="flex items-center w-full p-2 text-white transition duration-75 rounded-lg pl-11 group hover:bg-gray-700">
77+
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
78+
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 12H4m12 0-4 4m4-4-4-4m3-4h2a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3h-2" />
79+
</svg>
80+
<span class="flex-1 ms-3 whitespace-nowrap">Logout</span>
81+
</a>
82+
</li>
83+
</ul>
84+
</li>
85+
</ul>
86+
</div>
87+
88+
<div id="sidebar-user" class="hidden border-t border-gray-700 px-4 py-3">
89+
<div class="flex items-center space-between">
90+
<div class="flex items-center space-x-3">
91+
<a href="/user">
92+
<img id="sidebar-user-avatar" class="w-10 h-10 rounded-full" src="/img/default-avatar.png" alt="User Avatar" />
93+
</a>
94+
<div class="text-sm text-white">
95+
<a href="/user">
96+
<div id="sidebar-user-name" class="font-medium"></div>
7297
</a>
73-
</li>
74-
<li>
75-
<a href="/user/logout" class="flex items-center w-full p-2 text-white transition duration-75 rounded-lg pl-11 group hover:bg-gray-700">
76-
<svg class="flex-shrink-0 w-6 h-6 text-gray-400 transition duration-75 group-hover:text-white" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
77-
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 12H4m12 0-4 4m4-4-4-4m3-4h2a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3h-2" />
78-
</svg>
79-
<span class="flex-1 ms-3 whitespace-nowrap">Logout</span>
98+
<a href="/user">
99+
<div class="text-gray-400">@<span id="sidebar-user-username"></span></div>
80100
</a>
81-
</li>
82-
</ul>
83-
</li>
84-
</ul>
101+
</div>
102+
</div>
103+
<button onclick="document.getElementById('sidebar-user-mini-menu').classList.toggle('hidden')" class="ml-auto inline-flex items-center text-gray-400 hover:text-white" type="button">
104+
<svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
105+
<circle cx="12" cy="24" r="3" fill="currentColor" />
106+
<circle cx="24" cy="24" r="3" fill="currentColor" />
107+
<circle cx="36" cy="24" r="3" fill="currentColor" />
108+
</svg>
109+
</button>
110+
<div id="sidebar-user-mini-menu" class="hidden absolute bottom-16 right-0 z-50 bg-dark border border-gray-700 rounded-lg shadow-lg">
111+
<ul class="py-2 text-sm text-gray-400">
112+
<li>
113+
<a href="/user/account" class="block px-4 py-2 hover:bg-gray-700 hover:text-white">
114+
Account
115+
</a>
116+
</li>
117+
<li>
118+
<a href="/user/settings" class="block px-4 py-2 hover:bg-gray-700 hover:text-white">
119+
Settings
120+
</a>
121+
</li>
122+
<li>
123+
<a href="/user/logout" class="block px-4 py-2 hover:bg-gray-700 hover:text-white">
124+
Logout
125+
</a>
126+
</li>
127+
</ul>
128+
</div>
129+
</div>
130+
</div>
85131
</div>
86132
</aside>
87133

@@ -138,5 +184,30 @@
138184
}
139185
}
140186
});
187+
188+
if (app.auth.authenticated) {
189+
let userData = app.cache.user;
190+
191+
(async () => {
192+
const cacheHit = userData;
193+
194+
let response;
195+
196+
if (!userData) {
197+
const user = new User(app);
198+
response = await user.getUser();
199+
userData = response.data;
200+
app.cache.user = userData;
201+
}
202+
203+
if (cacheHit || response.status === "success") {
204+
document.getElementById("sidebar-user-name").textContent = userData.profile.name || userData.username;
205+
document.getElementById("sidebar-user-username").textContent = userData.username;
206+
document.getElementById("sidebar-user-avatar").src = userData.profile.avatar || "/img/default-avatar.png";
207+
208+
document.getElementById("sidebar-user").classList.remove("hidden");
209+
}
210+
})();
211+
}
141212
});
142213
</script>

frontend/src/views/pages/dashboard.ejs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
<head>
55
<%- include("../components/head.ejs") %>
6+
<script src="/js/user.js"></script>
67
<title>GradeAnalyzer | Dashboard</title>
78
</head>
89

frontend/src/views/pages/user/logout.ejs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
<head>
55
<%- include("../../components/head.ejs") %>
6+
<script src="/js/user.js"></script>
67
<title>GradeAnalyzer | Logout</title>
78
</head>
89

0 commit comments

Comments
 (0)