'use client'; import React, { useState, useEffect } from 'react'; <<<<<<< HEAD import { EmailResponder } from './EmailResponder'; interface ContactMessage { id: string; name: string; email: string; subject: string; message: string; timestamp: string; responded: boolean; } export const EmailManager: React.FC = () => { const [messages, setMessages] = useState([]); const [selectedMessage, setSelectedMessage] = useState(null); const [showResponder, setShowResponder] = useState(false); const [isLoading, setIsLoading] = useState(true); const [filter, setFilter] = useState<'all' | 'unread' | 'responded'>('all'); // Mock data for demonstration - in real app, fetch from API useEffect(() => { const mockMessages: ContactMessage[] = [ { id: '1', name: 'Max Mustermann', email: 'max@example.com', subject: 'Projekt-Anfrage', message: 'Hallo Dennis,\n\nich interessiere mich für eine Zusammenarbeit an einem Web-Projekt. Können wir uns mal unterhalten?\n\nViele Grüße\nMax', timestamp: new Date().toISOString(), responded: false }, { id: '2', name: 'Anna Schmidt', email: 'anna@example.com', subject: 'Frage zu deinem Portfolio', message: 'Hi Dennis,\n\nsehr cooles Portfolio! Wie lange hast du an dem Design gearbeitet?\n\nLG Anna', timestamp: new Date(Date.now() - 86400000).toISOString(), responded: true }, { id: '3', name: 'Tom Weber', email: 'tom@example.com', subject: 'Job-Anfrage', message: 'Hallo,\n\nwir suchen einen Full-Stack Developer. Bist du interessiert?\n\nTom', timestamp: new Date(Date.now() - 172800000).toISOString(), responded: false } ]; setTimeout(() => { setMessages(mockMessages); setIsLoading(false); }, 1000); }, []); const filteredMessages = messages.filter(message => { switch (filter) { case 'unread': return !message.responded; case 'responded': return message.responded; default: return true; } }); const handleRespond = (message: ContactMessage) => { setSelectedMessage(message); setShowResponder(true); }; const handleResponseSent = () => { if (selectedMessage) { setMessages(prev => prev.map(msg => msg.id === selectedMessage.id ? { ...msg, responded: true } : msg )); } setShowResponder(false); setSelectedMessage(null); }; const formatDate = (timestamp: string) => { return new Date(timestamp).toLocaleString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); }; const getMessagePreview = (message: string) => { return message.length > 100 ? message.substring(0, 100) + '...' : message; }; if (isLoading) { return (
); } return (
{/* Header */}

📧 E-Mail Manager

Verwalte Kontaktanfragen und sende schöne Antworten

{filteredMessages.length} von {messages.length} Nachrichten
{/* Filters */}
{/* Messages List */}
{filteredMessages.length === 0 ? (
📭

Keine Nachrichten

{filter === 'unread' && 'Alle Nachrichten wurden beantwortet!'} {filter === 'responded' && 'Noch keine Nachrichten beantwortet.'} {filter === 'all' && 'Noch keine Kontaktanfragen eingegangen.'}

) : ( filteredMessages.map((message) => (

{message.name}

{message.email} {!message.responded && ( Neu )}

{message.subject}

{getMessagePreview(message.message)}

📅 {formatDate(message.timestamp)} {message.responded && ( ✅ Beantwortet )}
{!message.responded && ( )}
)) )}
{/* Email Responder Modal */} {showResponder && selectedMessage && ( )}
); }; ======= import { motion, AnimatePresence } from 'framer-motion'; import { Mail, Search, Reply, User, CheckCircle, Circle, Send, X, RefreshCw, Eye, Calendar, AtSign } from 'lucide-react'; interface ContactMessage { id: string; name: string; email: string; subject: string; message: string; createdAt: string; read: boolean; responded: boolean; priority: 'low' | 'medium' | 'high'; } export const EmailManager: React.FC = () => { const [messages, setMessages] = useState([]); const [selectedMessage, setSelectedMessage] = useState(null); const [isLoading, setIsLoading] = useState(true); const [filter, setFilter] = useState<'all' | 'unread' | 'responded'>('all'); const [searchTerm, setSearchTerm] = useState(''); const [showReplyModal, setShowReplyModal] = useState(false); const [replyContent, setReplyContent] = useState(''); // Load messages from API const loadMessages = async () => { try { setIsLoading(true); const response = await fetch('/api/contacts', { headers: { 'x-admin-request': 'true' } }); if (response.ok) { const data = await response.json(); const formattedMessages = data.contacts.map((contact: ContactMessage) => ({ id: contact.id.toString(), name: contact.name, email: contact.email, subject: contact.subject, message: contact.message, createdAt: contact.createdAt, read: false, responded: contact.responded || false, priority: 'medium' as const })); setMessages(formattedMessages); } } catch (error) { console.error('Error loading messages:', error); } finally { setIsLoading(false); } }; useEffect(() => { loadMessages(); }, []); const filteredMessages = messages.filter(message => { const matchesFilter = filter === 'all' || (filter === 'unread' && !message.read) || (filter === 'responded' && message.responded); const matchesSearch = searchTerm === '' || message.subject.toLowerCase().includes(searchTerm.toLowerCase()) || message.name.toLowerCase().includes(searchTerm.toLowerCase()) || message.email.toLowerCase().includes(searchTerm.toLowerCase()); return matchesFilter && matchesSearch; }); const handleMessageClick = (message: ContactMessage) => { setSelectedMessage(message); // Mark as read setMessages(prev => prev.map(msg => msg.id === message.id ? { ...msg, read: true } : msg )); }; const handleReply = async () => { if (!selectedMessage || !replyContent.trim()) return; try { const response = await fetch('/api/email/respond', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ to: selectedMessage.email, name: selectedMessage.name, template: 'reply', originalMessage: selectedMessage.message, response: replyContent }) }); if (response.ok) { setMessages(prev => prev.map(msg => msg.id === selectedMessage.id ? { ...msg, responded: true } : msg )); setShowReplyModal(false); setReplyContent(''); } } catch (error) { console.error('Error sending reply:', error); } }; const formatDate = (dateString: string) => { const date = new Date(dateString); return date.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric', hour: '2-digit', minute: '2-digit' }); }; // eslint-disable-next-line @typescript-eslint/no-unused-vars const getPriorityColor = (priority: string) => { switch (priority) { case 'high': return 'text-red-400'; case 'medium': return 'text-yellow-400'; case 'low': return 'text-green-400'; default: return 'text-blue-400'; } }; if (isLoading) { return (
); } return (
{/* Header */}

Email Manager

Manage your contact messages

{/* Filters and Search */}
setSearchTerm(e.target.value)} className="w-full pl-10 pr-4 py-2 bg-white/10 border border-white/20 rounded-lg text-white placeholder-white/50 focus:outline-none focus:ring-2 focus:ring-blue-500" />
{['all', 'unread', 'responded'].map((filterType) => ( ))}
{/* Messages List */}
{filteredMessages.length === 0 ? (

No messages found

) : ( filteredMessages.map((message) => ( handleMessageClick(message)} >

{message.subject}

{!message.read && } {message.responded && }

{message.name}

{formatDate(message.createdAt)}

)) )}
{/* Message Detail */}
{selectedMessage ? (
{/* Message Header */}

{selectedMessage.subject}

{selectedMessage.name}
{selectedMessage.email}
{formatDate(selectedMessage.createdAt)}
{!selectedMessage.read && } {selectedMessage.responded && }
{/* Message Body */}

Message:

{selectedMessage.message}
{/* Actions */}
) : (

Select a message to view details

)}
{/* Reply Modal */} {showReplyModal && selectedMessage && ( setShowReplyModal(false)} > e.stopPropagation()} >

Reply to {selectedMessage.name}