diff --git a/app/api/emails/route.ts b/app/api/emails/route.ts new file mode 100644 index 00000000..b56a61ee --- /dev/null +++ b/app/api/emails/route.ts @@ -0,0 +1,80 @@ +import { NextRequest, NextResponse } from "next/server"; +import { getServerSession } from "next-auth/next"; +import { authOptions } from "@/app/api/auth/[...nextauth]/route"; + +export async function GET(req: NextRequest) { + try { + const session = await getServerSession(authOptions); + + if (!session?.user?.email || !session.accessToken) { + return NextResponse.json( + { error: "Non authentifié" }, + { status: 401 } + ); + } + + // Get Nextcloud base URL from environment variable + const nextcloudUrl = process.env.NEXTCLOUD_URL; + if (!nextcloudUrl) { + throw new Error("NEXTCLOUD_URL not configured"); + } + + // Fetch unread messages from Nextcloud Mail API using OIDC token + const response = await fetch(`${nextcloudUrl}/apps/mail/api/v1/messages?filter=unseen`, { + headers: { + 'Authorization': `Bearer ${session.accessToken}`, + 'Accept': 'application/json', + 'OCS-APIRequest': 'true', + 'Content-Type': 'application/json', + }, + }); + + if (!response.ok) { + console.error('Failed to fetch emails:', { + status: response.status, + statusText: response.statusText + }); + + // If token is expired or invalid, return 401 + if (response.status === 401) { + return NextResponse.json( + { error: "Session expirée" }, + { status: 401 } + ); + } + + throw new Error('Failed to fetch emails from Nextcloud'); + } + + const data = await response.json(); + console.log('Nextcloud mail response:', { + status: response.status, + dataLength: data?.ocs?.data?.length || 0 + }); + + // Transform the response to match our Email interface + const emails = (data?.ocs?.data || []).map((email: any) => ({ + id: email.id, + subject: email.subject || '(No subject)', + sender: { + name: email.from?.name || email.from?.email || 'Unknown', + email: email.from?.email || '', + }, + date: email.sentDate, + isUnread: true, // Since we're only fetching unread messages + })); + + // Sort by date (newest first) and limit to 5 messages + const sortedEmails = emails + .sort((a: any, b: any) => new Date(b.date).getTime() - new Date(a.date).getTime()) + .slice(0, 5); + + return NextResponse.json(sortedEmails); + } catch (error) { + console.error('Error fetching emails:', error); + return NextResponse.json( + { error: "Erreur lors de la récupération des emails" }, + { status: 500 } + ); + } +} \ No newline at end of file diff --git a/components/email.tsx b/components/email.tsx index 5bef9213..6b9065d4 100644 --- a/components/email.tsx +++ b/components/email.tsx @@ -4,7 +4,9 @@ import { useEffect, useState } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { RefreshCw, Mail } from "lucide-react"; -import { useSession } from "next-auth/react"; +import { useSession, signIn } from "next-auth/react"; +import { format, formatDistance } from "date-fns"; +import { fr } from "date-fns/locale/fr"; interface Email { id: string; @@ -26,37 +28,24 @@ export function Email() { const fetchEmails = async (isRefresh = false) => { if (isRefresh) setRefreshing(true); - setLoading(true); - - // Placeholder data - replace with actual API call - const mockEmails = [ - { - id: '1', - subject: 'Project Update: Q1 Milestones', - sender: { name: 'Project Manager', email: 'pm@example.com' }, - date: '2024-03-20 09:30', - isUnread: true - }, - { - id: '2', - subject: 'Team Meeting Notes', - sender: { name: 'Team Lead', email: 'lead@example.com' }, - date: '2024-03-19 15:45', - isUnread: false - }, - { - id: '3', - subject: 'Important: System Maintenance', - sender: { name: 'IT Support', email: 'it@example.com' }, - date: '2024-03-19 11:20', - isUnread: true - }, - ]; + if (!isRefresh) setLoading(true); try { - // Simulate API call - await new Promise(resolve => setTimeout(resolve, 1000)); - setEmails(mockEmails); + const response = await fetch('/api/emails'); + if (!response.ok) { + const data = await response.json(); + + // Handle session expiration + if (response.status === 401) { + signIn(); // Redirect to login + return; + } + + throw new Error(data.error || 'Failed to fetch emails'); + } + + const data = await response.json(); + setEmails(data); setError(null); } catch (err) { setError('Failed to fetch emails'); @@ -67,20 +56,52 @@ export function Email() { } }; + // Initial fetch useEffect(() => { if (status === 'authenticated') { fetchEmails(); } }, [status]); + // Auto-refresh every 5 minutes + useEffect(() => { + if (status !== 'authenticated') return; + + const interval = setInterval(() => { + fetchEmails(true); + }, 5 * 60 * 1000); + + return () => clearInterval(interval); + }, [status]); + + const formatDate = (dateString: string) => { + try { + const date = new Date(dateString); + return formatDistance(date, new Date(), { + addSuffix: true, + locale: fr + }); + } catch (err) { + console.error('Error formatting date:', err); + return dateString; + } + }; + if (status === 'loading' || loading) { return ( - Email + +
+ + Emails non lus +
+
-

Loading...

+
+ +
); @@ -89,7 +110,12 @@ export function Email() { return ( - Email + +
+ + Emails non lus +
+