import React from 'react'; import { useTranslation } from 'react-i18next'; import { BellIcon, BellAlertIcon, ExclamationTriangleIcon, FolderIcon, FolderOpenIcon, ClockIcon, } from '@heroicons/react/24/outline'; import type { NotificationPreferences } from '../types'; interface NotificationsTabProps { isActive: boolean; notificationPreferences: NotificationPreferences | null | undefined; onChange: (preferences: NotificationPreferences) => void; } const DEFAULT_PREFERENCES: NotificationPreferences = { dueTasks: { inApp: true, email: false, push: false, telegram: false }, overdueTasks: { inApp: true, email: false, push: false, telegram: false }, dueProjects: { inApp: true, email: false, push: false, telegram: false }, overdueProjects: { inApp: true, email: false, push: false, telegram: false, }, deferUntil: { inApp: true, email: false, push: false, telegram: false }, }; interface NotificationTypeRowProps { icon: React.ComponentType<{ className?: string }>; label: string; description: string; preferences: { inApp: boolean; email: boolean; push: boolean; telegram: boolean; }; onToggle: ( channel: 'inApp' | 'email' | 'push' | 'telegram', value: boolean ) => void; telegramConfigured: boolean; } const NotificationTypeRow: React.FC = ({ icon: Icon, label, description, preferences, onToggle, telegramConfigured, }) => { const renderToggle = ( channel: 'inApp' | 'email' | 'push' | 'telegram', isEnabled: boolean, isAvailable: boolean ) => ( ); return (
{label}
{description}
{renderToggle('inApp', preferences.inApp, true)} {renderToggle('email', preferences.email, false)} {renderToggle('push', preferences.push, false)} {renderToggle( 'telegram', preferences.telegram, telegramConfigured )} ); }; const NotificationsTab: React.FC = ({ isActive, notificationPreferences, onChange, }) => { const { t } = useTranslation(); const [profile, setProfile] = React.useState(null); const [selectedTestType, setSelectedTestType] = React.useState('task_due_soon'); const [testLoading, setTestLoading] = React.useState(false); const [testMessage, setTestMessage] = React.useState(''); // Fetch profile data to check telegram configuration React.useEffect(() => { if (isActive) { fetch('/api/profile') .then((res) => res.json()) .then((data) => setProfile(data)) .catch((err) => console.error('Failed to fetch profile', err)); } }, [isActive]); if (!isActive) return null; // Merge with defaults to ensure all types exist const preferences: NotificationPreferences = { ...DEFAULT_PREFERENCES, ...notificationPreferences, }; // Check if Telegram is configured const telegramConfigured = !!( profile?.telegram_bot_token && profile?.telegram_chat_id ); const handleToggle = ( notificationType: keyof NotificationPreferences, channel: 'inApp' | 'email' | 'push' | 'telegram', value: boolean ) => { const updatedPreferences = { ...preferences, [notificationType]: { ...preferences[notificationType], [channel]: value, }, }; onChange(updatedPreferences); }; const handleTestNotification = async () => { setTestLoading(true); setTestMessage(''); try { const response = await fetch('/api/test-notifications/trigger', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ type: selectedTestType }), }); const data = await response.json(); if (response.ok) { const sources = data.notification.sources; const sourcesList = sources.length > 0 ? sources.join(', ') : 'in-app only'; setTestMessage(`✅ Test notification sent! (${sourcesList})`); } else { setTestMessage(`❌ Failed: ${data.error}`); } } catch (error) { setTestMessage( `❌ Error: ${error.message || 'Failed to send test'}` ); } finally { setTestLoading(false); // Clear message after 5 seconds setTimeout(() => setTestMessage(''), 5000); } }; return (

{t('profile.tabs.notifications', 'Notification Preferences')}

{t( 'profile.notificationsDescription', 'Choose how you want to be notified about important events.' )}

{/* Telegram Not Configured Warning */} {!telegramConfigured && (

{t( 'notifications.telegram.notConfigured.title', 'Telegram Not Configured:' )} {' '} {t( 'notifications.telegram.notConfigured.message', 'To receive Telegram notifications, please configure your Telegram bot in the Telegram tab.' )}

)} {/* Notifications Table */}
handleToggle('dueTasks', channel, value) } telegramConfigured={telegramConfigured} /> handleToggle('overdueTasks', channel, value) } telegramConfigured={telegramConfigured} /> handleToggle('deferUntil', channel, value) } telegramConfigured={telegramConfigured} /> handleToggle('dueProjects', channel, value) } telegramConfigured={telegramConfigured} /> handleToggle('overdueProjects', channel, value) } telegramConfigured={telegramConfigured} />
{t( 'notifications.table.type', 'Notification Type' )} {t('notifications.channels.inApp', 'In-app')}
{t('notifications.channels.email', 'Email')} ({t('common.comingSoon', 'Coming Soon')} )
{t('notifications.channels.push', 'Push')} ({t('common.comingSoon', 'Coming Soon')} )
{t( 'notifications.channels.telegram', 'Telegram' )}
{/* Test Notifications Section */}

{t('notifications.test.title', 'Test Notifications')}

{t( 'notifications.test.description', 'Send a test notification to see how it appears in-app and on enabled channels (Telegram, etc.)' )}

{testMessage && (
{testMessage}
)}
{/* Help Text */}

{t('notifications.info.title', 'Note:')} {' '} {t( 'notifications.info.message', 'Email and Push notifications are coming soon. In-app and Telegram notifications are currently available.' )}

); }; export default NotificationsTab;