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>
164 lines
6.7 KiB
TypeScript
164 lines
6.7 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
import { useTheme } from '@/lib/ThemeContext'
|
|
|
|
export function EmailImportModal({
|
|
onClose,
|
|
onImport
|
|
}: {
|
|
onClose: () => void
|
|
onImport: (content: string, subject?: string) => void
|
|
}) {
|
|
const { isDark } = useTheme()
|
|
const [emailSubject, setEmailSubject] = useState('')
|
|
const [emailContent, setEmailContent] = useState('')
|
|
const [isProcessing, setIsProcessing] = useState(false)
|
|
|
|
const handleImport = async () => {
|
|
if (!emailContent.trim()) return
|
|
setIsProcessing(true)
|
|
// Simulate processing delay
|
|
await new Promise(resolve => setTimeout(resolve, 800))
|
|
onImport(emailContent, emailSubject || undefined)
|
|
setIsProcessing(false)
|
|
onClose()
|
|
}
|
|
|
|
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-2xl rounded-3xl border p-6 max-h-[90vh] overflow-y-auto ${
|
|
isDark ? 'bg-slate-900 border-white/20' : 'bg-white border-slate-200 shadow-2xl'
|
|
}`}>
|
|
<div className="flex items-center justify-between mb-6">
|
|
<div className="flex items-center gap-3">
|
|
<div className="w-10 h-10 rounded-xl bg-gradient-to-br from-purple-500 to-pink-500 flex items-center justify-center text-xl">
|
|
📧
|
|
</div>
|
|
<div>
|
|
<h3 className={`text-lg font-semibold ${isDark ? 'text-white' : 'text-slate-900'}`}>
|
|
E-Mail manuell einfuegen
|
|
</h3>
|
|
<p className={`text-sm ${isDark ? 'text-white/60' : 'text-slate-500'}`}>
|
|
Fuegen Sie den Inhalt einer Google Alert E-Mail ein
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<button onClick={onClose} className={`p-2 rounded-lg ${isDark ? 'hover:bg-white/10' : 'hover:bg-slate-100'}`}>
|
|
<svg className={`w-5 h-5 ${isDark ? 'text-white/60' : 'text-slate-400'}`} fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
|
|
<div className="space-y-4">
|
|
{/* Subject (optional) */}
|
|
<div>
|
|
<label className={`block text-sm font-medium mb-2 ${isDark ? 'text-white/80' : 'text-slate-700'}`}>
|
|
Betreff (optional)
|
|
</label>
|
|
<input
|
|
type="text"
|
|
placeholder="z.B. Google Alert - Parkscheinautomaten"
|
|
value={emailSubject}
|
|
onChange={(e) => setEmailSubject(e.target.value)}
|
|
className={`w-full px-4 py-3 rounded-xl border ${
|
|
isDark
|
|
? 'bg-white/10 border-white/20 text-white placeholder-white/40'
|
|
: 'bg-white border-slate-200 text-slate-900 placeholder-slate-400'
|
|
}`}
|
|
/>
|
|
</div>
|
|
|
|
{/* Email Content */}
|
|
<div>
|
|
<label className={`block text-sm font-medium mb-2 ${isDark ? 'text-white/80' : 'text-slate-700'}`}>
|
|
E-Mail-Inhalt *
|
|
</label>
|
|
<textarea
|
|
placeholder="Fuegen Sie hier den kompletten E-Mail-Inhalt ein...
|
|
|
|
Beispiel:
|
|
Google Alerts
|
|
|
|
Parkscheinautomaten
|
|
Tagesaktuell | 23. Januar 2026
|
|
|
|
Stadt Muenchen schreibt neue Parkscheinautomaten aus
|
|
www.muenchen.de - Die Landeshauptstadt Muenchen schreibt die Beschaffung von 150 neuen Parkscheinautomaten fuer das Stadtgebiet aus. Die Submission endet am 15.02.2026..."
|
|
value={emailContent}
|
|
onChange={(e) => setEmailContent(e.target.value)}
|
|
rows={12}
|
|
className={`w-full px-4 py-3 rounded-xl border resize-none font-mono text-sm ${
|
|
isDark
|
|
? 'bg-white/10 border-white/20 text-white placeholder-white/30'
|
|
: 'bg-white border-slate-200 text-slate-900 placeholder-slate-400'
|
|
}`}
|
|
/>
|
|
<p className={`text-xs mt-2 ${isDark ? 'text-white/40' : 'text-slate-400'}`}>
|
|
Kopieren Sie den gesamten E-Mail-Text inkl. Links aus Ihrer Google Alert E-Mail
|
|
</p>
|
|
</div>
|
|
|
|
{/* Info Box */}
|
|
<div className={`p-4 rounded-xl ${isDark ? 'bg-purple-500/10 border border-purple-500/30' : 'bg-purple-50 border border-purple-200'}`}>
|
|
<div className="flex items-start gap-3">
|
|
<span className="text-xl">🤖</span>
|
|
<div>
|
|
<p className={`text-sm font-medium ${isDark ? 'text-purple-300' : 'text-purple-700'}`}>
|
|
KI-Verarbeitung
|
|
</p>
|
|
<p className={`text-sm ${isDark ? 'text-purple-200/70' : 'text-purple-600'}`}>
|
|
Die KI analysiert den Inhalt, erkennt Beschaffungs-Signale, identifiziert
|
|
potenzielle Auftraggeber und bewertet die Relevanz fuer Ihr Unternehmen.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Actions */}
|
|
<div className="flex items-center justify-end gap-3 mt-6 pt-4 border-t border-white/10">
|
|
<button
|
|
onClick={onClose}
|
|
className={`px-4 py-2 rounded-xl font-medium ${
|
|
isDark
|
|
? 'text-white/60 hover:text-white hover:bg-white/10'
|
|
: 'text-slate-500 hover:text-slate-900 hover:bg-slate-100'
|
|
}`}
|
|
>
|
|
Abbrechen
|
|
</button>
|
|
<button
|
|
onClick={handleImport}
|
|
disabled={!emailContent.trim() || isProcessing}
|
|
className={`px-6 py-2 rounded-xl font-medium transition-all flex items-center gap-2 ${
|
|
emailContent.trim() && !isProcessing
|
|
? 'bg-gradient-to-r from-purple-500 to-pink-500 text-white hover:shadow-lg hover:shadow-purple-500/30'
|
|
: isDark
|
|
? 'bg-white/10 text-white/30 cursor-not-allowed'
|
|
: 'bg-slate-200 text-slate-400 cursor-not-allowed'
|
|
}`}
|
|
>
|
|
{isProcessing ? (
|
|
<>
|
|
<svg className="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
|
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
|
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
</svg>
|
|
Verarbeite...
|
|
</>
|
|
) : (
|
|
<>
|
|
<span>🔍</span>
|
|
Analysieren & Importieren
|
|
</>
|
|
)}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|