Claude Code Plugins

Community-maintained marketplace

Feedback

Implement Video Question

@asmith7013/coachingPlatform
0
0

Create D3 questions where students watch a video and provide written responses. The video is the primary instructional content.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name Implement Video Question
description Create D3 questions where students watch a video and provide written responses. The video is the primary instructional content.

Implement Video Question

Use this skill when creating questions where students:

  • Watch a video as the primary instructional content
  • Provide written reflections based on the video
  • Answer questions about what they observed in the video

When to Use This Pattern

Perfect for:

  • "Watch this video and explain the main concept"
  • Video-based instruction followed by reflection questions
  • Visual demonstrations requiring written analysis
  • Questions where the video IS the lesson content

Not suitable for:

  • Text-only reflections without video → use implement-text-response-question
  • Video as optional help/hint → use createVideoAccordion() from shared snippets
  • Interactive controls + optional video help → use other question types with video accordion

Distinction from Text Response Questions

Feature Video Question Text Response Question
Primary content Video is the lesson Static text/images or no media
Video role Required, main instruction Optional or absent
Interaction Watch → Respond Read/Analyze → Respond
Snippet video-response.js No snippet (uses cards directly)

Components Required

Copy these from .claude/skills/question-types/:

Required

  • implement-video-question/snippets/video-response.jscreateVideoResponseQuestion()
  • snippets/cards/standard-card.jscreateStandardCard()
  • snippets/cards/video-player.jscreateVideoPlayer()
  • snippets/cards/explanation-card.jscreateExplanationCard()

Quick Start

  1. Review the pattern guide: PATTERN.md
  2. Study the snippet: snippets/video-response.js
  3. Copy from a working example:
    cat courses/IM-8th-Grade/modules/Unit-3/assignments/161-Proportion-Graphs/questions/01/attachments/chart.js
    

Working Examples

Reference these codebase files:

courses/IM-8th-Grade/modules/Unit-3/assignments/161-Proportion-Graphs/questions/01/attachments/chart.js
courses/IM-8th-Grade/modules/Unit-3/assignments/510-Proportion-Equations/questions/01/attachments/chart.js
courses/IM-8th-Grade/modules/Unit-3/assignments/Ramp-Up-2/questions/01/attachments/chart.js

These examples include:

  • ✅ Video player with embedded video
  • ✅ Explanation card for written response
  • ✅ State management for response field
  • ✅ Full message protocol
  • ✅ Interactivity locking

State Shape

function createDefaultState() {
  return {
    explanation: ""
  };
}

For multiple questions:

function createDefaultState() {
  return {
    response1: "",
    response2: "",
    response3: ""
  };
}

Implementation Pattern (Single Response)

function buildLayout(d3, containerSelector) {
  const container = d3.select(containerSelector);
  container.html("").style("padding", "20px").style("overflow", "auto");

  createVideoResponseQuestion(d3, container, {
    videoUrl: "https://example.com/video.mp4",
    videoDescription: "Watch this explanation of proportional relationships",
    promptText: "What is the main concept explained in the video?",
    placeholderText: "Describe the main concept in your own words...",
    responseRows: 6,
    stateKey: "explanation",
    locked: interactivityLocked,
    introTitle: "Video Reflection",
    introContent: "Watch the video carefully and answer the question below."
  });
}

Implementation Pattern (Multiple Responses)

function buildLayout(d3, containerSelector) {
  const container = d3.select(containerSelector);
  container.html("").style("padding", "20px").style("overflow", "auto");

  // Intro
  const introCard = createStandardCard(d3, container, {
    size: "large",
    title: "Video Reflection"
  });
  introCard.append("p").text("Watch the video and answer the questions below.");

  // Video
  createVideoPlayer(d3, container, "https://example.com/video.mp4", {
    description: "Proportional relationships explained"
  });

  // Multiple response cards
  const questions = [
    { prompt: "1. What is the main concept?", key: "response1" },
    { prompt: "2. How does this relate to what you know?", key: "response2" },
    { prompt: "3. Give an example from real life.", key: "response3" }
  ];

  questions.forEach(q => {
    createExplanationCard(d3, container, {
      prompt: q.prompt,
      value: chartState[q.key] || "",
      onChange: (value) => {
        chartState[q.key] = value;
        sendChartState();
      },
      locked: interactivityLocked,
      rows: 4
    });
  });
}

Configuration Options

Video Player Options

{
  videoUrl: "https://example.com/video.mp4",  // Required
  videoDescription: "Watch this...",           // Shown above player
  autoplay: false,                             // Default: false
  controls: true                               // Default: true
}

Response Card Options

{
  promptText: "Question text",           // Required
  placeholderText: "Type here...",       // Optional
  responseRows: 6,                       // Textarea height (default: 6)
  stateKey: "explanation",               // Required - key in chartState
  locked: interactivityLocked            // Required - current lock state
}

Optional Intro Card

{
  introTitle: "Video Reflection",        // Optional
  introContent: "Instructions..."        // Optional
}

Video Hosting Best Practices

  1. Supported formats: MP4 (recommended), WebM
  2. Hosting: Use CDN or cloud storage for best performance
  3. File size: Keep videos under 50MB when possible
  4. Encoding: H.264 codec for MP4, VP9 for WebM
  5. Accessibility: Ensure videos have captions when possible

Common Variations

Character Count Display

const textarea = container.append("textarea");
const counter = container.append("div")
  .style("text-align", "right")
  .style("color", "#6b7280")
  .style("font-size", "14px");

textarea.on("input", function() {
  const length = this.value.length;
  counter.text(`${length} characters`);
  chartState.explanation = this.value;
  sendChartState();
});

Numbered Questions in Separate Cards

const QUESTIONS = [
  { prompt: "What is the main concept?", placeholder: "Main concept..." },
  { prompt: "How does this relate to ratios?", placeholder: "Connection..." }
];

QUESTIONS.forEach((q, index) => {
  const qCard = createStandardCard(d3, container, {
    size: "medium",
    title: `Question ${index + 1}`
  });

  qCard.append("p").text(q.prompt);

  qCard.append("textarea")
    .attr("rows", 4)
    .style("width", "100%")
    .attr("placeholder", q.placeholder)
    .property("value", chartState[`q${index + 1}`])
    .on("input", function() {
      chartState[`q${index + 1}`] = this.value;
      sendChartState();
    });
});

Implementation Checklist

  • Copied video-response.js snippet into chart.js
  • Copied required card components (standard-card, video-player, explanation-card)
  • Created createDefaultState() with response field(s)
  • Configured video URL and description
  • Configured prompt text and placeholder
  • Set correct stateKey for response
  • Tested video playback in browser
  • Tested state restoration
  • Tested interactivity locking
  • Verified response text is preserved
  • Checked video loads and plays correctly

Tips

  1. Clear prompts - Tell students exactly what to observe and explain
  2. Adequate textarea height - Use responseRows attribute (6+ for detailed responses)
  3. Placeholder guidance - Show students what kind of response you expect
  4. Video length - Keep videos under 3-5 minutes for best engagement
  5. Intro context - Set expectations before the video plays
  6. Auto-save - State updates automatically on every input (no submit button needed)

State Management

Initialization

function createDefaultState() {
  return {
    explanation: ""
  };
}

State Restoration

function applyInitialState(state) {
  Object.assign(chartState, state);
  buildLayout(d3, containerSelector);
}

Interactivity Control

function setInteractivity(enabled) {
  interactivityLocked = !enabled;
  buildLayout(d3, containerSelector);
}

Related Skills

Additional Resources