mirror of
https://github.com/clucraft/PriceGhost.git
synced 2026-05-12 09:12:40 +02:00
Add notification history feature with bell icon and history page
- Add notification_history database table for logging all triggered notifications - Create API endpoints for fetching recent and historical notifications - Add NotificationBell component in navbar with badge showing recent count - Dropdown shows 5 most recent notifications with links to products - Create full NotificationHistory page with filtering by notification type - Log notifications when sent: price drops, target prices, back-in-stock - Track which channels (telegram, discord, pushover, ntfy) received each notification - Update sendNotifications to return which channels succeeded - Bump version to 1.0.3 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
45363e4d97
commit
63fcaebfd8
12 changed files with 1244 additions and 16 deletions
72
backend/src/routes/notifications.ts
Normal file
72
backend/src/routes/notifications.ts
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import { Router, Response } from 'express';
|
||||
import { authMiddleware, AuthRequest } from '../middleware/auth';
|
||||
import { notificationHistoryQueries } from '../models';
|
||||
|
||||
const router = Router();
|
||||
|
||||
// All routes require authentication
|
||||
router.use(authMiddleware);
|
||||
|
||||
// Get recent notifications (for bell dropdown)
|
||||
router.get('/recent', async (req: AuthRequest, res: Response) => {
|
||||
try {
|
||||
const userId = req.userId!;
|
||||
const limit = Math.min(parseInt(req.query.limit as string) || 10, 20);
|
||||
|
||||
const notifications = await notificationHistoryQueries.getRecent(userId, limit);
|
||||
const recentCount = await notificationHistoryQueries.countRecent(userId, 24);
|
||||
|
||||
res.json({
|
||||
notifications,
|
||||
recentCount,
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching recent notifications:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch notifications' });
|
||||
}
|
||||
});
|
||||
|
||||
// Get notification history with pagination
|
||||
router.get('/history', async (req: AuthRequest, res: Response) => {
|
||||
try {
|
||||
const userId = req.userId!;
|
||||
const page = parseInt(req.query.page as string) || 1;
|
||||
const limit = Math.min(parseInt(req.query.limit as string) || 20, 100);
|
||||
const offset = (page - 1) * limit;
|
||||
|
||||
const [notifications, totalCount] = await Promise.all([
|
||||
notificationHistoryQueries.getByUserId(userId, limit, offset),
|
||||
notificationHistoryQueries.getTotalCount(userId),
|
||||
]);
|
||||
|
||||
res.json({
|
||||
notifications,
|
||||
pagination: {
|
||||
page,
|
||||
limit,
|
||||
totalCount,
|
||||
totalPages: Math.ceil(totalCount / limit),
|
||||
},
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Error fetching notification history:', error);
|
||||
res.status(500).json({ error: 'Failed to fetch notification history' });
|
||||
}
|
||||
});
|
||||
|
||||
// Get count of recent notifications (for badge)
|
||||
router.get('/count', async (req: AuthRequest, res: Response) => {
|
||||
try {
|
||||
const userId = req.userId!;
|
||||
const hours = parseInt(req.query.hours as string) || 24;
|
||||
|
||||
const count = await notificationHistoryQueries.countRecent(userId, hours);
|
||||
|
||||
res.json({ count });
|
||||
} catch (error) {
|
||||
console.error('Error counting notifications:', error);
|
||||
res.status(500).json({ error: 'Failed to count notifications' });
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
||||
Loading…
Add table
Add a link
Reference in a new issue