Implement multi-channel notification system with: - Core notification service with email, push, and in-app channels - Email templates for all notification types (welcome, plant registered, transport alerts, farm alerts, harvest ready, demand matches, weekly digest) - Push notification support with VAPID authentication - In-app notification management with read/unread tracking - Notification scheduler for recurring and scheduled notifications - API endpoints for notifications CRUD, preferences, and subscriptions - UI components (NotificationBell, NotificationList, NotificationItem, PreferencesForm) - Full notifications page with preferences management - Service worker for push notification handling
90 lines
2.3 KiB
TypeScript
90 lines
2.3 KiB
TypeScript
/**
|
|
* API: Notifications List Endpoint
|
|
* GET /api/notifications - Get user notifications
|
|
* POST /api/notifications - Send a notification
|
|
*/
|
|
|
|
import type { NextApiRequest, NextApiResponse } from 'next';
|
|
import { getNotificationService } from '../../../lib/notifications';
|
|
|
|
export default async function handler(
|
|
req: NextApiRequest,
|
|
res: NextApiResponse
|
|
) {
|
|
const notificationService = getNotificationService();
|
|
|
|
if (req.method === 'GET') {
|
|
try {
|
|
// In production, get userId from session/auth
|
|
const userId = req.query.userId as string || 'demo-user';
|
|
const unreadOnly = req.query.unreadOnly === 'true';
|
|
const type = req.query.type as string;
|
|
const limit = parseInt(req.query.limit as string) || 50;
|
|
const offset = parseInt(req.query.offset as string) || 0;
|
|
|
|
const notifications = notificationService.getUserNotifications(userId, {
|
|
unreadOnly,
|
|
type: type as any,
|
|
limit,
|
|
offset
|
|
});
|
|
|
|
const unreadCount = notificationService.getUnreadCount(userId);
|
|
|
|
return res.status(200).json({
|
|
success: true,
|
|
data: {
|
|
notifications,
|
|
unreadCount,
|
|
pagination: {
|
|
limit,
|
|
offset,
|
|
hasMore: notifications.length === limit
|
|
}
|
|
}
|
|
});
|
|
} catch (error: any) {
|
|
return res.status(500).json({
|
|
success: false,
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
if (req.method === 'POST') {
|
|
try {
|
|
const { recipientId, email, title, message, type, channels, priority, actionUrl, data } = req.body;
|
|
|
|
if (!recipientId || !title || !message) {
|
|
return res.status(400).json({
|
|
success: false,
|
|
error: 'Missing required fields: recipientId, title, message'
|
|
});
|
|
}
|
|
|
|
const notification = await notificationService.send(
|
|
{ userId: recipientId, email },
|
|
{
|
|
type: type || 'system_alert',
|
|
title,
|
|
message,
|
|
actionUrl,
|
|
data
|
|
},
|
|
{ channels, priority }
|
|
);
|
|
|
|
return res.status(201).json({
|
|
success: true,
|
|
data: notification
|
|
});
|
|
} catch (error: any) {
|
|
return res.status(500).json({
|
|
success: false,
|
|
error: error.message
|
|
});
|
|
}
|
|
}
|
|
|
|
return res.status(405).json({ error: 'Method not allowed' });
|
|
}
|