PromptParts 组件

PromptParts 组件

Prompt 组件分析组件,通过分类游戏教学 Prompt 的各个组成部分。

功能概述

  • 组件分类: 学习 Prompt 的四个核心组成部分
  • 交互式学习: 点击选择文本并分类
  • 即时反馈: 正确/错误的视觉反馈
  • 进度追踪: 显示得分情况
  • 状态持久化: 保存学习进度

Props 接口

type PartType = "role" | "task" | "context" | "constraint";

interface PromptPart {
  text: string;      // 文本内容
  type: PartType;    // 组件类型
}

interface PromptPartsProps {
  title?: string;           // 标题
  instruction?: string;     // 说明文字
  parts: PromptPart[];      // Prompt 组件数组
  successMessage?: string;  // 成功消息
}

Prompt 组件类型

类型Emoji颜色说明
role🎭紫色角色定义
task✏️蓝色任务描述
context📖绿色上下文信息
constraint📏橙色约束条件

颜色配置

const partColors = {
  role:       { bg: "bg-purple-100", border: "border-purple-400", text: "text-purple-700", emoji: "🎭" },
  task:       { bg: "bg-blue-100",   border: "border-blue-400",   text: "text-blue-700",   emoji: "✏️" },
  context:    { bg: "bg-green-100",  border: "border-green-400",  text: "text-green-700",  emoji: "📖" },
  constraint: { bg: "bg-orange-100", border: "border-orange-400", text: "text-orange-700", emoji: "📏" },
};

交互流程

  1. 查看文本: 显示打乱顺序的 Prompt 片段
  2. 点击片段: 选中要高亮的文本
  3. 选择分类: 从四个类别中选择
  4. 获得反馈: 正确显示绿色边框,错误显示红色边框
  5. 完成所有: 显示成功消息

使用示例

import { PromptParts } from "@/components/kids/elements/prompt-parts";

<PromptParts
  title="分析这个 Prompt"
  instruction="点击每个部分,选择它属于哪一类"
  parts={[
    { text: "你是一位专业的故事作家", type: "role" },
    { text: "写一个关于太空冒险的故事", type: "task" },
    { text: "主角是一个勇敢的小女孩", type: "context" },
    { text: "故事要在 200 字以内", type: "constraint" },
  ]}
  successMessage="完美!你理解了 Prompt 的结构!"
/>

翻译键

{
  "kids": {
    "promptParts": {
      "title": "🧩 Prompt 拼图",
      "instruction": "把这些 Prompt 片段分类到正确的类别",
      "score": "得分",
      "pickCategory": "选择一个类别:",
      "types": {
        "role": "角色",
        "task": "任务",
        "context": "上下文",
        "constraint": "约束"
      },
      "success": "太棒了!你掌握了 Prompt 的组成!",
      "retry": "再玩一次"
    }
  }
}

状态管理

内部状态

const [assignments, setAssignments] = useState<Record<number, PartType | null>>({});
const [selectedPart, setSelectedPart] = useState<number | null>(null);
const [completed, setCompleted] = useState(false);

完成判断

const allAssigned = parts.every((_, index) => assignments[index] != null);
const allCorrect = parts.every((part, index) => assignments[index] === part.type);

样式说明

  • 背景: 黄色渐变 (from-[#FEF3C7] to-[#FDE68A])
  • 边框: 4px 实线琥珀色 (border-[#D97706])
  • 圆角: 12px (rounded-xl)

文本片段状态

  • 未分类: 灰色背景
  • 已选中: 黄色边框,放大效果
  • 正确: 对应类别颜色 + 绿色边框
  • 错误: 对应类别颜色 + 红色边框

依赖

  • next-intl - 国际化
  • react (useId, useState, useEffect)
  • @/lib/utils (cn)
  • @/components/kids/providers/level-context
  • @/lib/kids/progress

注意事项

  • 需要至少 2 个 PromptPart 才有意义
  • 文本片段顺序会自动打乱
  • 支持多次尝试直到全部正确
← 返回目录