diff --git a/src/app/board/notifications/components/notifications.table.tsx b/src/app/board/notifications/components/notifications.table.tsx
new file mode 100644
index 0000000..b0ce62c
--- /dev/null
+++ b/src/app/board/notifications/components/notifications.table.tsx
@@ -0,0 +1,102 @@
+"use client";
+
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table";
+import { Badge } from "@/components/ui/badge";
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "@/components/ui/tooltip";
+import { Notification } from "@/types/notification.types";
+import { formatDate } from "@/lib/utils";
+
+interface NotificationsTableProps {
+ notifications: Notification[];
+ isLoading: boolean;
+}
+
+export function NotificationsTable({ notifications, isLoading }: NotificationsTableProps) {
+ if (isLoading) {
+ return (
+
+ );
+ }
+
+ if (notifications.length === 0) {
+ return (
+
+
Aucune notification trouvée.
+
+ );
+ }
+
+ return (
+
+
+
+
+ Message
+ Status
+ Cours
+ Date
+ Destinataire
+
+
+
+ {notifications.map((notification) => (
+
+ {notification.message}
+
+
+
+
+
+
+
+ {notification.emargement.classSession.course.name}
+
+
+
+
Date: {formatDate(notification.emargement.classSession.date)}
+
Début: {notification.emargement.classSession.heureDebut}
+
Fin: {notification.emargement.classSession.heureFin}
+
+
+
+
+
+ {formatDate(notification.createdAt)}
+ {notification.recipient.name}
+
+ ))}
+
+
+
+ );
+}
+
+function StatusBadge({ status }: { status: Notification["status"] }) {
+ const variant = {
+ SENT: "default",
+ READ: "success",
+ DELETED: "destructive",
+ }[status];
+
+ const label = {
+ SENT: "Envoyé",
+ READ: "Lu",
+ DELETED: "Supprimé",
+ }[status];
+
+ return {label};
+}
diff --git a/src/app/board/notifications/page.tsx b/src/app/board/notifications/page.tsx
new file mode 100644
index 0000000..48afcdd
--- /dev/null
+++ b/src/app/board/notifications/page.tsx
@@ -0,0 +1,80 @@
+"use client";
+
+import { AppSidebar } from "@/components/shared/navigation/app.sidebar";
+import UserDropdown from "@/components/shared/navigation/user.dropdown";
+import FeedbackDialog from "@/components/shared/others/feedback.dialog";
+import { ModeToggle } from "@/components/shared/theme/mode-toggle";
+import {
+ Breadcrumb,
+ BreadcrumbItem,
+ BreadcrumbLink,
+ BreadcrumbList,
+ BreadcrumbPage,
+ BreadcrumbSeparator,
+} from "@/components/ui/breadcrumb";
+import { Separator } from "@/components/ui/separator";
+import { SidebarInset, SidebarProvider, SidebarTrigger } from "@/components/ui/sidebar";
+import { useNotificationsQuery } from "@/hooks/queries/use-notification.query";
+import { RiBellLine, RiScanLine } from "@remixicon/react";
+import { NotificationsTable } from "./components/notifications.table";
+import { PiBellDuotone, PiBuildingsDuotone } from "react-icons/pi";
+
+
+
+
+export default function NotificationsPage() {
+ const { data: notifications = [], isLoading } = useNotificationsQuery();
+
+ return (
+
+
+
+
+
+ {/* Page intro */}
+
+
+
+
+ Notifications
+
+
Gérez vos notifications liées aux émargements de cours.
+
+
+
+ {/* Table */}
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/config/navigation-items.tsx b/src/config/navigation-items.tsx
index 651f0b4..5e6b8a3 100644
--- a/src/config/navigation-items.tsx
+++ b/src/config/navigation-items.tsx
@@ -10,6 +10,7 @@ import {
PiGearDuotone,
PiHouseDuotone,
PiUserDuotone,
+ PiBellDuotone,
} from "react-icons/pi";
import { routes } from "./routes";
diff --git a/src/config/routes.ts b/src/config/routes.ts
index a17dc26..b22e2cd 100644
--- a/src/config/routes.ts
+++ b/src/config/routes.ts
@@ -9,8 +9,7 @@ export const routes = {
home: "/board",
users: "/board/users",
profile: "/board/profile",
- settings: "/board/settings",
- academicYears: "/board/academic-years",
+ settings: "/board/settings", academicYears: "/board/academic-years",
organizations: "/board/organizations",
attendance: "/board/attendance",
attendanceAdmin: "/board/attendance-admin",
@@ -19,5 +18,6 @@ export const routes = {
programs: "/board/programs",
universities: "/board/universities",
classSessions: "/board/class-sessions",
+ notifications: "/board/notifications",
},
};
diff --git a/src/server/services/notification.service.ts b/src/server/services/notification.service.ts
index d872328..1718b4b 100644
--- a/src/server/services/notification.service.ts
+++ b/src/server/services/notification.service.ts
@@ -49,80 +49,4 @@ export class NotificationService {
return data;
} catch (error) {
console.error(`Erreur lors de la récupération de la notification ${id}:`, error);
- throw new Error("Impossible de récupérer les détails de la notification");
- }
- }
-
- /**
- * Créer une nouvelle notification
- */
- static async createNotification(input: CreateNotificationDto): Promise {
- try {
- const token = getAuthToken();
- if (!token) {
- throw new Error("Vous devez être connecté pour accéder à cette ressource");
- }
-
- const { data } = await api.post(`/api/v1/notifications`, input, {
- headers: {
- Authorization: `Bearer ${token}`,
- },
- });
-
- return data;
- } catch (error) {
- console.error("Erreur lors de la création de la notification:", error);
- throw new Error("Impossible de créer la notification");
- }
- }
-
- /**
- * Mettre à jour le statut d'une notification
- */
- static async updateNotificationStatus(id: string, status: string): Promise {
- try {
- const token = getAuthToken();
- if (!token) {
- throw new Error("Vous devez être connecté pour accéder à cette ressource");
- }
-
- await api.put(
- `/api/v1/notifications/${id}`,
- { status },
- {
- headers: {
- Authorization: `Bearer ${token}`,
- },
- }
- );
-
- return true;
- } catch (error) {
- console.error(`Erreur lors de la mise à jour du statut de la notification ${id}:`, error);
- throw new Error("Impossible de mettre à jour le statut de la notification");
- }
- }
-
- /**
- * Récupérer les notifications non lues pour un utilisateur
- */
- static async getUnreadNotifications(): Promise {
- try {
- const token = getAuthToken();
- if (!token) {
- throw new Error("Vous devez être connecté pour accéder à cette ressource");
- }
-
- const { data } = await api.get(`/api/v1/notifications?status=SENT`, {
- headers: {
- Authorization: `Bearer ${token}`,
- },
- });
-
- return data.items || data;
- } catch (error) {
- console.error("Erreur lors de la récupération des notifications non lues:", error);
- throw new Error("Impossible de récupérer les notifications non lues");
- }
- }
-}
+ throw new Error("Impossible de récupérer les détails d
diff --git a/src/types/attendance.types.ts b/src/types/attendance.types.ts
index 8348e77..ca26c51 100644
--- a/src/types/attendance.types.ts
+++ b/src/types/attendance.types.ts
@@ -1,12 +1,31 @@
import { AcademicYear } from "./academic-year.types";
import { User } from "./user.types";
+import { Course } from "./course.types"
+import { AcademicYear } from "./academic-year.types"
+import { User } from "./user.types"
+
+export interface ClassSession {
+ id: string;
+ date: string;
+ heureDebut: string;
+ heureFin: string;
+ academicYear: AcademicYear;
+ course: Course;
+ professor: User;
+ classRepresentative: User;
+ createdAt: string;
+ updatedAt: string;
+}
+
export interface Attendance {
id: string;
professorId: string;
courseId: string;
date: string;
status: "PRESENT" | "ABSENT" | "LATE";
+ classSession: ClassSession;
+ professor: User;
comments?: string;
createdAt: string;
updatedAt: string;
@@ -31,14 +50,6 @@ export interface UpdateAttendanceInput {
comments?: string;
}
-export interface Course {
- id: string;
- title: string;
- startTime: string;
- endTime: string;
- location: string;
- hasAttendance: boolean;
-}
export interface ClassSession {
id: string;
@@ -101,3 +112,4 @@ export interface UpdateEmargementInput {
id: string;
status?: "PENDING" | "PRESENT" | "ABSENT" | "SUPERVISOR_CONFIRMED" | "CLASS_HEADER_CONFIRMED";
}
+
\ No newline at end of file
diff --git a/src/types/notification.types.ts b/src/types/notification.types.ts
index 2751deb..aca3f9a 100644
--- a/src/types/notification.types.ts
+++ b/src/types/notification.types.ts
@@ -1,10 +1,12 @@
import { Emargement } from "./attendance.types";
import { User } from "./user.types";
+export type NotificationStatus = "SENT" | "CONFIRMED" | "RECEIVED" | "READ" | "DELETED";
+
export interface Notification {
id: string;
message: string;
- status: "SENT" | "CONFIRMED" | "RECEIVED" | "READ";
+ status: NotificationStatus;
emargement?: Emargement;
recipient: User;
createdAt: string;
@@ -13,13 +15,13 @@ export interface Notification {
export interface CreateNotificationDto {
message: string;
- status: "SENT" | "CONFIRMED" | "RECEIVED" | "READ";
+ status: NotificationStatus;
emargementId: string;
recipientId: string;
}
export interface UpdateNotificationDto {
id: string;
- status?: "SENT" | "CONFIRMED" | "RECEIVED" | "READ";
+ status?: NotificationStatus;
message?: string;
}