mail page imap connection 2
This commit is contained in:
parent
4836353591
commit
ea4de624eb
@ -6,12 +6,25 @@ import { simpleParser } from 'mailparser';
|
||||
const imapConfig = {
|
||||
user: 'contact@governance-labs.org',
|
||||
password: 'K!376c$6H#kMknM',
|
||||
host: 'mail.governance-labs.org',
|
||||
host: 'mail.infomniak.com',
|
||||
port: 993,
|
||||
tls: true,
|
||||
tlsOptions: { rejectUnauthorized: false }
|
||||
};
|
||||
|
||||
interface ImapMessage {
|
||||
header: {
|
||||
from: string[];
|
||||
to: string[];
|
||||
subject: string[];
|
||||
date: string[];
|
||||
};
|
||||
body: string;
|
||||
attributes: {
|
||||
flags: string[];
|
||||
};
|
||||
}
|
||||
|
||||
// Helper function to create a promise-based IMAP connection
|
||||
function createImapConnection() {
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -24,7 +37,7 @@ function createImapConnection() {
|
||||
}
|
||||
|
||||
// Helper function to promisify the message fetching
|
||||
function fetchMessages(imap: Imap, box: string) {
|
||||
function fetchMessages(imap: Imap, box: string): Promise<ImapMessage[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
imap.openBox(box, false, (err, mailbox) => {
|
||||
if (err) {
|
||||
@ -50,10 +63,10 @@ function fetchMessages(imap: Imap, box: string) {
|
||||
struct: true
|
||||
});
|
||||
|
||||
const messages: any[] = [];
|
||||
const messages: ImapMessage[] = [];
|
||||
|
||||
fetch.on('message', (msg) => {
|
||||
const message: any = {};
|
||||
const message: Partial<ImapMessage> = {};
|
||||
|
||||
msg.on('body', (stream, info) => {
|
||||
let buffer = '';
|
||||
@ -74,7 +87,7 @@ function fetchMessages(imap: Imap, box: string) {
|
||||
});
|
||||
|
||||
msg.once('end', () => {
|
||||
messages.push(message);
|
||||
messages.push(message as ImapMessage);
|
||||
});
|
||||
});
|
||||
|
||||
@ -96,7 +109,7 @@ export async function GET(request: Request) {
|
||||
const messages = await fetchMessages(imap, 'INBOX');
|
||||
|
||||
// Process messages into the format expected by the frontend
|
||||
const processedMessages = messages.map((msg: any, index: number) => ({
|
||||
const processedMessages = messages.map((msg: ImapMessage, index: number) => ({
|
||||
id: index + 1,
|
||||
accountId: 1,
|
||||
from: msg.header.from[0],
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
import { Card } from "@/components/ui/card"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Input } from "@/components/ui/input"
|
||||
import { Mail, Search, Star, Inbox, Send, Archive, Trash } from "lucide-react"
|
||||
import { Mail, Search, Star, Inbox, Send, Archive, Trash, AlertCircle } from "lucide-react"
|
||||
import { useState, useEffect } from "react"
|
||||
|
||||
interface Email {
|
||||
@ -23,16 +23,23 @@ interface Email {
|
||||
export default function MailPage() {
|
||||
const [emails, setEmails] = useState<Email[]>([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
async function fetchEmails() {
|
||||
try {
|
||||
setError(null)
|
||||
const res = await fetch('/api/mail')
|
||||
if (!res.ok) throw new Error('Failed to fetch emails')
|
||||
if (!res.ok) {
|
||||
const errorData = await res.json().catch(() => ({}))
|
||||
throw new Error(errorData.error || 'Failed to fetch emails')
|
||||
}
|
||||
const data = await res.json()
|
||||
setEmails(data.messages)
|
||||
setEmails(data.messages || [])
|
||||
} catch (error) {
|
||||
console.error('Error fetching emails:', error)
|
||||
setError('Unable to connect to mail server. Please try again later.')
|
||||
setEmails([])
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
@ -96,39 +103,61 @@ export default function MailPage() {
|
||||
<div className="flex items-center justify-center h-full">
|
||||
<p className="text-gray-500">Loading emails...</p>
|
||||
</div>
|
||||
) : error ? (
|
||||
<div className="flex flex-col items-center justify-center h-full text-center">
|
||||
<AlertCircle className="h-12 w-12 text-yellow-500 mb-4" />
|
||||
<p className="text-gray-600 mb-2">{error}</p>
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => {
|
||||
setLoading(true)
|
||||
setError(null)
|
||||
fetchEmails()
|
||||
}}
|
||||
>
|
||||
Try Again
|
||||
</Button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
{emails.map((email) => (
|
||||
<Card key={email.id} className={`p-4 hover:bg-gray-50 cursor-pointer ${!email.read ? 'bg-blue-50' : ''}`}>
|
||||
<div className="flex items-center gap-4">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-4 w-4 p-0"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
// TODO: Implement star functionality
|
||||
}}
|
||||
>
|
||||
<Star className={`h-4 w-4 ${email.starred ? 'fill-yellow-400 text-yellow-400' : 'text-gray-400'}`} />
|
||||
</Button>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="font-medium truncate">{email.fromName}</p>
|
||||
<span className="text-sm text-gray-500">
|
||||
{new Date(email.date).toLocaleDateString()}
|
||||
</span>
|
||||
{emails.length === 0 ? (
|
||||
<div className="flex flex-col items-center justify-center h-[calc(100vh-12rem)] text-center">
|
||||
<Mail className="h-12 w-12 text-gray-400 mb-4" />
|
||||
<p className="text-gray-600">No emails found</p>
|
||||
</div>
|
||||
) : (
|
||||
emails.map((email) => (
|
||||
<Card key={email.id} className={`p-4 hover:bg-gray-50 cursor-pointer ${!email.read ? 'bg-blue-50' : ''}`}>
|
||||
<div className="flex items-center gap-4">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="h-4 w-4 p-0"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
// TODO: Implement star functionality
|
||||
}}
|
||||
>
|
||||
<Star className={`h-4 w-4 ${email.starred ? 'fill-yellow-400 text-yellow-400' : 'text-gray-400'}`} />
|
||||
</Button>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="font-medium truncate">{email.fromName}</p>
|
||||
<span className="text-sm text-gray-500">
|
||||
{new Date(email.date).toLocaleDateString()}
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm font-medium truncate">{email.subject}</p>
|
||||
<p className="text-sm text-gray-500 truncate">{email.body}</p>
|
||||
</div>
|
||||
<p className="text-sm font-medium truncate">{email.subject}</p>
|
||||
<p className="text-sm text-gray-500 truncate">{email.body}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</Card>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user