[split-required] Split website + studio-v2 monoliths (Phase 3 continued)
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>
This commit is contained in:
131
studio-v2/app/meet/_components/NewMeetingModal.tsx
Normal file
131
studio-v2/app/meet/_components/NewMeetingModal.tsx
Normal file
@@ -0,0 +1,131 @@
|
||||
'use client'
|
||||
|
||||
import { Icons } from './types'
|
||||
|
||||
interface NewMeetingModalProps {
|
||||
isDark: boolean
|
||||
meetingType: string
|
||||
meetingTitle: string
|
||||
meetingDuration: number
|
||||
meetingDateTime: string
|
||||
enableLobby: boolean
|
||||
enableRecording: boolean
|
||||
muteOnStart: boolean
|
||||
creating: boolean
|
||||
setMeetingType: (type: string) => void
|
||||
setMeetingTitle: (title: string) => void
|
||||
setMeetingDuration: (duration: number) => void
|
||||
setMeetingDateTime: (dateTime: string) => void
|
||||
setEnableLobby: (val: boolean) => void
|
||||
setEnableRecording: (val: boolean) => void
|
||||
setMuteOnStart: (val: boolean) => void
|
||||
onClose: () => void
|
||||
onSubmit: () => void
|
||||
}
|
||||
|
||||
export function NewMeetingModal({
|
||||
isDark, meetingType, meetingTitle, meetingDuration, meetingDateTime,
|
||||
enableLobby, enableRecording, muteOnStart, creating,
|
||||
setMeetingType, setMeetingTitle, setMeetingDuration, setMeetingDateTime,
|
||||
setEnableLobby, setEnableRecording, setMuteOnStart,
|
||||
onClose, onSubmit,
|
||||
}: NewMeetingModalProps) {
|
||||
const inputClass = `w-full px-4 py-3 rounded-xl transition-all focus:outline-none focus:ring-2 ${
|
||||
isDark
|
||||
? 'bg-white/10 border border-white/20 text-white focus:ring-white/30'
|
||||
: 'bg-slate-50 border border-slate-300 text-slate-900 focus:ring-blue-300'
|
||||
}`
|
||||
|
||||
return (
|
||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
|
||||
<div className="absolute inset-0 bg-black/50 backdrop-blur-sm" onClick={onClose} />
|
||||
<div className={`relative w-full max-w-lg rounded-3xl border p-6 ${
|
||||
isDark ? 'bg-slate-900 border-white/20' : 'bg-white border-slate-200 shadow-2xl'
|
||||
}`}>
|
||||
<div className="flex items-center justify-between mb-6">
|
||||
<h2 className={`text-xl font-semibold ${isDark ? 'text-white' : 'text-slate-900'}`}>Neues Meeting erstellen</h2>
|
||||
<button onClick={onClose}
|
||||
className={`p-2 rounded-lg transition-colors ${isDark ? 'hover:bg-white/10' : 'hover:bg-slate-100'}`}>
|
||||
{Icons.close}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label className={`block text-sm font-medium mb-2 ${isDark ? 'text-white/70' : 'text-slate-700'}`}>Meeting-Typ</label>
|
||||
<select value={meetingType} onChange={(e) => setMeetingType(e.target.value)} className={inputClass}>
|
||||
<option value="quick">Sofort-Meeting</option>
|
||||
<option value="scheduled">Geplantes Meeting</option>
|
||||
<option value="training">Schulung</option>
|
||||
<option value="parent">Elterngespraech</option>
|
||||
<option value="class">Klassenkonferenz</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className={`block text-sm font-medium mb-2 ${isDark ? 'text-white/70' : 'text-slate-700'}`}>Titel</label>
|
||||
<input
|
||||
type="text"
|
||||
value={meetingTitle}
|
||||
onChange={(e) => setMeetingTitle(e.target.value)}
|
||||
placeholder="Meeting-Titel eingeben"
|
||||
className={`${inputClass} ${isDark ? 'placeholder-white/40' : 'placeholder-slate-400'}`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{meetingType !== 'quick' && (
|
||||
<div>
|
||||
<label className={`block text-sm font-medium mb-2 ${isDark ? 'text-white/70' : 'text-slate-700'}`}>Datum & Uhrzeit</label>
|
||||
<input type="datetime-local" value={meetingDateTime}
|
||||
onChange={(e) => setMeetingDateTime(e.target.value)} className={inputClass} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<label className={`block text-sm font-medium mb-2 ${isDark ? 'text-white/70' : 'text-slate-700'}`}>Dauer</label>
|
||||
<select value={meetingDuration} onChange={(e) => setMeetingDuration(Number(e.target.value))} className={inputClass}>
|
||||
<option value={30}>30 Minuten</option>
|
||||
<option value={60}>60 Minuten</option>
|
||||
<option value={90}>90 Minuten</option>
|
||||
<option value={120}>120 Minuten</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-3 pt-2">
|
||||
<CheckboxOption isDark={isDark} checked={enableLobby}
|
||||
onChange={setEnableLobby} label="Warteraum aktivieren" />
|
||||
<CheckboxOption isDark={isDark} checked={enableRecording}
|
||||
onChange={setEnableRecording} label="Aufzeichnung erlauben" />
|
||||
<CheckboxOption isDark={isDark} checked={muteOnStart}
|
||||
onChange={setMuteOnStart} label="Teilnehmer stummschalten bei Beitritt" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className={`mt-6 pt-6 border-t flex justify-end gap-3 ${isDark ? 'border-white/10' : 'border-slate-200'}`}>
|
||||
<button onClick={onClose}
|
||||
className={`px-5 py-2.5 rounded-xl font-medium transition-all ${
|
||||
isDark ? 'text-white/60 hover:text-white hover:bg-white/10' : 'text-slate-600 hover:text-slate-900 hover:bg-slate-100'
|
||||
}`}>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button onClick={onSubmit} disabled={creating}
|
||||
className="px-6 py-2.5 bg-gradient-to-r from-blue-500 to-purple-500 text-white rounded-xl font-medium hover:shadow-lg hover:shadow-purple-500/30 transition-all hover:scale-105 disabled:opacity-50 disabled:hover:scale-100">
|
||||
{creating ? 'Erstellen...' : meetingType === 'quick' ? 'Meeting starten' : 'Meeting erstellen'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function CheckboxOption({ isDark, checked, onChange, label }: {
|
||||
isDark: boolean; checked: boolean; onChange: (val: boolean) => void; label: string
|
||||
}) {
|
||||
return (
|
||||
<label className={`flex items-center gap-3 cursor-pointer ${isDark ? 'text-white/70' : 'text-slate-700'}`}>
|
||||
<input type="checkbox" checked={checked} onChange={(e) => onChange(e.target.checked)}
|
||||
className="w-5 h-5 rounded text-blue-500 focus:ring-blue-500" />
|
||||
<span className="text-sm">{label}</span>
|
||||
</label>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user