Completes the CMS port to feature parity with public/js/learningHub.js
(@be14578). Previously the React CMS had only a plain-textarea body,
no slide editor for presentations, and no AI content generation —
three large gaps from the vanilla app.
New components:
client/src/components/RichTextEditor.tsx — Tiptap/ProseMirror editor
with the vanilla tp-toolbar feature set: bold/italic/underline/
strike, H2/H3, bullet/ordered/quote/codeblock lists, link-with-
URL-bar, and clear formatting. Three variants (default/mini/
option) match vanilla's buildTpToolbar(mini, isOption).
client/src/pages/cms/SlideEditor.tsx — per-slide Tiptap editor +
slide navigator (move/add/remove). Slides join back to the body
column with the vanilla \n---\n separator so the Learning Hub
viewer renders them unchanged.
client/src/pages/cms/AiGenerator.tsx — generate content via three
sources (topic / upload / Nextcloud WebDAV). POSTs multipart
to /api/admin/learning/ai-generate, matching the vanilla
runAiGenerate flow exactly. WebDAV file browser uses the
existing /api/admin/learning/webdav-browse endpoint. Auto-
hides the Nextcloud tab when the user isn't connected.
Updated:
QuestionsEditor — question text, option text, per-option
explanation, and question explanation are now all Tiptap-backed
so quiz authoring matches content authoring in feel.
ContentEditor — "Generate with AI" button opens the AI panel;
presentation body uses SlideEditor; everything else uses
RichTextEditor with a 320px min height.
Dependencies added:
@tiptap/react @tiptap/pm @tiptap/starter-kit
@tiptap/extension-link @tiptap/extension-underline
47 lines
1.2 KiB
JSON
47 lines
1.2 KiB
JSON
{
|
|
"name": "client",
|
|
"private": true,
|
|
"version": "0.0.0",
|
|
"type": "module",
|
|
"engines": {
|
|
"node": ">=20"
|
|
},
|
|
"scripts": {
|
|
"dev": "vite",
|
|
"build": "tsc -b && vite build",
|
|
"lint": "eslint .",
|
|
"preview": "vite preview"
|
|
},
|
|
"dependencies": {
|
|
"@tailwindcss/vite": "^4.2.4",
|
|
"@tanstack/react-query": "^5.100.1",
|
|
"@tiptap/extension-link": "^3.22.4",
|
|
"@tiptap/extension-underline": "^3.22.4",
|
|
"@tiptap/pm": "^3.22.4",
|
|
"@tiptap/react": "^3.22.4",
|
|
"@tiptap/starter-kit": "^3.22.4",
|
|
"class-variance-authority": "^0.7.1",
|
|
"clsx": "^2.1.1",
|
|
"lucide-react": "^1.9.0",
|
|
"react": "^19.2.5",
|
|
"react-dom": "^19.2.5",
|
|
"react-router-dom": "^7.14.2",
|
|
"tailwind-merge": "^3.5.0",
|
|
"tailwindcss": "^4.2.4",
|
|
"zod": "^4.3.6"
|
|
},
|
|
"devDependencies": {
|
|
"@eslint/js": "^10.0.1",
|
|
"@types/node": "^24.12.2",
|
|
"@types/react": "^19.2.14",
|
|
"@types/react-dom": "^19.2.3",
|
|
"@vitejs/plugin-react": "^6.0.1",
|
|
"eslint": "^10.2.1",
|
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
"eslint-plugin-react-refresh": "^0.5.2",
|
|
"globals": "^17.5.0",
|
|
"typescript": "~6.0.2",
|
|
"typescript-eslint": "^8.58.2",
|
|
"vite": "^8.0.10"
|
|
}
|
|
}
|