import { createSignal, onMount, For, Show } from 'solid-js'; import { IconChartLine, IconBookmarks, IconChecklist, IconClock, IconTarget, IconBrain, IconGitBranch, IconBulb, IconAward } from '@tabler/icons-solidjs'; import { Card, CardHeader, CardTitle, CardContent, CardDescription } from '@/components/ui/Card'; import { Button } from '@/components/ui/Button'; import { useHaptics } from '@/lib/haptics'; import { getApiOrigin } from '@/lib/api-url'; interface AnalyticsData { period: { start_date: string; end_date: string; days: number; }; summary: { hours_tracked: number; tasks_completed: number; bookmarks_added: number; notes_created: number; courses_completed: number; github_commits: number; }; analytics: Array<{ date: string; hours_tracked: number; tasks_completed: number; bookmarks_added: number; notes_created: number; courses_completed: number; github_commits: number; study_streak: number; productivity_score: number; }>; productivity_metrics: Array<{ period: string; start_date: string; end_date: string; total_hours: number; billable_hours: number; non_billable_hours: number; tasks_completed: number; average_task_time: number; peak_productivity_hour: number; focus_score: number; efficiency_score: number; }>; learning_analytics: Array<{ id: number; course: { title: string; description: string; }; start_date: string; last_accessed: string; time_spent: number; progress: number; modules_completed: number; total_modules: number; average_score: number; streak_days: number; skills_acquired: string[]; }>; github_analytics: Array<{ date: string; commits: number; pull_requests: number; issues_opened: number; issues_closed: number; reviews: number; contributions: number; languages: Record; repositories: string[]; }>; goals: Array<{ id: number; title: string; description: string; category: string; target_value: number; current_value: number; unit: string; deadline: string; status: string; priority: string; progress: number; is_completed: boolean; milestones: Array<{ id: number; title: string; target_value: number; current_value: number; deadline: string; status: string; is_completed: boolean; }>; }>; habit_analytics: Array<{ habit_name: string; start_date: string; last_completed: string; streak: number; best_streak: number; total_days: number; completion_rate: number; frequency: string; category: string; goal_target: number; goal_achieved: boolean; }>; } export const Analytics = () => { const haptics = useHaptics(); const [analytics, setAnalytics] = createSignal(null); const [loading, setLoading] = createSignal(true); const [error, setError] = createSignal(null); const [selectedPeriod, setSelectedPeriod] = createSignal('30'); const createFallbackAnalyticsData = (): AnalyticsData => ({ period: { start_date: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString(), end_date: new Date().toISOString(), days: 30, }, summary: { hours_tracked: 0, tasks_completed: 0, bookmarks_added: 0, notes_created: 0, courses_completed: 0, github_commits: 0, }, analytics: [], productivity_metrics: [], learning_analytics: [], github_analytics: [], goals: [], habit_analytics: [], }); const normalizeAnalyticsData = (raw: any): AnalyticsData => { const fallback = createFallbackAnalyticsData(); if (!raw || typeof raw !== 'object') { return fallback; } const periodRaw = raw.period && typeof raw.period === 'object' ? raw.period : {}; const summaryRaw = raw.summary && typeof raw.summary === 'object' ? raw.summary : {}; return { period: { start_date: typeof periodRaw.start_date === 'string' ? periodRaw.start_date : fallback.period.start_date, end_date: typeof periodRaw.end_date === 'string' ? periodRaw.end_date : fallback.period.end_date, days: Number(periodRaw.days) || fallback.period.days, }, summary: { hours_tracked: Number(summaryRaw.hours_tracked) || 0, tasks_completed: Number(summaryRaw.tasks_completed) || 0, bookmarks_added: Number(summaryRaw.bookmarks_added) || 0, notes_created: Number(summaryRaw.notes_created) || 0, courses_completed: Number(summaryRaw.courses_completed) || 0, github_commits: Number(summaryRaw.github_commits) || 0, }, analytics: Array.isArray(raw.analytics) ? raw.analytics : [], productivity_metrics: Array.isArray(raw.productivity_metrics) ? raw.productivity_metrics : [], learning_analytics: Array.isArray(raw.learning_analytics) ? raw.learning_analytics : [], github_analytics: Array.isArray(raw.github_analytics) ? raw.github_analytics : [], goals: Array.isArray(raw.goals) ? raw.goals : [], habit_analytics: Array.isArray(raw.habit_analytics) ? raw.habit_analytics : [], }; }; const fetchAnalytics = async () => { try { setLoading(true); setError(null); const token = localStorage.getItem('token'); const response = await fetch(`${getApiOrigin()}/api/v1/analytics/dashboard?days=${selectedPeriod()}`, { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json', }, }); if (!response.ok) { throw new Error('Failed to fetch analytics'); } const data = await response.json(); setAnalytics(normalizeAnalyticsData(data)); } catch (err) { setError(err instanceof Error ? err.message : 'An error occurred'); setAnalytics(createFallbackAnalyticsData()); } finally { setLoading(false); } }; onMount(() => { fetchAnalytics(); }); const formatHours = (hours: number) => { const h = Math.floor(hours); const m = Math.round((hours - h) * 60); return `${h}h ${m}m`; }; const formatDate = (dateString: string) => { return new Date(dateString).toLocaleDateString(); }; const getPriorityColor = (priority: string) => { switch (priority) { case 'urgent': return 'text-destructive'; case 'high': return 'text-orange-500'; case 'medium': return 'text-yellow-500'; case 'low': return 'text-muted-foreground'; default: return 'text-gray-500'; } }; // Component render return (

Analytics & Insights

Track your productivity and progress

{error()}

Loading analytics...

{/* Summary Cards */}

Hours Tracked

{formatHours(analytics()!.summary.hours_tracked)}

Tasks Completed

{analytics()!.summary.tasks_completed}

Bookmarks Added

{analytics()!.summary.bookmarks_added}

GitHub Commits

{analytics()!.summary.github_commits}

{/* Goals Progress */}
Active Goals Track your goal progress
g.status === 'active').slice(0, 5)}> {(goal) => (

{goal.title}

{goal.current_value} / {goal.target_value} {goal.unit}

{goal.priority} {Math.round(goal.progress)}%

Deadline: {formatDate(goal.deadline)}

)}
g.status === 'active').length === 0}>

No active goals

{/* Habit Tracking */} Habit Tracking Your daily habits and streaks
{(habit) => (

{habit.habit_name}

{habit.frequency} • {Math.round(habit.completion_rate)}% completion

{habit.streak} day streak

Best: {habit.best_streak} days

)}

No habits tracked

{/* Learning Progress */} Learning Progress Your course progress and achievements
{(course) => (

{course.course.title}

{course.modules_completed}/{course.total_modules} modules

{Math.round(course.progress)}% complete {course.streak_days} day streak
)}

No courses in progress

{/* GitHub Activity */} GitHub Activity Your contribution summary

{analytics()!.summary.github_commits}

Commits

{analytics()!.github_analytics.reduce((sum, day) => sum + day.pull_requests, 0)}

Pull Requests

{analytics()!.github_analytics.reduce((sum, day) => sum + day.issues_opened, 0)}

Issues Opened

{analytics()!.github_analytics.reduce((sum, day) => sum + day.reviews, 0)}

Reviews

{(day) => (
{formatDate(day.date)}
{day.commits} commits {day.pull_requests} PRs {day.issues_opened} issues
)}
{/* Productivity Insights */} Productivity Insights Key insights and patterns

Daily Activity

{(day) => (
{formatDate(day.date)}
{formatHours(day.hours_tracked)} {day.tasks_completed} tasks 0}> {Math.round(day.productivity_score)}%
)}

Key Metrics

Average Daily Hours {formatHours(analytics()!.summary.hours_tracked / analytics()!.period.days)}
Tasks per Day {(analytics()!.summary.tasks_completed / analytics()!.period.days).toFixed(1)}
Study Streak {Math.max(...analytics()!.analytics.map(a => a.study_streak))} days
Average Productivity {Math.round( analytics()!.analytics.reduce((sum, a) => sum + a.productivity_score, 0) / analytics()!.analytics.length )}%
); };