feat: redesign nav — home shows public links, user menu with dropdown

- Remove Public Directory tab; public links now show on home page
- Rename Private Links to My Links
- Add right-aligned user menu with hover dropdown (Profile, Settings, Admin, Logout)
- Show admin badge next to username when role=admin
- Show Sign In button when not logged in
- Admin tab only visible to admins
- New GET /api/auth/me endpoint returns current user from session
- useCurrentUser hook for auth state in React
- CSS-only hover dropdown with fade-in animation
- Placeholder pages for Profile and Settings
This commit is contained in:
Hermes Agent
2026-06-20 15:09:19 +10:00
parent fd647bcc2e
commit b357e8aa80
11 changed files with 655 additions and 23 deletions
+5
View File
@@ -1,5 +1,6 @@
import type { Env } from './env';
import { withPrivateNoStoreHeaders } from './lib/responses';
import { handleAuthApi } from './routes/api.auth';
import { handleDevAuth } from './routes/api.dev-auth';
import { handleLinksApi } from './routes/api.links';
import { handlePromotionsApi } from './routes/api.promotions';
@@ -35,6 +36,10 @@ export default {
}
if (url.pathname.startsWith('/api/')) {
const authResponse = await handleAuthApi(request, env);
if (authResponse) {
return withPrivateHostNoStoreHeaders(url, authResponse, env.PRIVATE_HOST);
}
const devAuthResponse = await handleDevAuth(request, env);
if (devAuthResponse) {
return withPrivateHostNoStoreHeaders(url, devAuthResponse, env.PRIVATE_HOST);
+29
View File
@@ -0,0 +1,29 @@
import { getCurrentUser } from '../auth';
import type { Env } from '../env';
export async function handleAuthApi(request: Request, env: Env): Promise<Response | null> {
const url = new URL(request.url);
if (url.pathname !== '/api/auth/me') {
return null;
}
if (request.method !== 'GET') {
return Response.json({ error: 'Method not allowed' }, { status: 405 });
}
const user = await getCurrentUser(request, env);
if (!user) {
return Response.json({ user: null }, { status: 200 });
}
return Response.json({
user: {
id: user.id,
email: user.email,
name: user.name,
imageUrl: user.imageUrl,
role: user.role,
},
});
}