Files
backerup-website/frontend/app/components/LogoutButton.tsx
T
Anders Böttcher 0d58fafe4e feat: implement user authentication and admin management
- Add user management API endpoints for listing and creating users.
- Implement login and logout functionality with rate limiting.
- Create UI components for login form, logout button, and animated elements.
- Add session management with JWT and secure cookie handling.
- Seed initial admin user if no users exist.
- Introduce utility functions for password hashing and user authentication.
- Set up proxy middleware for route protection and security headers.
- Create a JSON file for user data storage.
- Add links configuration for external resources.
2026-05-12 14:58:11 +02:00

41 lines
1.7 KiB
TypeScript

'use client'
import { useRouter } from 'next/navigation'
import { useState } from 'react'
export default function LogoutButton() {
const router = useRouter()
const [loading, setLoading] = useState(false)
async function handleLogout() {
setLoading(true)
await fetch('/api/auth/logout', { method: 'POST' })
router.push('/login')
router.refresh()
}
return (
<button
onClick={handleLogout}
disabled={loading}
className="px-3 py-2 rounded-lg text-sm font-medium text-slate-400 hover:text-white hover:bg-white/5 transition-all disabled:opacity-50"
title="Sign out"
>
{loading ? (
<svg className="animate-spin w-4 h-4" fill="none" viewBox="0 0 24 24" aria-hidden="true">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" />
</svg>
) : (
<span className="flex items-center gap-1.5">
<svg viewBox="0 0 20 20" fill="currentColor" className="w-4 h-4" aria-hidden="true">
<path fillRule="evenodd" d="M3 4.25A2.25 2.25 0 015.25 2h5.5A2.25 2.25 0 0113 4.25v2a.75.75 0 01-1.5 0v-2a.75.75 0 00-.75-.75h-5.5a.75.75 0 00-.75.75v11.5c0 .414.336.75.75.75h5.5a.75.75 0 00.75-.75v-2a.75.75 0 011.5 0v2A2.25 2.25 0 0110.75 18h-5.5A2.25 2.25 0 013 15.75V4.25z" clipRule="evenodd" />
<path fillRule="evenodd" d="M6 10a.75.75 0 01.75-.75h9.546l-1.048-.943a.75.75 0 111.004-1.114l2.5 2.25a.75.75 0 010 1.114l-2.5 2.25a.75.75 0 11-1.004-1.114l1.048-.943H6.75A.75.75 0 016 10z" clipRule="evenodd" />
</svg>
<span className="hidden sm:inline">Sign out</span>
</span>
)}
</button>
)
}