MosswartOverlord/frontend/src/hooks/useCurrentUser.ts
Erik 1c1c43d28b feat(dashboard): logout button + admin user-management window
Logout: new sidebar link 'Log out (username)' that POSTs /api/logout
(clears session cookie) and navigates to /login. Visible to everyone.
Replaces 'no logout functionality' state where users could only get
out by deleting cookies manually.

Admin window: new 'Admin · Users' window (only shown when current
user.is_admin) lists all users in a table with:
  - Add user (username + password + admin checkbox)
  - Reset password inline per row
  - Toggle admin per row
  - Delete user per row (blocked for self)
Wraps the existing /api-admin/users CRUD endpoints in main.py.

Plumbing: useCurrentUser hook fetches /me on mount; apiPatch+apiDelete
helpers added to api/client.ts; new endpoint wrappers exported from
api/endpoints.ts; AdminUsersWindow.tsx registered in WindowRenderer
under id prefix 'adminusers'; CSS for admin table/form/buttons and
the muted-red logout link.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-15 20:10:10 +02:00

25 lines
910 B
TypeScript

import { useEffect, useState } from 'react';
import { getCurrentUser, type CurrentUser } from '../api/endpoints';
/**
* Returns the currently-logged-in dashboard user, or null if not logged in /
* not yet loaded. Useful for conditionally showing admin-only UI bits.
*
* Fetches `/me` once on mount. Cheap — the endpoint just decodes the
* session cookie and returns {username, is_admin}.
*/
export function useCurrentUser(): { user: CurrentUser | null; loading: boolean } {
const [user, setUser] = useState<CurrentUser | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let cancelled = false;
getCurrentUser()
.then(u => { if (!cancelled) setUser(u); })
.catch(() => { if (!cancelled) setUser(null); })
.finally(() => { if (!cancelled) setLoading(false); });
return () => { cancelled = true; };
}, []);
return { user, loading };
}