chrysopedia/frontend/src/api/videos.ts
jlightner 7b111a7ded feat: Built ChapterReview page with WaveSurfer waveform (draggable/resi…
- "frontend/src/pages/ChapterReview.tsx"
- "frontend/src/pages/ChapterReview.module.css"
- "frontend/src/api/videos.ts"
- "frontend/src/App.tsx"

GSD-Task: S06/T02
2026-04-04 06:07:23 +00:00

110 lines
3.3 KiB
TypeScript

import { request, BASE } from "./client";
// ── Types ────────────────────────────────────────────────────────────────────
export interface VideoDetail {
id: string;
filename: string;
file_path: string;
duration_seconds: number | null;
content_type: string;
creator_id: string;
creator_name: string;
creator_slug: string;
video_url: string | null;
processing_status: string;
created_at: string;
updated_at: string;
}
export interface TranscriptSegment {
id: string;
source_video_id: string;
start_time: number;
end_time: number;
text: string;
segment_index: number;
topic_label: string | null;
}
export interface TranscriptResponse {
video_id: string;
segments: TranscriptSegment[];
total: number;
}
// ── API functions ────────────────────────────────────────────────────────────
export function fetchVideo(id: string): Promise<VideoDetail> {
return request<VideoDetail>(`${BASE}/videos/${encodeURIComponent(id)}`);
}
export function fetchTranscript(videoId: string): Promise<TranscriptResponse> {
return request<TranscriptResponse>(
`${BASE}/videos/${encodeURIComponent(videoId)}/transcript`,
);
}
// ── Chapters (KeyMoments as timeline markers) ────────────────────────────────
export interface Chapter {
id: string;
title: string;
start_time: number;
end_time: number;
content_type: string;
chapter_status: string;
sort_order: number;
}
export interface ChaptersResponse {
video_id: string;
chapters: Chapter[];
}
export function fetchChapters(videoId: string): Promise<ChaptersResponse> {
return request<ChaptersResponse>(
`${BASE}/videos/${encodeURIComponent(videoId)}/chapters`,
);
}
// ── Creator chapter management ───────────────────────────────────────────────
export function fetchCreatorChapters(videoId: string): Promise<ChaptersResponse> {
return request<ChaptersResponse>(
`${BASE}/creator/${encodeURIComponent(videoId)}/chapters`,
);
}
export interface ChapterPatch {
title?: string;
start_time?: number;
end_time?: number;
chapter_status?: string;
}
export function updateChapter(chapterId: string, patch: ChapterPatch): Promise<Chapter> {
return request<Chapter>(
`${BASE}/creator/chapters/${encodeURIComponent(chapterId)}`,
{ method: "PATCH", body: JSON.stringify(patch) },
);
}
export interface ReorderItem {
id: string;
sort_order: number;
}
export function reorderChapters(videoId: string, order: ReorderItem[]): Promise<ChaptersResponse> {
return request<ChaptersResponse>(
`${BASE}/creator/${encodeURIComponent(videoId)}/chapters/reorder`,
{ method: "PUT", body: JSON.stringify({ chapters: order }) },
);
}
export function approveChapters(videoId: string, chapterIds: string[]): Promise<ChaptersResponse> {
return request<ChaptersResponse>(
`${BASE}/creator/${encodeURIComponent(videoId)}/chapters/approve`,
{ method: "POST", body: JSON.stringify({ chapter_ids: chapterIds }) },
);
}