TransHub / client /src /components /SubtitlingModule.tsx
linguabot's picture
Upload folder using huggingface_hub
ff65064 verified
import React from 'react';
export interface SubtitleSegment {
id: number;
startTime: string;
endTime: string;
duration: string;
sourceText: string;
targetText?: string;
isCurrent?: boolean;
}
export interface VideoInfo {
title: string;
duration: string;
totalSegments: number;
currentSegment: number;
}
interface SubtitlingModuleProps {
videoInfo: VideoInfo;
subtitleSegments: SubtitleSegment[];
currentDisplayedSubtitle?: string;
onSegmentClick?: (id: number) => void;
getSegmentButtonClass?: (id: number) => string;
onPlayPause?: () => void;
isPlaying?: boolean;
onSaveSegment?: (id: number, text: string) => void;
}
/**
* Reusable subtitling interface template for future weeks.
* Not currently rendered in any page; kept for reuse.
*/
const SubtitlingModule: React.FC<SubtitlingModuleProps> = ({
videoInfo,
subtitleSegments,
currentDisplayedSubtitle,
onSegmentClick,
getSegmentButtonClass,
onPlayPause,
isPlaying,
}) => {
return (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
<div className="bg-white rounded-xl shadow-lg border border-gray-100 p-6">
<div className="mb-4">
<h3 className="text-xl font-bold text-gray-900 mb-2">{videoInfo.title}</h3>
</div>
<div className="bg-black rounded-lg aspect-video overflow-hidden relative">
<div className="absolute inset-0 flex items-center justify-center text-white/70 text-sm">Video Placeholder</div>
{currentDisplayedSubtitle && (
<div className="absolute bottom-8 left-1/2 transform -translate-x-1/2 z-10">
<div className="bg-black bg-opacity-80 text-white px-6 py-3 rounded-lg text-center max-w-lg">
<p className={`text-base font-medium leading-relaxed tracking-wide ${currentDisplayedSubtitle.length <= 42 ? 'whitespace-nowrap' : 'whitespace-pre-line'}`}>
{currentDisplayedSubtitle}
</p>
</div>
</div>
)}
</div>
</div>
<div className="bg-white rounded-xl shadow-lg border border-gray-100 p-6">
<h3 className="text-xl font-bold text-gray-900 mb-4">Translation Workspace</h3>
<div className="grid grid-cols-9 gap-1 mb-6">
{subtitleSegments.map((segment) => (
<button
key={segment.id}
onClick={() => onSegmentClick && onSegmentClick(segment.id)}
className={`px-1 py-1 rounded text-xs w-full ${getSegmentButtonClass ? getSegmentButtonClass(segment.id) : ''}`}
>
{segment.id}
</button>
))}
</div>
<div className="flex items-center gap-2 mb-4">
<button onClick={onPlayPause} className="px-3 py-1.5 text-sm rounded-md border border-gray-300">
{isPlaying ? 'Pause' : 'Play'}
</button>
<div className="text-sm text-gray-600">{videoInfo.currentSegment}/{videoInfo.totalSegments}</div>
</div>
<div className="space-y-4">
{subtitleSegments.map(seg => (
<div key={seg.id} className="border border-gray-200 rounded-lg p-3">
<div className="text-xs text-gray-500 mb-1">{seg.startTime} → {seg.endTime} ({seg.duration})</div>
<div className="text-sm text-gray-800 mb-2">{seg.sourceText}</div>
<textarea className="w-full border border-gray-300 rounded p-2 text-sm" defaultValue={seg.targetText || ''} rows={2} />
</div>
))}
</div>
</div>
</div>
);
};
export default SubtitlingModule;