Commit Graph
8 Commits
Author SHA1 Message Date
LeoVasanko f11b772493 Integrate Paskia auth UI flows, hide delete for empty pages. 2026-08-17 22:32:18 +00:00
LeoVasanko 7db08ea821 Fix new-page flow, save/delete semantics, add Cormorant font
- New-page flow: slug placeholder shows the slug derived live from the
  title (placeholders keep browser-default styling; slug values no longer
  muted). Committing PUTs empty markdown, which now creates an empty page
  rendering with its title instead of 404, then hands over to the page
  editor (CodeMirror focuses on mount)
- Saving never deletes: REST PUT and WS save store empty content as an
  empty page; deletion is the page editor's explicit choice — saving
  trimmed-empty text issues a REST DELETE
- Fonts: add Cormorant (variable 300-700, normal+italic) to the serif
  picks, replacing single-weight Gloock; Playfair Display files kept on
  disk but not offered
2026-08-17 02:54:12 +00:00
LeoVasanko 4a84aceb4f Add selectable site theme, custom CSS, and new font set
- Data.theme/Data.custom_css site settings with /_api/settings support;
  theme stylesheet linked per page, custom CSS inline as #pagerite-user,
  swapped during fetch-navigation
- Site editor: theme selector, custom CSS CodeMirror field; in-place
  stylesheet swap (diff-based, preserves editor stylesheets); dev swaps
  Vite-injected style tags since no <link>s exist there
- Dev theme delivery via <meta name="pagerite:theme"> + dynamic import
  in pagerite.js instead of a hardcoded purple import
- Fix dead edit pens in prod: Vite app builds strip entry exports, so
  the dynamic-imported main.js had no openEditor/closeEditor; build with
  preserveEntrySignatures 'exports-only' and log editor load failures
  instead of swallowing them
- Editor slide-in is one-shot: cleared on animationend so stylesheet
  swaps cannot restart a finished animation
- Replace Fraunces/Literata with Source Sans 3/Serif 4, Inter and
  Montserrat variable fonts; font stacks as CSS variables
2026-08-16 23:39:11 +00:00
LeoVasanko 53d98f0583 Restructure internal URL prefixes from /_/... to /_...
- Move API routes from /_/api/ to /_api/
- Move uploaded files from /_/f/ to /_f/
- Move built assets from /_/assets/ to /_assets/
- Move admin shell from /_/admin to /_admin
- Update Vite proxy/build config, frontend fetches/WebSockets, devserver health URL, seed content, and docs
- Fix README database name to pagerite.kantadb
2026-08-16 20:04:16 +00:00
LeoVasanko a8cf5a6a82 Rework category labels, slug validation, and task-list checkboxes
- Remove the section-header  "add landing page" button; landing pages are
  now created via the page editor pen.
- Treat saving a page with empty (after stripping) Markdown as deleting it:
  childless nodes are removed, nodes with children become content-less labels.
- Restrict server-side slugs to [a-z0-9_-] with no leading underscore or dot;
  drop the reserved-filename blacklist.
- Render placeholder pages for content-less category labels and link them to
  their first published child in the navigation.
- Make task-list checkboxes live, non-disabled inputs: toggling updates the
  Markdown source, updates the open CodeMirror document when the page editor is
  open, and persists to the server when no editor is open. Errors revert the UI.
- Update docs and AGENTS.md conventions accordingly.
2026-08-16 19:04:55 +00:00
LeoVasanko 3dc438f8df Fix structure tree drag feedback: stable rows, on-row child drops
Rework the site structure tree's drag-and-drop to match Sortable's native
model instead of mid-drag drop zones:

- Drop the dashed empty-list drop zones that appeared on drag start
  (flicker, space reservation, and mis-targeted drops: the last item's
  child zone sat exactly where 'end of parent list' was).
- Every non-empty list (and the root) ends with a non-draggable  footer
  row (vuedraggable #footer slot): click to start a new page at that
  level, and while dragging it is the 'end of this list' drop target.
  It renders last even mid-drag via flex order, since Sortable appends
  end-of-list previews after it in the DOM.
- Dropping ON the lower part of a row makes the page that row's first
  child: the child list's container invisibly overlaps its own row's
  bottom (negative margin + equal padding, no layout effect) and becomes
  hit-testable only while dragging. A row's exposed top strip remains
  the 'sibling before' target. Leaf rows work too, creating a sublist.
- Indentation is structural (each nested list margin-indents itself), so
  a dragged row previews its whole subtree at the target list's depth.
  Rows get a little vertical padding to widen the drop zones.
2026-08-16 18:05:33 +00:00
LeoVasanko e38063a522 Slug input filtering, title-derived slugs, reserved file names
Slug inputs in the site editor now filter as you type via slugify.js
(built on the transliteration npm package: unicode incl. asian scripts
folds to ASCII, spaces become hyphens, anything outside [a-z0-9-] is
dropped) instead of erroring on commit. A new page left with an empty
slug gets one derived from its title. Server-side, _check_reserved
additionally rejects reserved root file names (robots.txt, ads.txt,
sitemap.xml, openapi.json, favicon.ico, site.webmanifest) with a
human-readable reason, which the editor surfaces in its error line so
the row can be edited and committed again; those URLs are also never
looked up as content when serving.
2026-08-16 16:45:57 +00:00
LeoVasanko 36b250a15c Pagerite: single-user CMS/blog
FastAPI backend rendering HTML with html5tagger, content persisted in a
kanta database and rendered per request. Vue only for the editing tools
(page editor over a WebSocket, site/structure editor); public pages are
plain HTML with fetch navigation. No auth: single trusted author.
2026-08-16 05:49:38 +00:00