divan/web/src/pages/api/library.ts
Anas Rashid 1485781fb7 Notes on couplets and selected text, and the site's own dialog, toasts and busy buttons
- Notes: a glyph below each couplet's bookmark opens a note box (filled gold when the couplet or a phrase in it has a note; the note shows on hover). Selected text gets نوٹ in the selection menu; a highlighted phrase with a note shows the note glyph and opens its note (with "remove highlight"). API: POST /api/library/note {poemId, couplet, phrase?, note} (bookmarks if needed; empty clears the note), notes in /api/library/state; tests added
- Confirm dialog in Urdu (destructive answer in red, named for what it does) in place of the browser's English confirm(); forms use data-confirm
- Toasts for "done" messages; errors stay by the form and nudge; a submitting button shows a spinner
- Motion: page cross-fade (View Transitions) with the logo held; couplets rise in on load; bookmark and note glyphs pop; the word sidebar slides in; menus and folding sections open smoothly; all off with reduced motion

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 17:14:59 +02:00

24 lines
1.3 KiB
TypeScript

// Browser -> API for the bookmark buttons and the word book: the reader's session cookie becomes the Bearer token.
// JSON posts from other sites are refused: the Origin must be this site (and SameSite cookies are not sent).
import type { APIRoute } from 'astro';
import { asUser, COOKIE } from '../../lib/auth';
const json = (data: unknown, status = 200) => new Response(JSON.stringify(data), { status, headers: { 'content-type': 'application/json' } });
export const POST: APIRoute = async ({ request, cookies, url }) => {
const origin = request.headers.get('origin');
if (origin && new URL(origin).host !== url.host) return json({ error: 'forbidden' }, 403);
const token = cookies.get(COOKIE)?.value;
if (!token) return json({ error: 'لاگ ان کریں' }, 401);
const body = await request.json().catch(() => ({}));
const r = await asUser(token, 'note' in body ? '/api/library/note' : '/api/library/toggle', body); // {note, poemId, couplet, phrase?}: a note
return json(r.data, r.status);
};
export const GET: APIRoute = async ({ cookies, url }) => {
const token = cookies.get(COOKIE)?.value;
if (!token) return json({ error: 'لاگ ان کریں' }, 401);
const r = await asUser(token, `/api/library/state?word=${encodeURIComponent(url.searchParams.get('word') ?? '')}`);
return json(r.data, r.status);
};