mediahub-fe/app/[locale]/(protected)/notifications/components/notifications-table.tsx

139 lines
4.0 KiB
TypeScript

"use client";
import React, { useState, useEffect } from "react";
import { Button } from "@/components/ui/button";
import { getNotifications } from "@/service/notifications/notifications";
import {
CalendarCheck,
CheckCheck,
ChevronLeft,
ChevronRight,
CircleAlert,
Clock7,
MessageCircle,
SquareCheck,
UploadIcon,
} from "lucide-react";
import { useRouter } from "next/navigation";
export type Notification = {
id: number;
notificationTypeId: number;
message: string;
createdAt: string;
isActive: boolean;
isPublic: boolean;
isRead: boolean;
redirectUrl: string;
userGroupIdDst: string | null;
userIdDst: string | null;
userLevelIdDst: string;
userLevelNumberDst: string | null;
userRoleIdDst: string;
};
const getNotificationIcon = (notificationTypeId: number) => {
switch (notificationTypeId) {
case 2:
return <MessageCircle className="h-8 w-8 text-success" />;
case 3:
return <UploadIcon className="h-5 w-5 text-warning" />;
case 4:
return <CheckCheck className="h-5 w-5 text-primary" />;
case 5:
return <SquareCheck className="h-5 w-5 text-warning" />;
case 6:
return <CalendarCheck className="h-5 w-5 text-danger" />;
case 7:
return <CircleAlert className="h-5 w-5 text-danger" />;
case 8:
return <Clock7 className="h-5 w-5 text-danger" />;
default:
return <SquareCheck className="h-5 w-5 text-danger" />;
}
};
const NotificationsList: React.FC = () => {
const router = useRouter();
const [notifications, setNotifications] = useState<Notification[]>([]);
const [totalData, setTotalData] = useState<number>(0);
const [page, setPage] = useState<number>(1);
const [pageSize] = useState<number>(10);
const [totalPage, setTotalPage] = useState<number>(1);
useEffect(() => {
async function fetchNotifications() {
const response = await getNotifications(page - 1, pageSize);
setNotifications(response.data?.data?.content || []);
setTotalData(response.data?.data?.totalElements || 0);
setTotalPage(response.data?.data?.totalPages);
}
fetchNotifications();
}, [page, pageSize]);
const handleNotificationClick = (redirectUrl: string) => {
router.push(redirectUrl);
};
const handlePageChange = (newPage: number) => {
setPage(newPage);
};
return (
<div className="mx-3">
<div className="space-y-3">
{notifications.length > 0 ? (
notifications.map((notification) => (
<div
key={notification.id}
className="flex items-start space-x-4 p-4 border rounded-lg shadow-sm bg-white cursor-pointer"
onClick={() => handleNotificationClick(notification.redirectUrl)}
>
<div className="flex-shrink-0">
<div className="flex-none">
{getNotificationIcon(notification.notificationTypeId)}
</div>
</div>
<div>
<p className="text-sm font-medium">{notification.message}</p>
<p className="text-xs text-gray-500">
{new Date(notification.createdAt).toLocaleString()}
</p>
</div>
</div>
))
) : (
<p className="text-gray-500 text-sm">Tidak ada notifikasi.</p>
)}
</div>
{/* Pagination */}
<div className="flex justify-end items-center mt-6 gap-3 mb-3">
<Button
onClick={() => handlePageChange(page - 1)}
disabled={page === 1}
variant="outline"
className="rounded-full"
size="sm"
>
<ChevronLeft size={20} />
</Button>
<p className="text-sm">
Page {page} of {totalPage}
</p>
<Button
onClick={() => handlePageChange(page + 1)}
disabled={page === totalPage}
variant="outline"
className="rounded-full"
size="sm"
>
<ChevronRight size={20} />
</Button>
</div>
</div>
);
};
export default NotificationsList;