177 lines
4.7 KiB
TypeScript
177 lines
4.7 KiB
TypeScript
import { Request, Response } from 'express';
|
|
import { Notification } from '@models/Notification';
|
|
import { Op } from 'sequelize';
|
|
import logger from '@utils/logger';
|
|
|
|
export class NotificationController {
|
|
/**
|
|
* Get user's notifications with pagination
|
|
*/
|
|
async getUserNotifications(req: Request, res: Response): Promise<void> {
|
|
try {
|
|
const userId = (req as any).user?.userId;
|
|
const { page = 1, limit = 20, unreadOnly = false } = req.query;
|
|
|
|
if (!userId) {
|
|
res.status(401).json({ success: false, message: 'Unauthorized' });
|
|
return;
|
|
}
|
|
|
|
const where: any = { userId };
|
|
if (unreadOnly === 'true') {
|
|
where.isRead = false;
|
|
}
|
|
|
|
const offset = (Number(page) - 1) * Number(limit);
|
|
|
|
const { rows, count } = await Notification.findAndCountAll({
|
|
where,
|
|
order: [['createdAt', 'DESC']],
|
|
limit: Number(limit),
|
|
offset
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
data: {
|
|
notifications: rows,
|
|
pagination: {
|
|
page: Number(page),
|
|
limit: Number(limit),
|
|
total: count,
|
|
totalPages: Math.ceil(count / Number(limit))
|
|
},
|
|
unreadCount: unreadOnly === 'true' ? count : await Notification.count({ where: { userId, isRead: false } })
|
|
}
|
|
});
|
|
} catch (error: any) {
|
|
logger.error('[Notification Controller] Error fetching notifications:', error);
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get unread notification count
|
|
*/
|
|
async getUnreadCount(req: Request, res: Response): Promise<void> {
|
|
try {
|
|
const userId = (req as any).user?.userId;
|
|
|
|
if (!userId) {
|
|
res.status(401).json({ success: false, message: 'Unauthorized' });
|
|
return;
|
|
}
|
|
|
|
const count = await Notification.count({
|
|
where: { userId, isRead: false }
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
data: { unreadCount: count }
|
|
});
|
|
} catch (error: any) {
|
|
logger.error('[Notification Controller] Error fetching unread count:', error);
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Mark notification as read
|
|
*/
|
|
async markAsRead(req: Request, res: Response): Promise<void> {
|
|
try {
|
|
const userId = (req as any).user?.userId;
|
|
const { notificationId } = req.params;
|
|
|
|
if (!userId) {
|
|
res.status(401).json({ success: false, message: 'Unauthorized' });
|
|
return;
|
|
}
|
|
|
|
const notification = await Notification.findOne({
|
|
where: { notificationId, userId }
|
|
});
|
|
|
|
if (!notification) {
|
|
res.status(404).json({ success: false, message: 'Notification not found' });
|
|
return;
|
|
}
|
|
|
|
await notification.update({
|
|
isRead: true,
|
|
readAt: new Date()
|
|
});
|
|
|
|
res.json({
|
|
success: true,
|
|
message: 'Notification marked as read',
|
|
data: { notification }
|
|
});
|
|
} catch (error: any) {
|
|
logger.error('[Notification Controller] Error marking notification as read:', error);
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Mark all notifications as read
|
|
*/
|
|
async markAllAsRead(req: Request, res: Response): Promise<void> {
|
|
try {
|
|
const userId = (req as any).user?.userId;
|
|
|
|
if (!userId) {
|
|
res.status(401).json({ success: false, message: 'Unauthorized' });
|
|
return;
|
|
}
|
|
|
|
await Notification.update(
|
|
{ isRead: true, readAt: new Date() },
|
|
{ where: { userId, isRead: false } }
|
|
);
|
|
|
|
res.json({
|
|
success: true,
|
|
message: 'All notifications marked as read'
|
|
});
|
|
} catch (error: any) {
|
|
logger.error('[Notification Controller] Error marking all as read:', error);
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Delete notification
|
|
*/
|
|
async deleteNotification(req: Request, res: Response): Promise<void> {
|
|
try {
|
|
const userId = (req as any).user?.userId;
|
|
const { notificationId } = req.params;
|
|
|
|
if (!userId) {
|
|
res.status(401).json({ success: false, message: 'Unauthorized' });
|
|
return;
|
|
}
|
|
|
|
const deleted = await Notification.destroy({
|
|
where: { notificationId, userId }
|
|
});
|
|
|
|
if (deleted === 0) {
|
|
res.status(404).json({ success: false, message: 'Notification not found' });
|
|
return;
|
|
}
|
|
|
|
res.json({
|
|
success: true,
|
|
message: 'Notification deleted'
|
|
});
|
|
} catch (error: any) {
|
|
logger.error('[Notification Controller] Error deleting notification:', error);
|
|
res.status(500).json({ success: false, message: error.message });
|
|
}
|
|
}
|
|
}
|
|
|