feat: add in-app notification system with real-time delivery
Introduces a full in-app notification system with three types (simple, boolean with server-side callbacks, navigate), three scopes (user, trip, admin), fan-out persistence per recipient, and real-time push via WebSocket. Includes a notification bell in the navbar, dropdown, dedicated /notifications page, and a dev-only admin tab for testing all notification variants. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -184,6 +184,8 @@ export const adminApi = {
|
||||
getPermissions: () => apiClient.get('/admin/permissions').then(r => r.data),
|
||||
updatePermissions: (permissions: Record<string, string>) => apiClient.put('/admin/permissions', { permissions }).then(r => r.data),
|
||||
rotateJwtSecret: () => apiClient.post('/admin/rotate-jwt-secret').then(r => r.data),
|
||||
sendTestNotification: (data: Record<string, unknown>) =>
|
||||
apiClient.post('/admin/dev/test-notification', data).then(r => r.data),
|
||||
}
|
||||
|
||||
export const addonsApi = {
|
||||
@@ -318,4 +320,23 @@ export const notificationsApi = {
|
||||
testWebhook: () => apiClient.post('/notifications/test-webhook').then(r => r.data),
|
||||
}
|
||||
|
||||
export const inAppNotificationsApi = {
|
||||
list: (params?: { limit?: number; offset?: number; unread_only?: boolean }) =>
|
||||
apiClient.get('/notifications/in-app', { params }).then(r => r.data),
|
||||
unreadCount: () =>
|
||||
apiClient.get('/notifications/in-app/unread-count').then(r => r.data),
|
||||
markRead: (id: number) =>
|
||||
apiClient.put(`/notifications/in-app/${id}/read`).then(r => r.data),
|
||||
markUnread: (id: number) =>
|
||||
apiClient.put(`/notifications/in-app/${id}/unread`).then(r => r.data),
|
||||
markAllRead: () =>
|
||||
apiClient.put('/notifications/in-app/read-all').then(r => r.data),
|
||||
delete: (id: number) =>
|
||||
apiClient.delete(`/notifications/in-app/${id}`).then(r => r.data),
|
||||
deleteAll: () =>
|
||||
apiClient.delete('/notifications/in-app/all').then(r => r.data),
|
||||
respond: (id: number, response: 'positive' | 'negative') =>
|
||||
apiClient.post(`/notifications/in-app/${id}/respond`, { response }).then(r => r.data),
|
||||
}
|
||||
|
||||
export default apiClient
|
||||
|
||||
Reference in New Issue
Block a user