Extracted components and constants into _components/ subdirectories to bring all three pages under the 300 LOC soft target (was 651/628/612, now 255/232/278 LOC respectively). Zero behavior changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
72 lines
2.7 KiB
TypeScript
72 lines
2.7 KiB
TypeScript
'use client'
|
|
|
|
interface VideoStatus {
|
|
status: string
|
|
lessons?: Array<{ lessonId: string; status: string }>
|
|
}
|
|
|
|
interface VideosTabProps {
|
|
videoStatus: VideoStatus | null
|
|
isGeneratingVideos: boolean
|
|
onGenerateVideos: () => void
|
|
onCheckVideoStatus: () => void
|
|
}
|
|
|
|
export function VideosTab({ videoStatus, isGeneratingVideos, onGenerateVideos, onCheckVideoStatus }: VideosTabProps) {
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className="bg-white rounded-xl border border-gray-200 p-6">
|
|
<div className="flex items-center justify-between mb-4">
|
|
<h3 className="text-lg font-semibold text-gray-900">Video-Generierung</h3>
|
|
<div className="flex gap-2">
|
|
<button onClick={onCheckVideoStatus} className="px-4 py-2 text-sm border border-gray-300 rounded-lg hover:bg-gray-50">
|
|
Status pruefen
|
|
</button>
|
|
<button
|
|
onClick={onGenerateVideos}
|
|
disabled={isGeneratingVideos}
|
|
className="px-4 py-2 text-sm bg-purple-600 text-white rounded-lg hover:bg-purple-700 disabled:opacity-50"
|
|
>
|
|
{isGeneratingVideos ? 'Wird gestartet...' : 'Videos generieren'}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="bg-blue-50 border border-blue-200 rounded-xl p-4 mb-4 text-sm text-blue-700">
|
|
Videos werden mit ElevenLabs (Stimme) und HeyGen (Avatar) generiert.
|
|
Konfigurieren Sie die API-Keys in den Umgebungsvariablen.
|
|
</div>
|
|
|
|
{videoStatus && (
|
|
<div className="space-y-3">
|
|
<div className="flex items-center gap-2">
|
|
<span className="text-sm text-gray-500">Gesamtstatus:</span>
|
|
<span className={`px-2 py-1 text-xs rounded-full ${
|
|
videoStatus.status === 'completed' ? 'bg-green-100 text-green-700' :
|
|
videoStatus.status === 'processing' ? 'bg-yellow-100 text-yellow-700' :
|
|
'bg-gray-100 text-gray-600'
|
|
}`}>
|
|
{videoStatus.status}
|
|
</span>
|
|
</div>
|
|
{videoStatus.lessons?.map((ls) => (
|
|
<div key={ls.lessonId} className="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
|
|
<span className="text-sm text-gray-700">Lektion {ls.lessonId.slice(-4)}</span>
|
|
<span className={`text-xs ${ls.status === 'completed' ? 'text-green-600' : 'text-gray-500'}`}>
|
|
{ls.status}
|
|
</span>
|
|
</div>
|
|
))}
|
|
</div>
|
|
)}
|
|
|
|
{!videoStatus && (
|
|
<p className="text-sm text-gray-500 text-center py-8">
|
|
Klicken Sie auf "Videos generieren" um den Prozess zu starten.
|
|
</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|