Website (14 monoliths split): - compliance/page.tsx (1,519 → 9), docs/audit (1,262 → 20) - quality (1,231 → 16), alerts (1,203 → 10), docs (1,202 → 11) - i18n.ts (1,173 → 8 language files) - unity-bridge (1,094 → 12), backlog (1,087 → 6) - training (1,066 → 8), rag (1,063 → 8) - Deleted index_original.ts (4,899 LOC dead backup) Studio-v2 (5 monoliths split): - meet/page.tsx (1,481 → 9), messages (1,166 → 9) - AlertsB2BContext.tsx (1,165 → 5 modules) - alerts-b2b/page.tsx (1,019 → 6), korrektur/archiv (1,001 → 6) All existing imports preserved. Zero new TypeScript errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
200 lines
8.2 KiB
TypeScript
200 lines
8.2 KiB
TypeScript
'use client'
|
|
|
|
import { useTheme } from '@/lib/ThemeContext'
|
|
import { useLanguage } from '@/lib/LanguageContext'
|
|
import { Sidebar } from '@/components/Sidebar'
|
|
import { Icons, type TabType } from './_components/types'
|
|
import { useMeetPage } from './_components/useMeetPage'
|
|
import { DashboardTab } from './_components/DashboardTab'
|
|
import { BreakoutTab } from './_components/BreakoutTab'
|
|
import { RecordingsTab } from './_components/RecordingsTab'
|
|
import { NewMeetingModal } from './_components/NewMeetingModal'
|
|
import { JoinMeetingModal } from './_components/JoinMeetingModal'
|
|
import { TranscriptModal } from './_components/TranscriptModal'
|
|
|
|
export default function MeetPage() {
|
|
const { isDark } = useTheme()
|
|
const { t } = useLanguage()
|
|
const meet = useMeetPage()
|
|
|
|
return (
|
|
<div className={`min-h-screen relative overflow-hidden ${
|
|
isDark
|
|
? 'bg-gradient-to-br from-indigo-900 via-purple-900 to-pink-800'
|
|
: 'bg-gradient-to-br from-slate-100 via-blue-50 to-indigo-100'
|
|
}`}>
|
|
{/* Animated Background Blobs */}
|
|
<div className="absolute inset-0 overflow-hidden pointer-events-none">
|
|
<div className={`absolute -top-40 -right-40 w-80 h-80 rounded-full mix-blend-multiply filter blur-3xl animate-blob ${
|
|
isDark ? 'bg-purple-500 opacity-70' : 'bg-purple-300 opacity-50'
|
|
}`} />
|
|
<div className={`absolute -bottom-40 -left-40 w-80 h-80 rounded-full mix-blend-multiply filter blur-3xl animate-blob animation-delay-2000 ${
|
|
isDark ? 'bg-blue-500 opacity-70' : 'bg-blue-300 opacity-50'
|
|
}`} />
|
|
<div className={`absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-80 h-80 rounded-full mix-blend-multiply filter blur-3xl animate-blob animation-delay-4000 ${
|
|
isDark ? 'bg-pink-500 opacity-70' : 'bg-pink-300 opacity-50'
|
|
}`} />
|
|
</div>
|
|
|
|
{/* Layout with Sidebar */}
|
|
<div className="relative z-10 flex min-h-screen gap-6 p-4">
|
|
<Sidebar />
|
|
|
|
<main className="flex-1">
|
|
{/* Header */}
|
|
<div className="flex items-center justify-between mb-8">
|
|
<div>
|
|
<h1 className={`text-4xl font-bold mb-2 ${isDark ? 'text-white' : 'text-slate-900'}`}>
|
|
BreakPilot Meet
|
|
</h1>
|
|
<p className={isDark ? 'text-white/60' : 'text-slate-600'}>
|
|
Videokonferenzen, Schulungen und Elterngespraeche verwalten
|
|
</p>
|
|
</div>
|
|
<button
|
|
onClick={() => meet.setShowNewMeetingModal(true)}
|
|
className="flex items-center gap-2 px-6 py-3 bg-gradient-to-r from-blue-500 to-purple-500 text-white rounded-2xl font-medium hover:shadow-xl hover:shadow-purple-500/30 transition-all hover:scale-105"
|
|
>
|
|
{Icons.plus}
|
|
Neues Meeting
|
|
</button>
|
|
</div>
|
|
|
|
{/* Tabs */}
|
|
<div className={`backdrop-blur-xl border rounded-2xl p-1 inline-flex gap-1 mb-8 ${
|
|
isDark
|
|
? 'bg-white/10 border-white/20'
|
|
: 'bg-white/70 border-black/10 shadow-lg'
|
|
}`}>
|
|
{([
|
|
{ id: 'dashboard', label: 'Dashboard' },
|
|
{ id: 'breakout', label: 'Breakout-Rooms' },
|
|
{ id: 'recordings', label: 'Aufzeichnungen' },
|
|
] as { id: TabType; label: string }[]).map((tab) => (
|
|
<button
|
|
key={tab.id}
|
|
onClick={() => meet.setActiveTab(tab.id)}
|
|
className={`px-6 py-3 rounded-xl font-medium transition-all ${
|
|
meet.activeTab === tab.id
|
|
? isDark
|
|
? 'bg-white/20 text-white shadow-lg'
|
|
: 'bg-white text-slate-900 shadow-lg'
|
|
: isDark
|
|
? 'text-white/60 hover:text-white hover:bg-white/10'
|
|
: 'text-slate-600 hover:text-slate-900 hover:bg-slate-100'
|
|
}`}
|
|
>
|
|
{tab.label}
|
|
</button>
|
|
))}
|
|
</div>
|
|
|
|
{/* Tab Content */}
|
|
{meet.activeTab === 'dashboard' && (
|
|
<DashboardTab
|
|
isDark={isDark} loading={meet.loading} stats={meet.stats}
|
|
activeMeetings={meet.activeMeetings} scheduledMeetings={meet.scheduledMeetings}
|
|
errorMessage={meet.errorMessage} creating={meet.creating}
|
|
setErrorMessage={meet.setErrorMessage}
|
|
setShowNewMeetingModal={meet.setShowNewMeetingModal}
|
|
setMeetingType={meet.setMeetingType}
|
|
startQuickMeeting={meet.startQuickMeeting}
|
|
joinMeeting={meet.joinMeeting} copyMeetingLink={meet.copyMeetingLink}
|
|
/>
|
|
)}
|
|
|
|
{meet.activeTab === 'breakout' && (
|
|
<BreakoutTab
|
|
isDark={isDark} hasActiveMeeting={meet.hasActiveMeeting}
|
|
breakoutRooms={meet.breakoutRooms}
|
|
breakoutAssignment={meet.breakoutAssignment}
|
|
breakoutTimer={meet.breakoutTimer}
|
|
setBreakoutAssignment={meet.setBreakoutAssignment}
|
|
setBreakoutTimer={meet.setBreakoutTimer}
|
|
addBreakoutRoom={meet.addBreakoutRoom}
|
|
removeBreakoutRoom={meet.removeBreakoutRoom}
|
|
startQuickMeeting={meet.startQuickMeeting}
|
|
/>
|
|
)}
|
|
|
|
{meet.activeTab === 'recordings' && (
|
|
<RecordingsTab
|
|
isDark={isDark} loading={meet.loading}
|
|
recordingsFilter={meet.recordingsFilter}
|
|
setRecordingsFilter={meet.setRecordingsFilter}
|
|
filteredRecordings={meet.filteredRecordings}
|
|
recordings={meet.recordings}
|
|
totalStorageBytes={meet.totalStorageBytes}
|
|
maxStorageGB={meet.maxStorageGB}
|
|
storagePercent={meet.storagePercent}
|
|
fetchData={meet.fetchData}
|
|
startQuickMeeting={meet.startQuickMeeting}
|
|
playRecording={meet.playRecording}
|
|
viewTranscript={meet.viewTranscript}
|
|
downloadRecording={meet.downloadRecording}
|
|
deleteRecording={meet.deleteRecording}
|
|
/>
|
|
)}
|
|
</main>
|
|
</div>
|
|
|
|
{/* Modals */}
|
|
{meet.showNewMeetingModal && (
|
|
<NewMeetingModal
|
|
isDark={isDark}
|
|
meetingType={meet.meetingType} meetingTitle={meet.meetingTitle}
|
|
meetingDuration={meet.meetingDuration} meetingDateTime={meet.meetingDateTime}
|
|
enableLobby={meet.enableLobby} enableRecording={meet.enableRecording}
|
|
muteOnStart={meet.muteOnStart} creating={meet.creating}
|
|
setMeetingType={meet.setMeetingType} setMeetingTitle={meet.setMeetingTitle}
|
|
setMeetingDuration={meet.setMeetingDuration} setMeetingDateTime={meet.setMeetingDateTime}
|
|
setEnableLobby={meet.setEnableLobby} setEnableRecording={meet.setEnableRecording}
|
|
setMuteOnStart={meet.setMuteOnStart}
|
|
onClose={() => meet.setShowNewMeetingModal(false)}
|
|
onSubmit={meet.createMeeting}
|
|
/>
|
|
)}
|
|
|
|
{meet.showJoinModal && (
|
|
<JoinMeetingModal
|
|
isDark={isDark}
|
|
currentMeetingUrl={meet.currentMeetingUrl}
|
|
currentMeetingTitle={meet.currentMeetingTitle}
|
|
openInNewTab={meet.openInNewTab}
|
|
onClose={() => meet.setShowJoinModal(false)}
|
|
/>
|
|
)}
|
|
|
|
{meet.showTranscriptModal && meet.currentRecording && (
|
|
<TranscriptModal
|
|
isDark={isDark}
|
|
currentRecording={meet.currentRecording}
|
|
transcriptText={meet.transcriptText}
|
|
transcriptLoading={meet.transcriptLoading}
|
|
startTranscription={meet.startTranscription}
|
|
onClose={() => meet.setShowTranscriptModal(false)}
|
|
/>
|
|
)}
|
|
|
|
{/* Blob Animation Styles */}
|
|
<style jsx>{`
|
|
@keyframes blob {
|
|
0% { transform: translate(0px, 0px) scale(1); }
|
|
33% { transform: translate(30px, -50px) scale(1.1); }
|
|
66% { transform: translate(-20px, 20px) scale(0.9); }
|
|
100% { transform: translate(0px, 0px) scale(1); }
|
|
}
|
|
.animate-blob {
|
|
animation: blob 7s infinite;
|
|
}
|
|
.animation-delay-2000 {
|
|
animation-delay: 2s;
|
|
}
|
|
.animation-delay-4000 {
|
|
animation-delay: 4s;
|
|
}
|
|
`}</style>
|
|
</div>
|
|
)
|
|
}
|