feat(settings): add notification preferences and channel tests
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
All checks were successful
Deploy to Production / Trigger production update (push) Successful in 7s
Expand the Notifications settings tab: per-user preferences (channels, critical-only email, Telegram chat id + verify, webhook, quiet hours), SMTP/Telegram test buttons, a test-notification sender with channel selection, channel status, and the configured Telegram bot username. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -75,3 +75,66 @@ export function useDeleteAllRead() {
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: ['notifications'] }),
|
||||
});
|
||||
}
|
||||
|
||||
// ==================== Preferences & channels ====================
|
||||
|
||||
export interface NotificationPreferences {
|
||||
id: number;
|
||||
user_id: number;
|
||||
enabled: boolean;
|
||||
email_enabled: boolean;
|
||||
email_critical_only: boolean;
|
||||
telegram_enabled: boolean;
|
||||
telegram_chat_id: string | null;
|
||||
webhook_url: string | null;
|
||||
notification_levels: string[];
|
||||
notification_types: string[];
|
||||
quiet_hours_start: string | null;
|
||||
quiet_hours_end: string | null;
|
||||
}
|
||||
|
||||
export function useNotificationPreferences() {
|
||||
return useQuery({
|
||||
queryKey: notificationKeys.preferences,
|
||||
queryFn: () => apiClient.get<NotificationPreferences>('/api/notifications/preferences'),
|
||||
});
|
||||
}
|
||||
|
||||
export function useUpdateNotificationPreferences() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (data: Partial<NotificationPreferences>) =>
|
||||
apiClient.put<NotificationPreferences>('/api/notifications/preferences', data),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: notificationKeys.preferences }),
|
||||
});
|
||||
}
|
||||
|
||||
export function useChannelsStatus() {
|
||||
return useQuery({
|
||||
queryKey: ['notification-channels-status'],
|
||||
queryFn: () => apiClient.get<Record<string, unknown>>('/api/notifications/channels/status'),
|
||||
});
|
||||
}
|
||||
|
||||
export function useSendTestNotification() {
|
||||
return useMutation({
|
||||
mutationFn: (channel: string) =>
|
||||
apiClient.post<Record<string, unknown>>(`/api/notifications/test?channel=${encodeURIComponent(channel)}`, {}),
|
||||
});
|
||||
}
|
||||
|
||||
export function useVerifyTelegramChat() {
|
||||
const qc = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (chatId: string) =>
|
||||
apiClient.post<{ success: boolean; message: string; chat_id: string }>(`/api/notifications/telegram/verify?chat_id=${encodeURIComponent(chatId)}`, {}),
|
||||
onSuccess: () => qc.invalidateQueries({ queryKey: notificationKeys.preferences }),
|
||||
});
|
||||
}
|
||||
|
||||
export function useTelegramBotInfo() {
|
||||
return useQuery({
|
||||
queryKey: ['telegram-bot-info'],
|
||||
queryFn: () => apiClient.get<{ configured: boolean; bot_info: Record<string, unknown> | null }>('/api/notifications/telegram/bot-info'),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -131,6 +131,20 @@ export function useUpdateTelegram() {
|
||||
});
|
||||
}
|
||||
|
||||
export function useTestSMTP() {
|
||||
return useMutation({
|
||||
mutationFn: (testEmail: string) =>
|
||||
apiClient.post<{ success: boolean; message: string }>(`/settings/api/notification-channels/smtp/test?test_email=${encodeURIComponent(testEmail)}`, {}),
|
||||
});
|
||||
}
|
||||
|
||||
export function useTestTelegram() {
|
||||
return useMutation({
|
||||
mutationFn: (chatId: string) =>
|
||||
apiClient.post<{ success: boolean; message: string }>(`/settings/api/notification-channels/telegram/test?chat_id=${encodeURIComponent(chatId)}`, {}),
|
||||
});
|
||||
}
|
||||
|
||||
export function useAppVersion() {
|
||||
return useQuery({
|
||||
queryKey: settingsKeys.version,
|
||||
|
||||
Reference in New Issue
Block a user