first version
This commit is contained in:
139
app/emails/page.tsx
Normal file
139
app/emails/page.tsx
Normal file
@@ -0,0 +1,139 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useSearchParams } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
|
||||
interface Email {
|
||||
key: string;
|
||||
subject: string;
|
||||
date: string;
|
||||
processed: string;
|
||||
}
|
||||
|
||||
export default function Emails() {
|
||||
const searchParams = useSearchParams();
|
||||
const bucket = searchParams.get('bucket');
|
||||
const mailbox = searchParams.get('mailbox');
|
||||
const [emails, setEmails] = useState<Email[]>([]);
|
||||
const [message, setMessage] = useState('');
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
if (!bucket || !mailbox) {
|
||||
setError('Missing parameters');
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
const auth = localStorage.getItem('auth');
|
||||
if (!auth) {
|
||||
setError('Not authenticated');
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(`/api/emails?bucket=${bucket}&mailbox=${encodeURIComponent(mailbox)}`, {
|
||||
headers: { Authorization: `Basic ${auth}` }
|
||||
})
|
||||
.then(res => {
|
||||
if (!res.ok) throw new Error('Failed to fetch emails');
|
||||
return res.json();
|
||||
})
|
||||
.then(setEmails)
|
||||
.catch(err => setError(err.message))
|
||||
.finally(() => setLoading(false));
|
||||
}, [bucket, mailbox]);
|
||||
|
||||
if (loading) return <div className="min-h-screen flex items-center justify-center bg-gray-100">Loading...</div>;
|
||||
if (error) return <div className="min-h-screen flex items-center justify-center bg-gray-100 text-red-500">{error}</div>;
|
||||
|
||||
const handleResendAll = async () => {
|
||||
const auth = localStorage.getItem('auth');
|
||||
if (!auth) return setMessage('Not authenticated');
|
||||
|
||||
const response = await fetch('/api/resend-domain', {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Basic ${auth}`, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ bucket }),
|
||||
});
|
||||
const res = await response.json();
|
||||
setMessage(res.message || res.error);
|
||||
};
|
||||
|
||||
const handleUpdateProcessed = async (key: string, newValue: boolean) => {
|
||||
const auth = localStorage.getItem('auth');
|
||||
if (!auth) return;
|
||||
|
||||
await fetch('/api/email', {
|
||||
method: 'PUT',
|
||||
headers: { Authorization: `Basic ${auth}`, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ bucket, key, processed: newValue ? 'true' : 'false' }),
|
||||
});
|
||||
setEmails(emails.map(em => em.key === key ? { ...em, processed: newValue ? 'true' : 'false' } : em));
|
||||
};
|
||||
|
||||
const handleResend = async (key: string) => {
|
||||
const auth = localStorage.getItem('auth');
|
||||
if (!auth) return alert('Not authenticated');
|
||||
|
||||
const response = await fetch('/api/email', {
|
||||
method: 'POST',
|
||||
headers: { Authorization: `Basic ${auth}`, 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ bucket, key }),
|
||||
});
|
||||
const res = await response.json();
|
||||
alert(res.message || res.error);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-gray-100 p-8">
|
||||
<h1 className="text-3xl font-bold mb-6 text-center">Emails for {mailbox} in {bucket}</h1>
|
||||
<div className="flex justify-center mb-6">
|
||||
<button
|
||||
onClick={handleResendAll}
|
||||
className="bg-green-500 text-white px-6 py-3 rounded hover:bg-green-600 transition"
|
||||
>
|
||||
Resend all unprocessed
|
||||
</button>
|
||||
</div>
|
||||
{message && <p className="text-center mb-4 text-blue-500">{message}</p>}
|
||||
<div className="overflow-x-auto max-w-4xl mx-auto bg-white rounded-lg shadow-md">
|
||||
<table className="min-w-full divide-y divide-gray-200">
|
||||
<thead className="bg-gray-50">
|
||||
<tr>
|
||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Subject</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Date</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Processed</th>
|
||||
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="bg-white divide-y divide-gray-200">
|
||||
{emails.map((e: Email) => (
|
||||
<tr key={e.key} className="hover:bg-gray-50 transition">
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">{e.subject}</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">{e.date}</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={e.processed === 'true'}
|
||||
onChange={() => handleUpdateProcessed(e.key, e.processed !== 'true')}
|
||||
className="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
|
||||
/>
|
||||
</td>
|
||||
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
|
||||
<Link href={`/email?bucket=${bucket}&key=${e.key}`} className="text-blue-600 hover:text-blue-900 mr-4">
|
||||
View
|
||||
</Link>
|
||||
<button onClick={() => handleResend(e.key)} className="text-green-600 hover:text-green-900">
|
||||
Resend
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user