Commit Graph

20 Commits

Author SHA1 Message Date
446e9f835b fix: use writable \$derived for search inputs, remove unnecessary \$state wrap
- Replace \$state + \$effect pattern with writable \$derived (Svelte 5.25+)
  for all searchValue instances across list pages — cleaner and lint-compliant
- Remove now-unused untrack imports from those files
- Drop \$state() wrapper around SvelteMap in device-mapping-dialog
  (SvelteMap is already reactive)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 11:46:15 +01:00
422f97417e fix: resolve vite-plugin-svelte warnings
- image-viewer: replace backdrop div with button for a11y
- file-drop-zone: wrap prop check in \$effect to avoid state_referenced_locally
- about: use \$derived for stats array
- magazine: use \$derived for featuredArticle
- play: add role/keyboard support to seek bar slider; fix \$state on SvelteMap in device-mapping-dialog
- admin/videos/[id]: add <track kind="captions"> to video element

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 11:41:58 +01:00
edee98b552 fix: use untrack() in \$state initialisers to silence state_referenced_locally warnings
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 11:31:51 +01:00
b9b98f178f fix: sync reactive state with data prop using \$effect
Replaces bare \$state(data.x) initialisers (which only capture the
initial value) with \$state + \$effect pairs so that state stays in sync
whenever page data is invalidated or the URL changes. Affects all list
pages (searchValue) and all edit/detail pages (form fields).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-08 11:06:30 +01:00
e236ced12a refactor: replace all explicit any types with proper TypeScript types
Backend resolvers: typed enrichArticle/enrichVideo/enrichModel with DB
and $inferSelect types, SQL<unknown>[] for conditions arrays, proper
enum casts for status/role fields, $inferInsert for .set() updates,
typed raw SQL result rows in gamification, ReplyLike interface for
ctx.reply in auth. Frontend: typed catch blocks with Error/interface
casts, isActiveLink param, adminGetUser response, tags filter callback.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 19:25:04 +01:00
8313664d70 chore: fix all lint errors and format codebase
- Remove unused `or` import in comments resolver
- Remove unused `users` import in recordings resolver
- Add index keys to pagination {#each} loops in videos, models, magazine
- Remove stale svelte-ignore comment in header (a11y warnings no longer fired)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 19:06:57 +01:00
ae0929ad06 fix: replace arrow symbol with icon css in author profile link
All checks were successful
Build and Push Backend Image / build (push) Successful in 43s
Build and Push Frontend Image / build (push) Successful in 4m12s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 19:03:41 +01:00
d2cbb1004f fix: show author description on magazine article page
Add description field to ARTICLE_BY_SLUG_QUERY and render it in the
author bio card below the name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 18:58:42 +01:00
291f72381f feat: improve UX across all listing pages and homepage
- Make model/video cards fully clickable on homepage, models, videos, magazine, and tags pages
- Replace inline blob divs with SexyBackground component on magazine and play pages
- Replace magazine hero section with PageHero component for consistency
- Remove redundant action buttons from cards (cards are now the link targets)
- Fix nested anchor/button invalid HTML in magazine featured article
- Convert inner overlay anchors to aria-hidden divs to avoid nested <a> elements
- Add bg-muted skeleton placeholder to all card images
- Update magazine pagination to smart numbered style with ellipsis (matching videos/models)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 18:41:39 +01:00
9c5dba5c90 feat: add server-side pagination, search, and filtering to all collection and admin pages
- Public pages (videos, magazine, models): URL-driven search, sort, category/duration
  filters, and Prev/Next pagination (page size 24)
- Admin tables (videos, articles): search input, toggle filters, and pagination (page size 50)
- Tags page: tag filtering now done server-side via DB arrayContains query instead of
  fetching all items and filtering client-side
- Backend resolvers updated for videos, articles, models with paginated { items, total }
  responses and filter/sort/tag args

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 10:43:26 +01:00
c90c09da9a chore: cleanup
All checks were successful
Build and Push Backend Image / build (push) Successful in 49s
Build and Push Frontend Image / build (push) Successful in 4m18s
2026-03-06 19:25:07 +01:00
95fd9f48fc refactor: align article author with VideoModel, streamline selects, fix flyout inert
- Remove ArticleAuthor type; article.author now reuses VideoModel (id, artist_name, slug, avatar)
- updateArticle accepts authorId; author selectable in admin article edit page
- Article edit: single Select with bind:value + $derived selectedAuthor display
- Video edit: replace pill toggles with Select type="multiple" bind:value for models
- Video table: replace inline badge spans with Badge component
- Magazine: display artist_name throughout, author bio links to model profile
- Fix flyout aria-hidden warning: replace with inert attribute

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 16:31:41 +01:00
ad7ceee5f8 fix: resolve lint errors from ACL/admin implementation
- Remove unused requireOwnerOrAdmin import from videos.ts
- Remove unused requireAuth import from users.ts
- Remove unused GraphQLError import from articles.ts
- Replace URLSearchParams with SvelteURLSearchParams in admin users page
- Apply prettier formatting to all changed files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 12:35:11 +01:00
c1770ab9c9 feat: role-based ACL + admin management UI
Backend:
- Add acl.ts with requireAuth/requireRole/requireOwnerOrAdmin helpers
- Gate premium videos from unauthenticated users in videos query/resolver
- Fix updateVideoPlay to verify ownership before updating
- Add admin mutations: adminListUsers, adminUpdateUser, adminDeleteUser
- Add admin mutations: createVideo, updateVideo, deleteVideo, setVideoModels, adminListVideos
- Add admin mutations: createArticle, updateArticle, deleteArticle, adminListArticles
- Add deleteComment mutation (owner or admin only)
- Add AdminUserListType to GraphQL types
- Fix featured filter on articles query

Frontend:
- Install marked for markdown rendering
- Add /admin/* section with sidebar layout and admin-only guard
- Admin users page: paginated table with search, role filter, inline role change, delete
- Admin videos pages: list, create form, edit form with file upload and model assignment
- Admin articles pages: list, create form, edit form with split-pane markdown editor
- Add admin nav link in header (desktop + mobile) for admin users
- Render article content through marked in magazine detail page
- Add all admin GraphQL service functions to services.ts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-06 12:31:33 +01:00
97269788ee feat: add shared @sexy.pivoine.art/types package and fix type safety across frontend/backend
- Create packages/types with shared TypeScript domain model interfaces (User, Video, Model, Article, Comment, Recording, etc.)
- Wire both frontend and backend packages to use @sexy.pivoine.art/types via workspace:*
- Update backend Pothos objectRef types to use shared interfaces instead of inline types
- Update frontend $lib/types.ts to re-export from shared package
- Fix all type errors introduced by more accurate nullable types (avatar/banner as string|null UUIDs, author nullable, events/device_info as object[])
- Add artist_name to comment user select in backend resolver
- Widen utility function signatures (getAssetUrl, getUserInitials, calcReadingTime) to accept null/undefined

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 11:01:11 +01:00
fd4050a49f refactor: remove directus.ts shim, import directly from api
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 10:19:05 +01:00
efc7624ba3 style: apply prettier formatting to all files
All checks were successful
Build and Push Backend Image / build (push) Successful in 46s
Build and Push Frontend Image / build (push) Successful in 5m12s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 22:27:54 +01:00
18116072c9 feat: add formidable ESLint + Prettier linting setup
Some checks failed
Build and Push Backend Image / build (push) Successful in 47s
Build and Push Frontend Image / build (push) Has been cancelled
- Root-level eslint.config.js (flat config): typescript-eslint,
  eslint-plugin-svelte, eslint-config-prettier, @eslint/js
- Root-level prettier.config.js with prettier-plugin-svelte
- svelte-check added to frontend for Svelte/TS type checking
- lint, lint:fix, format, format:check, check scripts in root
  and both packages
- All 60 lint errors fixed across backend and frontend:
  - Consistent type imports
  - Removed unused imports/variables
  - Added keys to all {#each} blocks for Svelte performance
  - Replaced mutable Set/Map with SvelteSet/SvelteMap
  - Fixed useless assignments and empty catch blocks
- 64 remaining warnings are intentional any usages in the
  Pothos/Drizzle GraphQL resolver layer

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 22:24:55 +01:00
c85fa7798e chore: remove Letterspace newsletter integration and all LETTERSPACE_* variables 2026-02-21 10:56:43 +01:00
Valknar XXX
be0fc11a5c A new start 2025-10-25 22:04:41 +02:00