diff --git a/app/email/page.tsx b/app/email/page.tsx
new file mode 100644
index 00000000..27daeca8
--- /dev/null
+++ b/app/email/page.tsx
@@ -0,0 +1,23 @@
+import { getServerSession } from "next-auth/next";
+import { authOptions } from "@/app/api/auth/[...nextauth]/route";
+import { redirect } from "next/navigation";
+import { ResponsiveIframe } from "@/app/components/responsive-iframe";
+
+export default async function Page() {
+ const session = await getServerSession(authOptions);
+
+ if (!session) {
+ redirect("/signin");
+ }
+
+ return (
+
+
+
+
+
+ );
+}
\ No newline at end of file
diff --git a/app/page.tsx b/app/page.tsx
index 8f3384b4..2bf7c383 100644
--- a/app/page.tsx
+++ b/app/page.tsx
@@ -1,31 +1,60 @@
"use client";
+import { QuoteCard } from "@/components/quote-card";
+import { Calendar } from "@/components/calendar";
import { News } from "@/components/news";
import { Duties } from "@/components/flow";
+import { Email } from "@/components/email";
import { Parole } from "@/components/parole";
import { useSession } from "next-auth/react";
import { useEffect, useState } from "react";
export default function Home() {
- const { data: session } = useSession();
+ const { data: session, status } = useSession();
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
- if (session) {
+ if (status !== "loading") {
setIsLoading(false);
}
- }, [session]);
+ }, [status]);
if (isLoading) {
- return
Loading...
;
+ return (
+
+
+
+ );
}
return (
-
-
-
-
-
+
+
+ {/* First row */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Second row */}
+
);
diff --git a/components/email.tsx b/components/email.tsx
new file mode 100644
index 00000000..b91ca50b
--- /dev/null
+++ b/components/email.tsx
@@ -0,0 +1,192 @@
+"use client";
+
+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 { formatDistance } from 'date-fns/formatDistance';
+import { fr } from 'date-fns/locale/fr';
+import { useRouter } from "next/navigation";
+
+interface Email {
+ id: string;
+ subject: string;
+ from: string;
+ fromName?: string;
+ date: string;
+ read: boolean;
+ starred: boolean;
+ folder: string;
+}
+
+interface EmailResponse {
+ emails: Email[];
+ mailUrl: string;
+ error?: string;
+}
+
+export function Email() {
+ const [emails, setEmails] = useState
([]);
+ const [mailUrl, setMailUrl] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState(null);
+ const [refreshing, setRefreshing] = useState(false);
+ const { data: session, status } = useSession();
+ const router = useRouter();
+
+ const fetchEmails = async (isRefresh = false) => {
+ if (status !== 'authenticated') {
+ setError('Please sign in to view emails');
+ setLoading(false);
+ setRefreshing(false);
+ return;
+ }
+
+ if (isRefresh) setRefreshing(true);
+ if (!isRefresh) setLoading(true);
+
+ try {
+ const response = await fetch('/api/mail');
+
+ if (!response.ok) {
+ const errorData = await response.json();
+ throw new Error(errorData.error || 'Failed to fetch emails');
+ }
+
+ const data = await response.json();
+
+ if (data.error) {
+ throw new Error(data.error);
+ }
+
+ const validatedEmails = data.emails.map((email: any) => ({
+ id: email.id || Date.now().toString(),
+ subject: email.subject || '(No subject)',
+ from: email.from || '',
+ fromName: email.fromName || email.from?.split('@')[0] || 'Unknown',
+ date: email.date || new Date().toISOString(),
+ read: !!email.read,
+ starred: !!email.starred,
+ folder: email.folder || 'INBOX'
+ }));
+
+ setEmails(validatedEmails);
+ setMailUrl(data.mailUrl || 'https://espace.slm-lab.net/apps/mail/');
+ setError(null);
+ } catch (err) {
+ setError(err instanceof Error ? err.message : 'Error fetching emails');
+ setEmails([]);
+ } finally {
+ setLoading(false);
+ setRefreshing(false);
+ }
+ };
+
+ // Initial fetch
+ useEffect(() => {
+ if (status === 'authenticated') {
+ fetchEmails();
+ } else if (status === 'unauthenticated') {
+ setError('Please sign in to view emails');
+ setLoading(false);
+ }
+ }, [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) {
+ return dateString;
+ }
+ };
+
+ if (status === 'loading' || loading) {
+ return (
+
+
+
+
+
+ Mail
+
+
+
+
+
+
+
+
+
+ );
+ }
+
+ return (
+
+
+
+
+
+ Mail
+
+
+
+
+
+ {error ? (
+ {error}
+ ) : (
+
+ {emails.length === 0 ? (
+
+ {loading ? 'Loading emails...' : 'No unread emails'}
+
+ ) : (
+ emails.map((email) => (
+
router.push('/mail')}
+ >
+
+
+ {email.fromName || email.from}
+
+
+ {!email.read && }
+ {formatDate(email.date)}
+
+
+
{email.subject}
+
+ ))
+ )}
+
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/components/main-nav.tsx b/components/main-nav.tsx
index a6c06684..303c36cb 100644
--- a/components/main-nav.tsx
+++ b/components/main-nav.tsx
@@ -21,7 +21,6 @@ import {
Lightbulb,
Circle,
Menu,
- Activity,
} from "lucide-react";
import Image from "next/image";
import Link from "next/link";
@@ -181,29 +180,29 @@ export function MainNav() {
// Role-specific menu items
const roleSpecificItems = [
{
- title: 'HealthView',
- href: '/healthview',
- icon: Activity,
- roles: ['admin', 'user']
+ title: "ShowCase",
+ icon: Lightbulb,
+ href: '/showcase',
+ requiredRoles: ["Expression"],
},
{
- title: 'MissionView',
- href: '/missionview',
- icon: Target,
- roles: ['admin', 'user']
+ title: "UsersView",
+ icon: UserCog,
+ href: '/management',
+ requiredRoles: ["Admin", "Entrepreneurship"],
},
{
- title: 'Announcement',
- href: '/announcement',
- icon: Megaphone,
- roles: ['admin', 'user']
- }
+ title: "TheMessage",
+ icon: Mail,
+ href: '/the-message',
+ requiredRoles: ["Mediation", "Expression"],
+ },
];
// Get visible menu items based on user roles
const visibleMenuItems = [
...baseMenuItems,
- ...roleSpecificItems.filter(item => hasRole(item.roles))
+ ...roleSpecificItems.filter(item => hasRole(item.requiredRoles))
];
// Format current date and time