✨ feat: update Header.astro page

swadhinbiswas committed 3 months ago
8363805
1 parent 00dd7f1
commit 8363805
1 file changed
+26 -12
Showing 1 changed file+26-12
▼src/components/layout/Header.astro
+26-12
2
2
import { Search, Bell, Plus, Menu } from "lucide-react"
3
3
import { GlobalSearch } from "@/components/search/GlobalSearch"
4
4
import { ThemeToggle } from "@/components/ThemeToggle"
5
+import { getCsrfToken } from "@/middleware/csrf"
5
6
6
7
const user = Astro.locals.user;
7
8
const currentPath = Astro.url.pathname;
9
+const { token: csrfToken } = getCsrfToken(Astro.request);
8
10
---
9
11
10
12
<header class="sticky top-0 z-50 w-full border-b border-border/40 bg-background/80 backdrop-blur-xl" role="banner">
131
133
Settings
132
134
</a>
133
135
<div class="h-px bg-border/50 my-1"></div>
134
- <form action="/api/auth/logout" method="POST">
135
- <button type="submit" class="w-full flex items-center gap-2 rounded-md px-3 py-1.5 text-sm hover:bg-accent text-left transition-colors">
136
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
137
- Sign out
138
- </button>
139
- </form>
136
+ <button type="button" class="logout-btn w-full flex items-center gap-2 rounded-md px-3 py-1.5 text-sm hover:bg-accent text-left transition-colors">
137
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
138
+ Sign out
139
+ </button>
140
140
</div>
141
141
</div>
142
142
</>
213
213
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg>
214
214
Settings
215
215
</a>
216
- <form action="/api/auth/logout" method="POST" class="mt-1">
217
- <button type="submit" class="w-full flex items-center gap-3 px-3 py-2 text-sm font-medium hover:bg-accent rounded-md transition-colors text-left">
218
- <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
219
- Sign out
220
- </button>
221
- </form>
216
+ <button type="button" class="logout-btn mt-1 w-full flex items-center gap-3 px-3 py-2 text-sm font-medium hover:bg-accent rounded-md transition-colors text-left">
217
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
218
+ Sign out
219
+ </button>
222
220
</div>
223
221
) : (
224
222
<div class="flex gap-2 px-3 py-2">
370
368
if (mobileSearchTrigger) {
371
369
mobileSearchTrigger.addEventListener('click', openSearch);
372
370
}
371
+
372
+ // Logout handler — uses fetch with CSRF header (injected by global interceptor in BaseLayout)
373
+ document.querySelectorAll('.logout-btn').forEach(btn => {
374
+ btn.addEventListener('click', async () => {
375
+ try {
376
+ const res = await fetch('/api/auth/logout', { method: 'POST' });
377
+ if (res.redirected || res.ok) {
378
+ window.location.href = res.url || '/login';
379
+ } else {
380
+ window.location.href = '/login';
381
+ }
382
+ } catch {
383
+ window.location.href = '/login';
384
+ }
385
+ });
386
+ });
373
387
</script>
374
388