Nicholai 0b8a680dcb Redesign page heroes, add pill buttons, improve HubertChat
Hero sections:
- Redesign blog, dev, and contact page heroes with sleek modern style
- Add gradient text titles, floating accent orbs, stats rows
- Remove heavy terminal-style elements for cleaner aesthetic

Buttons:
- Add rounded-full to all buttons sitewide for consistent pill shape
- Update btn-primary and btn-ghost utilities in global.css

HubertChat:
- Move Hubert to dedicated /hubert page
- Add framer-motion for smooth input transitions
- Support markdown rendering with marked + DOMPurify
- Add multiline textarea with Shift+Enter support
- Fix light mode visibility for input and message bubbles
- Extract useHubertChat hook for cleaner state management

Fonts:
- Update to Sora (sans) and IBM Plex Mono (mono)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-18 03:49:26 -07:00

56 lines
1.4 KiB
TypeScript

// Prevent prerendering - this endpoint requires runtime Cloudflare bindings
export const prerender = false;
/**
* Public guestbook endpoint
*
* Returns all conversations with visitor information
* Sorted by most recent first
* Limited to 50 most recent conversations
*/
export const GET = async ({ env }: { request: Request; env: Env }) => {
try {
const conversations = await env.HUBERT_DB.prepare(`
SELECT
c.id,
c.conversation_id,
c.started_at,
c.ended_at,
c.summary,
COUNT(m.id) as message_count,
v.visitor_id
FROM conversations c
JOIN visitors v ON c.visitor_id = v.visitor_id
LEFT JOIN messages m ON c.conversation_id = m.conversation_id
GROUP BY c.id
ORDER BY c.started_at DESC
LIMIT 50
`).all();
return Response.json({
status: '/// GUESTBOOK_ARCHIVE',
total: conversations.length,
conversations: conversations.map((conv: any) => ({
...conv,
started_at: new Date(conv.started_at).toISOString(),
ended_at: conv.ended_at ? new Date(conv.ended_at).toISOString() : null,
})),
});
} catch (error) {
console.error('[Hubert] Failed to fetch conversations:', error);
return new Response(
JSON.stringify({
status: '/// GUESTBOOK_ERROR',
error: 'Failed to retrieve conversations',
}),
{ status: 500, headers: { 'Content-Type': 'application/json' } }
)
}
};
export interface Env {
HUBERT_DB: D1Database;
OPENROUTER_API_KEY: string;
}