"use client"; import { useState } from "react"; import { BookOpenText, Play, Star, Video, } from "lucide-react"; import { ScoreBar } from "@/components/display"; import { EmptyState, ErrorBanner, Loading, PageHeading, } from "@/components/feedback"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { UsageGuide } from "@/components/usage-guide"; import { ApiError } from "@/lib/api"; import { skillVideoApi } from "@/lib/services"; const CATEGORIES = [ { value: "suture", label: "缝合技术" }, { value: "catheter", label: "导尿管置入" }, { value: "venipuncture", label: "静脉穿刺" }, { value: "intubation", label: "气管插管" }, { value: "cpr", label: "心肺复苏" }, { value: "physical-exam", label: "体格检查" }, { value: "aseptic", label: "无菌操作" }, { value: "surgical-scrub", label: "外科刷手" }, ]; export default function SkillVideoPage() { const [videos, setVideos] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [query, setQuery] = useState(""); async function search() { setLoading(true); setError(null); try { const res = await skillVideoApi.search({ query: query || undefined }); setVideos(Array.isArray(res) ? res : []); } catch (err) { setError(err instanceof ApiError ? err.message : "加载失败"); } finally { setLoading(false); } } return (
} title="技能视频" description="手术与操作技能视频学习,支持分段自评与关键点标记。" /> 视频检索
{CATEGORIES.map((c) => ( ))}
setQuery(e.target.value)} placeholder="搜索技能名称,如:清创缝合" className="max-w-md" />
{error &&
}
{loading ? ( ) : videos.length === 0 ? (
) : ( videos.map((v: any, i: number) => (
{v.duration && ( {v.duration} )}

{v.title ?? `视频 ${i + 1}`}

{v.category && ( {CATEGORIES.find((c) => c.value === v.category)?.label ?? v.category} )} {v.description}

{v.myScore != null && (
)}
{v.noteCount ?? 0} 条笔记 {v.favorite ? "已收藏" : "未收藏"}
)) )}
); }