import React, { useState, useEffect } from 'react'; import { motion } from 'framer-motion'; import { logStore } from '~/lib/stores/logs'; import { useStore } from '@nanostores/react'; import { formatDistanceToNow } from 'date-fns'; import { classNames } from '~/utils/classNames'; import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; interface NotificationDetails { type?: string; message?: string; currentVersion?: string; latestVersion?: string; branch?: string; updateUrl?: string; } type FilterType = 'all' | 'system' | 'error' | 'warning' | 'update' | 'info' | 'provider' | 'network'; const NotificationsTab = () => { const [filter, setFilter] = useState('all'); const logs = useStore(logStore.logs); useEffect(() => { const startTime = performance.now(); return () => { const duration = performance.now() - startTime; logStore.logPerformanceMetric('NotificationsTab', 'mount-duration', duration); }; }, []); const handleClearNotifications = () => { const count = Object.keys(logs).length; logStore.logInfo('Cleared notifications', { type: 'notification_clear', message: `Cleared ${count} notifications`, clearedCount: count, component: 'notifications', }); logStore.clearLogs(); }; const handleUpdateAction = (updateUrl: string) => { logStore.logInfo('Update link clicked', { type: 'update_click', message: 'User clicked update link', updateUrl, component: 'notifications', }); window.open(updateUrl, '_blank'); }; const handleFilterChange = (newFilter: FilterType) => { logStore.logInfo('Notification filter changed', { type: 'filter_change', message: `Filter changed to ${newFilter}`, previousFilter: filter, newFilter, component: 'notifications', }); setFilter(newFilter); }; const filteredLogs = Object.values(logs) .filter((log) => { if (filter === 'all') { return true; } if (filter === 'update') { return log.details?.type === 'update'; } if (filter === 'system') { return log.category === 'system'; } if (filter === 'provider') { return log.category === 'provider'; } if (filter === 'network') { return log.category === 'network'; } return log.level === filter; }) .sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()); const getNotificationStyle = (level: string, type?: string) => { if (type === 'update') { return { icon: 'i-ph:arrow-circle-up', color: 'text-purple-500 dark:text-purple-400', bg: 'hover:bg-purple-500/10 dark:hover:bg-purple-500/20', }; } switch (level) { case 'error': return { icon: 'i-ph:warning-circle', color: 'text-red-500 dark:text-red-400', bg: 'hover:bg-red-500/10 dark:hover:bg-red-500/20', }; case 'warning': return { icon: 'i-ph:warning', color: 'text-yellow-500 dark:text-yellow-400', bg: 'hover:bg-yellow-500/10 dark:hover:bg-yellow-500/20', }; case 'info': return { icon: 'i-ph:info', color: 'text-blue-500 dark:text-blue-400', bg: 'hover:bg-blue-500/10 dark:hover:bg-blue-500/20', }; default: return { icon: 'i-ph:bell', color: 'text-gray-500 dark:text-gray-400', bg: 'hover:bg-gray-500/10 dark:hover:bg-gray-500/20', }; } }; const renderNotificationDetails = (details: NotificationDetails) => { if (details.type === 'update') { return (

{details.message}

Current Version: {details.currentVersion}

Latest Version: {details.latestVersion}

Branch: {details.branch}

); } return details.message ?

{details.message}

: null; }; const filterOptions: { id: FilterType; label: string; icon: string; color: string }[] = [ { id: 'all', label: 'All Notifications', icon: 'i-ph:bell', color: '#9333ea' }, { id: 'system', label: 'System', icon: 'i-ph:gear', color: '#6b7280' }, { id: 'update', label: 'Updates', icon: 'i-ph:arrow-circle-up', color: '#9333ea' }, { id: 'error', label: 'Errors', icon: 'i-ph:warning-circle', color: '#ef4444' }, { id: 'warning', label: 'Warnings', icon: 'i-ph:warning', color: '#f59e0b' }, { id: 'info', label: 'Information', icon: 'i-ph:info', color: '#3b82f6' }, { id: 'provider', label: 'Providers', icon: 'i-ph:robot', color: '#10b981' }, { id: 'network', label: 'Network', icon: 'i-ph:wifi-high', color: '#6366f1' }, ]; return (
{filterOptions.map((option) => ( handleFilterChange(option.id)} >
{option.label} ))}
{filteredLogs.length === 0 ? (

No Notifications

You're all caught up!

) : ( filteredLogs.map((log) => { const style = getNotificationStyle(log.level, log.details?.type); return (

{log.message}

{log.details && renderNotificationDetails(log.details as NotificationDetails)}

Category: {log.category} {log.subCategory ? ` > ${log.subCategory}` : ''}

); }) )}
); }; export default NotificationsTab;