Create and manage physician course preview lectures using the JSON-based lecture system. Use when adding new lectures for physician feedback, registering courses, or updating existing preview content.
This skill creates JSON-based lectures for the physician course preview system. Lectures are rendered using the UniversalLecture component and are accessible via unlisted URLs for physician feedback before publication.
content/
└── physician-courses/
├── registry.ts # Central registry (import lectures here)
└── [physician-slug]/
└── [course-slug]/
└── lecture-N.json # Individual lecture files
src/views/preview/
├── CourseCatalog.tsx # /preview/courses
├── PhysicianCourseIndex.tsx # /preview/courses/:physician
└── PhysicianLectureViewer.tsx # /preview/courses/:physician/:lectureSlug
/preview/courses/preview/courses/{physician-id}/preview/courses/{physician-id}/{course-id}-{lecture-number}Example: /preview/courses/dr-abid-husain/new-biology-vascular-1
Location: content/physician-courses/{physician-slug}/{course-slug}/lecture-N.json
Use the JSON schema from content/lectures/schema.ts. Required fields:
{
"id": "course-slug-N",
"title": "Lecture Title",
"module": "Course Name",
"duration": 45,
"lastUpdated": "YYYY-MM-DD",
"description": "Brief description",
"level": "Foundational|Intermediate|Advanced",
"tags": ["Tag1", "Tag2"],
"slides": [...],
"keyTakeaways": [...],
"references": [...]
}
Add the import and register the lecture:
// Import at top of file
import drNewPhysicianLecture1 from './dr-new-physician/course-slug/lecture-1.json';
// Add to physicianRegistry
export const physicianRegistry: Record<string, PhysicianRegistry> = {
'dr-new-physician': {
physician: {
id: 'dr-new-physician',
name: 'Dr. New Physician',
credentials: 'MD',
specialty: 'Specialty Area',
},
courses: [
{
id: 'course-slug',
title: 'Course Title',
description: 'Course description',
status: 'preview',
lectures: [
{
id: 'lecture-1',
title: 'Lecture Title',
order: 1,
lecture: drNewPhysicianLecture1 as Lecture,
},
],
},
],
},
};
Each slide supports:
paragraph - Text paragraphbullets - Bullet listnumbered - Numbered listdefinition - Term and definitionquote - Quote with attributioncaseStudy - Clinical case (scenario, approach, outcome)formula - Mathematical formulacomparisonText - Side-by-side comparison itemshighlight - Highlighted text boxtable - Data table with headers and rowsclinicalNote - Clinical guidancekeyTakeaway - Key point summaryevidence - Research evidence (study + finding)warning - Important warningsproTip - Practical tipsCommon types: pathway, comparison, process, network, hierarchy, timeline, matrix, beforeAfter
IMPORTANT - Network Diagrams: Use edges (not links):
IMPORTANT - Hierarchy Diagrams: Nodes only have label, color, children - NO id field:
{
"type": "hierarchy",
"title": "Diagram Title",
"root": {
"label": "Root Node",
"color": "gold",
"children": [
{ "label": "Child 1", "color": "blue" },
{ "label": "Child 2", "color": "green" }
]
}
}
Network Diagram Example:
{
"type": "network",
"nodes": [...],
"edges": [
{ "from": "node1", "to": "node2", "type": "unidirectional" }
]
}
IMPORTANT - QuadrantDiagram:
IMPORTANT - NetworkDiagram Labels:
When using wouter's <Link> component, DO NOT nest <a> tags inside:
// WRONG - causes hydration errors
<Link href="/path">
<a className="...">Content</a>
</Link>
// CORRECT - pass props directly to Link
<Link
href="/path"
className="..."
style={{...}}
>
Content
</Link>
Always provide unique, stable keys when rendering lists. Keys must be unique among siblings.
// WRONG - missing key or using undefined property
{items.map((item) => (
<div key={item.id}>{item.label}</div> // If 'id' doesn't exist in schema!
))}
// CORRECT - use existing properties with index for uniqueness
{items.map((item, index) => (
<div key={`${item.label}-${index}`}>{item.label}</div>
))}
// CORRECT - for hierarchical/nested data, include level for uniqueness
{node.children.map((child, index) => (
<div key={`${child.label}-${level}-${index}`}>
{renderNode(child, level + 1, index)}
</div>
))}
Key Points:
id fields - check content/lectures/schema.tslabel, color, children - NO id fieldFor clickable cards/buttons:
<Link
href={`/preview/courses/${physicianId}/${lectureSlug}`}
className="block p-6 rounded-lg transition-all hover:shadow-md"
style={{ backgroundColor: colors.paperAlt }}
>
<div>Card content here</div>
</Link>
content/physician-courses/registry.ts/preview/courses/{physician}/{course-id}-{number}publishedSee content/physician-courses/dr-abid-husain/new-biology-vascular/lecture-1.json for a complete example.
Full TypeScript types are in content/lectures/schema.ts:
Lecture - Top-level lecture structureSlide - Individual slide with content, diagram, calloutsContentBlock - 10 content block typesCallout - 5 callout typesDiagram - 20 diagram types