'use client' import { useState, useEffect, useCallback } from 'react' import { useRouter } from 'next/navigation' import { BarChart2, History, TrendingUp, Download, Calendar, Filter, Activity } from 'lucide-react' import { useLiveQuery } from 'dexie-react-hooks' import { format, subDays, startOfDay, isSameDay, subWeeks, subMonths } from 'date-fns' import { db } from '@/lib/sync' import { Card, LoadingState, Button, showToast } from '@/components/ui' import { Header, PageContainer } from '@/components/layout/header' import { SymptomQuickLog } from '@/components/symptoms/SymptomQuickLog' import { SymptomCard } from '@/components/symptoms/SymptomCard' import { SymptomTrendChart } from '@/components/symptoms/SymptomTrendChart' import { SymptomReportGenerator } from '@/components/symptoms/SymptomReportGenerator' import { useApp } from '../provider' const TIME_RANGES = [ { value: '7', label: '7 Days' }, { value: '14', label: '14 Days' }, { value: '30', label: '30 Days' }, ] const SYMPTOM_TYPES = [ { type: 'FATIGUE', emoji: '😴', label: 'Fatigue', color: '#8b5cf6' }, { type: 'NAUSEA', emoji: '🤢', label: 'Nausea', color: '#f59e0b' }, { type: 'PAIN', emoji: '😣', label: 'Pain', color: '#ef4444' }, { type: 'APPETITE', emoji: '🍽️', label: 'Appetite', color: '#10b981' }, { type: 'SLEEP', emoji: '😴', label: 'Sleep', color: '#3b82f6' }, { type: 'MOOD', emoji: '😔', label: 'Mood', color: '#ec4899' }, ] export default function EnhancedSymptomsPage() { const router = useRouter() const { currentWorkspace, refreshData } = useApp() const [recentSymptoms, setRecentSymptoms] = useState([]) const [timeRange, setTimeRange] = useState('7') const [selectedType, setSelectedType] = useState(null) const [loading, setLoading] = useState(true) const [showReport, setShowReport] = useState(false) // Fetch symptoms from IndexedDB const localSymptoms = useLiveQuery( () => db.symptoms .where('workspaceId') .equals(currentWorkspace.id) .and((s) => !s.deletedAt) .reverse() .toArray(), [currentWorkspace.id] ) // Fetch from server const fetchSymptoms = useCallback(async () => { try { const response = await fetch( `/api/workspaces/${currentWorkspace.id}/symptoms?limit=100` ) if (response.ok) { const data = await response.json() setRecentSymptoms(data.symptoms) } } catch (err) { console.error('Failed to fetch symptoms:', err) } finally { setLoading(false) } }, [currentWorkspace.id]) useEffect(() => { fetchSymptoms() }, [fetchSymptoms]) const handleLogged = () => { fetchSymptoms() refreshData() } // Combine local and server data const symptoms = recentSymptoms.length > 0 ? recentSymptoms : localSymptoms || [] // Filter by time range const daysBack = parseInt(timeRange) const cutoffDate = subDays(new Date(), daysBack) const filteredSymptoms = symptoms.filter(s => new Date(s.recordedAt) >= cutoffDate && (!selectedType || s.type === selectedType) ) // Calculate stats const stats = useMemo(() => { const byType: Record = {} filteredSymptoms.forEach(s => { if (!byType[s.type]) { byType[s.type] = { count: 0, avgSeverity: 0 } } byType[s.type].count++ byType[s.type].avgSeverity += s.severity }) // Calculate averages Object.keys(byType).forEach(type => { byType[type].avgSeverity = Math.round((byType[type].avgSeverity / byType[type].count) * 10) / 10 }) return byType }, [filteredSymptoms]) // Find patterns (days with multiple symptoms) const patterns = useMemo(() => { const byDate: Record = {} filteredSymptoms.forEach(s => { const date = format(new Date(s.recordedAt), 'yyyy-MM-dd') if (!byDate[date]) byDate[date] = [] byDate[date].push(s) }) return Object.entries(byDate) .filter(([_, items]) => items.length >= 2) .sort((a, b) => b[0].localeCompare(a[0])) .slice(0, 5) }, [filteredSymptoms]) if (loading && !localSymptoms) { return ( <>
) } return ( <>
, label: 'History', onClick: () => router.push('/symptoms/history'), }} /> {/* Quick Log */}

Log a Symptom

{/* Time Range & Filters */}

Trends & Insights

{/* Time Range Selector */}
{TIME_RANGES.map(range => ( ))}
{/* Symptom Type Filter */}
{SYMPTOM_TYPES.map(type => ( ))}
{/* Trend Chart */} {filteredSymptoms.length > 0 && ( )} {/* Stats Summary */} {Object.keys(stats).length > 0 && (

Summary ({timeRange} Days)

{Object.entries(stats).map(([type, data]) => { const typeInfo = SYMPTOM_TYPES.find(t => t.type === type) return (
{typeInfo?.emoji}

{typeInfo?.label}

{data.count} logged

{data.avgSeverity}/5

avg severity

) })}
)} {/* Patterns */} {patterns.length > 0 && (

Patterns Noticed

Days with multiple symptoms logged

{patterns.map(([date, items]) => (

{format(new Date(date), 'EEEE, MMM d')}

{items.map((item, i) => ( {SYMPTOM_TYPES.find(t => t.type === item.type)?.label} ({item.severity}/5) ))}
))}
)} {/* Recent Symptoms */}

Recent

{symptoms.length > 5 && ( )}
{symptoms.length === 0 ? (

No symptoms logged yet

Use the form above to track how you're feeling

) : (
{symptoms.slice(0, 5).map((symptom: any) => ( ))}
)}
{/* Report Modal */} {showReport && ( setShowReport(false)} /> )} ) }