Kinescope renders an iframe that ignores z-index stacking.
Switch to mutually-exclusive render: show poster image OR
the player, never both. Click on poster dismisses it and
reveals the player.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Kinescope React player ignores the poster prop. Replace with a
click-to-dismiss overlay rendered above the player: shows the
lesson coverImage, a play button, and on click hides itself
and calls player.play() via ref.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The @kinescope/react-kinescope-player library accesses browser APIs
(window/document) during server-side rendering. In Next.js App Router,
client components are SSR-rendered on full page loads (direct URL,
refresh) but not on RSC navigations. This caused a 500 error for all
lessons with a kinescopeId when accessed directly.
Fix: defer rendering KinescopeReactPlayer until after mount with
useEffect + useState(false), so it only runs in the browser.
- Add coverImage field to Lesson model (prisma)
- Pass coverImage as poster prop to KinescopePlayer
- Show quiz in read-only preview mode for admin on lesson page
- Fix TipTap v3 editor reset on save: pass [lesson.id] as deps to useEditor
to prevent setOptions() from reinitializing content on every re-render
- Replace saveLesson Server Action call with fetch PATCH /api/admin/lessons/[id]
to avoid Next.js 16 automatic RSC refresh after Server Actions
- Simplify revalidatePath: only revalidate module page, not lesson editor page