Plan: Add Chat Sidebar to Instructors Page
Implement the following plan:
Plan: Add Chat Sidebar to Instructors Page
Context
The /instructors page showcases the course to other educators. Adding a chat lets visiting instructors ask questions about the course — pedagogical approach, technical implementation, assessment design, etc. The chat uses the existing public endpoint (/api/chat/public) with a new agent tailored for educators. No backend changes needed.
Layout: Sticky sidebar on desktop (lg+), slide-up bottom sheet on mobile.
Files
| File | Action | Purpose |
|---|---|---|
content/agents/instructor-assistant.md | Create | Agent with educator-focused system prompt |
apps/web/components/instructor-chat.tsx | Create | Chat client component (sidebar + bottom sheet) |
apps/web/app/instructors/page.tsx | Edit | Two-column layout with chat sidebar |
content/instructors.mdx | No change | MDX content stays as-is |
apps/web/mdx-components.tsx | No change | Chat is in page layout, not MDX |
Task 1: Agent Definition (content/agents/instructor-assistant.md)
New agent following existing pattern (content/agents/course-assistant.md as reference):
name: Instructor Assistant
description: Help for instructors and educators exploring the course
useRag: true
ragLimit: 8
visibility: public
System prompt persona: Geoff's knowledgeable colleague, not a student TA. Focuses on:
- Pedagogical approach and design decisions
- Technical implementation details (two-agent architecture, activity framework, RAG pipeline)
- How to adapt ideas for other courses/contexts
- Links to relevant pages when helpful (design docs, demos, blog posts)
Task 2: Chat Component (apps/web/components/instructor-chat.tsx)
Client component ("use client") with two modes:
Desktop (lg+): Sidebar panel
- Renders as a panel in the right column of the page layout
sticky top-12so it stays in view while scrolling content- Terminal-style UI (
bg-terminal-bg, monospace) matching the site aesthetic - Height:
h-[calc(100vh-6rem)]or similar to fill the viewport - Scrollable message area + fixed input at the bottom
Mobile (<lg): Floating button + bottom sheet
- A floating "Chat" button fixed to the bottom-right corner
- Tapping opens a slide-up panel (bottom sheet) covering ~80% of viewport
- Panel has a handle/close button at top, same chat UI inside
- Backdrop overlay to indicate modal state
Chat functionality (shared between both modes)
- Greeting: "Have questions about the course? Ask away."
- Placeholder: "Ask about assessments, activities, course design..."
- Streams responses via
POST /api/chat/publicwithagentSlug: "instructor-assistant" - Markdown rendering with
ReactMarkdown+remarkGfm - Uses
env.NEXT_PUBLIC_API_URLfrom@/lib/env - No slash commands, no typing animation, no collapse/expand buttons
Task 3: Page Layout (apps/web/app/instructors/page.tsx)
Change from single-column to responsive two-column layout:
// Desktop: two columns — content + sticky chat sidebar
// Mobile: single column content + floating chat button/bottom sheet
<div className="px-4 py-12 sm:px-6" data-testid="instructors-page">
<div className="mx-auto max-w-6xl lg:grid lg:grid-cols-[1fr_380px] lg:gap-8">
<Prose>
<InstructorsContent />
</Prose>
<InstructorChat />
</div>
</div>
The InstructorChat component handles its own responsive behavior internally:
- On
lg+: renders as the sidebar panel (visible in the grid column) - On
<lg: hides the sidebar, shows floating button + bottom sheet instead
Verification
- Visit
https://[local-hostname]/instructorson desktop- Content in left column, sticky chat sidebar on right
- Chat stays in view while scrolling
- Resize to mobile width
- Sidebar disappears, floating chat button appears
- Tapping button opens bottom sheet with chat
- Closing sheet returns to content
- Ask a question like "How do conversational assessments work?"
- Response streams in with markdown formatting
- RAG context used (references specific course details)
- Tone is educator-to-educator, not TA-to-student
- Verify no auth required
If you need specific details from before exiting plan mode (like exact code snippets, error messages, or content you generated), read the full transcript at: ~/.claude/projects/-Users-challen-www-usingandunderstanding-ai/b76890d1-6ed5-4f69-8809-4b444af29c89.jsonl
I'll start by reading the key reference files to understand existing patterns.
Now let me check the env module and look at existing tailwind classes/theme for reference.
Now I have a clear picture. Let me create all three files. I'll start with the tasks and work through them.
Sorry for interrupting! Please continue.
No problem, continuing with the chat component. Let me check the package.json for available dependencies first.
Good, both are available. Now let me create the chat component.
Now update the instructors page to use the two-column layout.
Let me verify the build compiles.
Clean typecheck. Let me also quickly verify the dev server is running and the page loads.
Dev server isn't running, but the TypeScript check passes cleanly. Here's a summary of what was created:
3 files changed:
-
content/agents/instructor-assistant.md(new) — Agent definition with educator-focused system prompt. Uses RAG with 8 document limit, public visibility. Tone is educator-to-educator, focusing on pedagogical design decisions and technical implementation details. -
apps/web/components/instructor-chat.tsx(new) — Client component with two modes:- Desktop (lg+): Sticky sidebar with terminal-style UI matching the site aesthetic (same
bg-terminal-bg, monospace,>and$prompt markers, streaming markdown) - Mobile (<lg): Floating "Chat" button + slide-up bottom sheet covering 80% viewport, with backdrop and Escape-to-close
- Desktop (lg+): Sticky sidebar with terminal-style UI matching the site aesthetic (same
-
apps/web/app/instructors/page.tsx(edited) — Changed from single-column to responsive two-column layout usinglg:grid lg:grid-cols-[1fr_380px] lg:gap-8. Prose usestoc={false}since the TOC sidebar would conflict with the chat column.
Cool! Can we write some tests for this?
Let me look at the terminal-prompt test and a simple page test for reference patterns.
Now let me read the playwright config to see the project definition pattern.
Good. I notice the component needs data-testid attributes. Now let me write the plan.