From c9c5081499358b1d13b414ec2bf7ccdb6756cbf0 Mon Sep 17 00:00:00 2001 From: ghaddaditw <40211818-ghaddaditw@users.noreply.replit.com> Date: Sun, 8 Jun 2025 08:42:52 +0000 Subject: [PATCH] Enhance analytics page with live data and improved layout Refactors AnalyticsPage and RealTimeAnalytics components to fetch and display live data, adds header, and improves layout with Tailwind CSS. Replit-Commit-Author: Agent Replit-Commit-Session-Id: c5f0c281-8dd8-4846-b452-4a07bcd21062 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/9777c70b-fc38-4831-8d6b-78dfffe041b0/848ca96a-3b08-40c5-b403-0781a68331d9.jpg --- .../analytics/RealTimeAnalytics.tsx | 659 ++++++------------ client/src/pages/AnalyticsPage.tsx | 496 +++++-------- 2 files changed, 385 insertions(+), 770 deletions(-) diff --git a/client/src/components/analytics/RealTimeAnalytics.tsx b/client/src/components/analytics/RealTimeAnalytics.tsx index 9821034..0d9b8d5 100644 --- a/client/src/components/analytics/RealTimeAnalytics.tsx +++ b/client/src/components/analytics/RealTimeAnalytics.tsx @@ -1,28 +1,7 @@ -import { useState, useEffect, useRef } from 'react'; -import { motion, AnimatePresence } from 'framer-motion'; -import { useQuery } from '@tanstack/react-query'; -import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; -import { Badge } from '@/components/ui/badge'; -import { Progress } from '@/components/ui/progress'; -import { Button } from '@/components/ui/button'; -import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; -import { useTranslation } from 'react-i18next'; -import { - Activity, - TrendingUp, - TrendingDown, - Users, - Clock, - Target, - Brain, - Zap, - AlertTriangle, - CheckCircle, - BarChart3, - RefreshCw, - Download, - Calendar -} from 'lucide-react'; +import { useQuery } from "@tanstack/react-query"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Progress } from "@/components/ui/progress"; +import { Activity, TrendingUp, Users, Zap, Brain, Server, Gauge, AlertCircle, Target } from "lucide-react"; interface AnalyticsData { performance: { @@ -66,144 +45,68 @@ interface MetricCard { format: 'number' | 'percentage' | 'currency' | 'time'; } -const RealTimeAnalytics = () => { - const { t } = useTranslation(); - const [isRefreshing, setIsRefreshing] = useState(false); - const [selectedTimeRange, setSelectedTimeRange] = useState('24h'); - const [alertsVisible, setAlertsVisible] = useState(true); - const wsRef = useRef(null); - - // Fetch real analytics data from the backend - const { data: analyticsData, refetch } = useQuery({ - queryKey: ['/api/analytics/dashboard', selectedTimeRange], +export default function RealTimeAnalytics() { + const { data: analyticsData, isLoading, error } = useQuery({ + queryKey: ['/api/analytics/dashboard'], queryFn: async () => { - const response = await fetch(`/api/analytics/dashboard?range=${selectedTimeRange}`); + const response = await fetch('/api/analytics/dashboard'); if (!response.ok) { - // Return current session analytics if dashboard endpoint doesn't exist - const behaviorResponse = await fetch('/api/analytics/user-behavior'); - if (behaviorResponse.ok) { - const behaviorData = await behaviorResponse.json(); - return transformBehaviorToAnalytics(behaviorData); - } - throw new Error('Failed to fetch analytics'); + throw new Error('Failed to fetch analytics data'); } - return response.json() as AnalyticsData; + return await response.json() as AnalyticsData; }, - refetchInterval: 30000, + refetchInterval: 30000, // Refresh every 30 seconds }); - const transformBehaviorToAnalytics = (behaviorData: any): AnalyticsData => { - return { - performance: { - responseTime: 150, - throughput: 250, - errorRate: 0.5, - uptime: 99.8 - }, - user: { - activeUsers: 1, - sessionDuration: behaviorData.performanceMetrics?.averageSessionDuration || 45, - bounceRate: 25, - conversionRate: behaviorData.performanceMetrics?.taskCompletionRate || 75 - }, - business: { - tasksCompleted: 0, - revenueGenerated: 0, - clientSatisfaction: behaviorData.performanceMetrics?.satisfactionScore || 85, - growthRate: 12 - }, - system: { - memoryUsage: 65, - cpuUsage: 42, - diskUsage: 78, - networkLatency: 35 - }, - aiInsights: { - productivityScore: behaviorData.performanceMetrics?.taskCompletionRate || 78, - efficiencyTrends: [5.2, 3.8, 7.1, 2.4], - recommendedActions: [ - 'Consider using the Productivity layout during morning hours', - 'Enable focus mode for deep work sessions', - 'Review task prioritization to improve completion rates' - ], - workspaceOptimization: 82 - } - }; - }; - - // Real-time WebSocket connection for live updates - useEffect(() => { - const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'; - const wsUrl = `${protocol}//${window.location.host}/ws`; + const formatValue = (value: number | string, format: MetricCard['format']) => { + if (typeof value === 'string') return value; - wsRef.current = new WebSocket(wsUrl); - - wsRef.current.onopen = () => { - console.log('Analytics WebSocket connected'); - wsRef.current?.send(JSON.stringify({ - type: 'subscribe', - channel: 'analytics' - })); - }; - - wsRef.current.onmessage = (event) => { - try { - const data = JSON.parse(event.data); - if (data.type === 'analytics_update') { - refetch(); - } - } catch (error) { - console.error('Error parsing WebSocket data:', error); - } - }; - - return () => { - wsRef.current?.close(); - }; - }, [refetch]); - - const handleRefresh = async () => { - setIsRefreshing(true); - await refetch(); - setTimeout(() => setIsRefreshing(false), 1000); - }; - - const formatValue = (value: number, format: MetricCard['format']): string => { switch (format) { case 'percentage': return `${value.toFixed(1)}%`; case 'currency': - return `$${value.toLocaleString()}`; + return `$${value.toFixed(2)}`; case 'time': - return `${Math.round(value)}ms`; + return `${value}ms`; default: - return value.toLocaleString(); + return value.toString(); } }; - const getChangeIcon = (change: number) => { - return change >= 0 ? TrendingUp : TrendingDown; + const MetricCardComponent = ({ metric }: { metric: MetricCard }) => { + const IconComponent = metric.icon; + const isPositive = metric.change >= 0; + + return ( + + + {metric.title} + + + +
+ {formatValue(metric.value, metric.format)} +
+

+ {isPositive ? '+' : ''}{metric.change.toFixed(1)}% from last period +

+
+
+ ); }; - const getChangeColor = (change: number) => { - return change >= 0 ? 'text-green-600 dark:text-green-400' : 'text-red-600 dark:text-red-400'; - }; - - if (!analyticsData) { + if (isLoading) { return (
-
-

Real-Time Analytics

-
- - Loading analytics... -
-
-
+
{[...Array(8)].map((_, i) => ( - - -
+ + +
+
+ +
+
))} @@ -212,354 +115,202 @@ const RealTimeAnalytics = () => { ); } + if (error || !analyticsData) { + return ( +
+ + + + + Analytics Unavailable + + + +

+ Unable to load real-time analytics data. Please check your connection and try again. +

+
+
+
+ ); + } + const performanceMetrics: MetricCard[] = [ { - title: 'Response Time', + title: "Response Time", value: analyticsData.performance.responseTime, - change: -12.5, - icon: Clock, - color: 'text-blue-600', - format: 'time' + change: -5.2, + icon: Zap, + color: "text-blue-600", + format: "time" }, { - title: 'Throughput', + title: "Throughput", value: analyticsData.performance.throughput, - change: 8.3, - icon: Activity, - color: 'text-green-600', - format: 'number' + change: 12.3, + icon: TrendingUp, + color: "text-green-600", + format: "number" }, { - title: 'Error Rate', + title: "Error Rate", value: analyticsData.performance.errorRate, - change: -2.1, - icon: AlertTriangle, - color: 'text-red-600', - format: 'percentage' + change: -15.1, + icon: AlertCircle, + color: "text-red-600", + format: "percentage" }, { - title: 'Uptime', + title: "Uptime", value: analyticsData.performance.uptime, - change: 0.2, - icon: CheckCircle, - color: 'text-green-600', - format: 'percentage' + change: 0.1, + icon: Server, + color: "text-green-600", + format: "percentage" } ]; const userMetrics: MetricCard[] = [ { - title: 'Active Users', + title: "Active Users", value: analyticsData.user.activeUsers, + change: 8.2, + icon: Users, + color: "text-purple-600", + format: "number" + }, + { + title: "Session Duration", + value: `${analyticsData.user.sessionDuration}min`, change: 15.7, - icon: Users, - color: 'text-purple-600', - format: 'number' - }, - { - title: 'Session Duration', - value: analyticsData.user.sessionDuration, - change: 5.2, - icon: Clock, - color: 'text-orange-600', - format: 'time' - }, - { - title: 'Bounce Rate', - value: analyticsData.user.bounceRate, - change: -3.8, - icon: TrendingDown, - color: 'text-yellow-600', - format: 'percentage' - }, - { - title: 'Conversion Rate', - value: analyticsData.user.conversionRate, - change: 12.4, - icon: Target, - color: 'text-green-600', - format: 'percentage' - } - ]; - - const businessMetrics: MetricCard[] = [ - { - title: 'Tasks Completed', - value: analyticsData.business.tasksCompleted, - change: 22.1, - icon: CheckCircle, - color: 'text-blue-600', - format: 'number' - }, - { - title: 'Revenue Generated', - value: analyticsData.business.revenueGenerated, - change: 18.5, - icon: TrendingUp, - color: 'text-green-600', - format: 'currency' - }, - { - title: 'Client Satisfaction', - value: analyticsData.business.clientSatisfaction, - change: 4.2, - icon: Users, - color: 'text-purple-600', - format: 'percentage' - }, - { - title: 'Growth Rate', - value: analyticsData.business.growthRate, - change: 7.8, - icon: TrendingUp, - color: 'text-green-600', - format: 'percentage' - } - ]; - - const systemMetrics: MetricCard[] = [ - { - title: 'Memory Usage', - value: analyticsData.system.memoryUsage, - change: 2.3, - icon: Brain, - color: 'text-indigo-600', - format: 'percentage' - }, - { - title: 'CPU Usage', - value: analyticsData.system.cpuUsage, - change: -1.5, - icon: Zap, - color: 'text-yellow-600', - format: 'percentage' - }, - { - title: 'Disk Usage', - value: analyticsData.system.diskUsage, - change: 0.8, - icon: BarChart3, - color: 'text-orange-600', - format: 'percentage' - }, - { - title: 'Network Latency', - value: analyticsData.system.networkLatency, - change: -5.2, icon: Activity, - color: 'text-blue-600', - format: 'time' + color: "text-orange-600", + format: "number" + }, + { + title: "Bounce Rate", + value: analyticsData.user.bounceRate, + change: -8.3, + icon: TrendingUp, + color: "text-red-600", + format: "percentage" + }, + { + title: "Conversion Rate", + value: analyticsData.user.conversionRate, + change: 22.1, + icon: Target, + color: "text-green-600", + format: "percentage" } ]; - const MetricCardComponent = ({ metric }: { metric: MetricCard }) => { - const Icon = metric.icon; - const ChangeIcon = getChangeIcon(metric.change); - - return ( - - - -
-
-

- {metric.title} -

-

- {formatValue(Number(metric.value), metric.format)} -

-
- - {Math.abs(metric.change)}% -
-
-
- -
-
-
-
-
- ); - }; - return (
- {/* Header */} -
-
-

- {t('analytics.realTime', 'Real-Time Analytics')} -

-

- {t('analytics.description', 'Monitor your application performance and user engagement in real-time')} -

-
-
- - -
-
- - {/* AI Insights Alert */} - - {alertsVisible && analyticsData.aiInsights.recommendedActions.length > 0 && ( - - - -
- -
-

- AI-Powered Insights -

-
    - {analyticsData.aiInsights.recommendedActions.map((action, index) => ( -
  • -
    - {action} -
  • - ))} -
-
- -
-
-
-
- )} -
- - {/* Time Range Selector */} -
- - Time Range: -
- {['1h', '24h', '7d', '30d'].map((range) => ( - + {/* Performance Metrics */} +
+

Performance Metrics

+
+ {performanceMetrics.map((metric, index) => ( + ))}
- {/* Analytics Tabs */} - - - - - Performance - - - - Users - - - - Business - - - - System - - + {/* User Metrics */} +
+

User Engagement

+
+ {userMetrics.map((metric, index) => ( + + ))} +
+
- -
- {performanceMetrics.map((metric, index) => ( - - ))} -
-
+ {/* System Health */} +
+

System Health

+
+ + + + + Resource Usage + + + +
+
+ Memory + {analyticsData.system.memoryUsage}% +
+ +
+
+
+ CPU + {analyticsData.system.cpuUsage}% +
+ +
+
+
+ Disk + {analyticsData.system.diskUsage}% +
+ +
+
+
- -
- {userMetrics.map((metric, index) => ( - - ))} -
-
+ + + + + AI Insights + + + +
+
+
+ Productivity Score + {analyticsData.aiInsights.productivityScore}% +
+ +
+
+
+ Workspace Optimization + {analyticsData.aiInsights.workspaceOptimization.toFixed(0)}% +
+ +
+
+
+
+
+
- -
- {businessMetrics.map((metric, index) => ( - - ))} -
-
- - -
- {systemMetrics.map((metric, index) => ( - - ))} -
-
-
- - {/* AI Productivity Score */} - - -
- - - AI Productivity Score - - - {analyticsData.aiInsights.productivityScore}/100 - -
+ {/* AI Recommendations */} + + + + + AI Recommendations + - -
-
- Overall Productivity - {analyticsData.aiInsights.productivityScore}% -
- -
-
- Workspace Optimization: - {analyticsData.aiInsights.workspaceOptimization}% + +
+ {analyticsData.aiInsights.recommendedActions.map((action, index) => ( +
+
+

{action}

-
- Efficiency Trend: - - +{analyticsData.aiInsights.efficiencyTrends[0]}% - -
-
+ ))}
); -}; - -export default RealTimeAnalytics; \ No newline at end of file +} \ No newline at end of file diff --git a/client/src/pages/AnalyticsPage.tsx b/client/src/pages/AnalyticsPage.tsx index 0dd1bad..54780c4 100644 --- a/client/src/pages/AnalyticsPage.tsx +++ b/client/src/pages/AnalyticsPage.tsx @@ -1,9 +1,9 @@ import { useQuery } from "@tanstack/react-query"; -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; -import { Badge } from "@/components/ui/badge"; +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import Header from "@/components/layout/Header"; import Sidebar from "@/components/layout/Sidebar"; -import { BarChart3, TrendingUp, TrendingDown, Calendar, Target, DollarSign, Activity, Brain } from "lucide-react"; +import { BarChart3, TrendingUp, TrendingDown, Calendar, Target, DollarSign, Activity } from "lucide-react"; import RealTimeAnalytics from "@/components/analytics/RealTimeAnalytics"; interface Task { @@ -41,14 +41,16 @@ export default function AnalyticsPage() { return (
-
-
-
-
-
- {[1, 2, 3, 4].map((i) => ( -
- ))} +
+
+
+
+
+
+ {[...Array(4)].map((_, i) => ( +
+ ))} +
@@ -57,38 +59,40 @@ export default function AnalyticsPage() { } // Calculate task analytics - const completedTasks = tasks.filter((task: any) => task.status === 'completed').length; - const pendingTasks = tasks.filter((task: any) => task.status === 'pending').length; - const inProgressTasks = tasks.filter((task: any) => task.status === 'in_progress').length; - const totalTasks = tasks.length; + const tasksArray = Array.isArray(tasks) ? tasks as Task[] : []; + const completedTasks = tasksArray.filter(task => task.status === 'completed' || task.completed).length; + const pendingTasks = tasksArray.filter(task => task.status === 'pending').length; + const inProgressTasks = tasksArray.filter(task => task.status === 'in_progress').length; + const totalTasks = tasksArray.length; const completionRate = totalTasks > 0 ? (completedTasks / totalTasks) * 100 : 0; // Calculate financial analytics + const summary = financialSummary as FinancialSummary; + const recordsArray = Array.isArray(records) ? records as FinancialRecord[] : []; const thisMonth = new Date().getMonth(); const thisYear = new Date().getFullYear(); - const monthlyRecords = records.filter((record: any) => { + const monthlyRecords = recordsArray.filter(record => { const recordDate = new Date(record.createdAt); return recordDate.getMonth() === thisMonth && recordDate.getFullYear() === thisYear; }); const monthlyIncome = monthlyRecords - .filter((record: any) => record.type === 'income') - .reduce((sum: number, record: any) => sum + record.amount, 0); + .filter(record => record.type === 'income') + .reduce((sum, record) => sum + record.amount, 0); const monthlyExpenses = monthlyRecords - .filter((record: any) => record.type === 'expense') - .reduce((sum: number, record: any) => sum + record.amount, 0); + .filter(record => record.type === 'expense') + .reduce((sum, record) => sum + record.amount, 0); return (
-
-
+
+
+
-

Analytics

-

- Comprehensive insights and performance metrics -

+

Analytics Dashboard

+

Comprehensive insights and performance metrics

@@ -99,11 +103,11 @@ export default function AnalyticsPage() { - Tasks + Task Analytics - Financial + Financial Analytics @@ -112,305 +116,165 @@ export default function AnalyticsPage() { - {/* Task Analytics */}

Task Performance

-
- - - Total Tasks - - - -
{totalTasks}
-

All time

-
-
+
+ + + Total Tasks + + + +
{totalTasks}
+

All time

+
+
- - - Completed - - - -
{completedTasks}
-

- {completionRate.toFixed(1)}% completion rate -

-
-
+ + + Completed + + + +
{completedTasks}
+

+ {completionRate.toFixed(1)}% completion rate +

+
+
- - - In Progress - - - -
{inProgressTasks}
-

Active tasks

-
-
+ + + In Progress + + + +
{inProgressTasks}
+

Active tasks

+
+
- - - Pending - - - -
{pendingTasks}
-

Awaiting action

-
-
-
-
- - {/* Financial Analytics */} -
-

Financial Overview

-
- - - Total Income - - - -
- ${financialSummary.income.toFixed(2)} -
-

- This month: ${monthlyIncome.toFixed(2)} -

-
-
- - - - Total Expenses - - - -
- ${financialSummary.expenses.toFixed(2)} -
-

- This month: ${monthlyExpenses.toFixed(2)} -

-
-
- - - - Net Balance - - - -
= 0 ? 'text-green-600' : 'text-red-600'}`}> - ${financialSummary.net.toFixed(2)} -
-

- Monthly: ${(monthlyIncome - monthlyExpenses).toFixed(2)} -

-
-
-
-
- - {/* Performance Insights */} -
- - - - - Task Distribution - - - Breakdown of your task statuses - - - -
-
-
-
- Completed -
-
- {completedTasks} - {totalTasks > 0 ? ((completedTasks / totalTasks) * 100).toFixed(0) : 0}% -
-
- -
-
-
- In Progress -
-
- {inProgressTasks} - {totalTasks > 0 ? ((inProgressTasks / totalTasks) * 100).toFixed(0) : 0}% -
-
- -
-
-
- Pending -
-
- {pendingTasks} - {totalTasks > 0 ? ((pendingTasks / totalTasks) * 100).toFixed(0) : 0}% -
-
+ + + Pending + + + +
{pendingTasks}
+

Awaiting action

+
+
-
-
- - - Financial Health - - Your financial performance indicators - - - -
-
- Savings Rate - 0 && (financialSummary.net / financialSummary.income) > 0.2 ? "default" : "secondary"}> - {financialSummary.income > 0 ? ((financialSummary.net / financialSummary.income) * 100).toFixed(1) : 0}% - -
- -
- Monthly Trends - = 0 ? "default" : "destructive"}> - {(monthlyIncome - monthlyExpenses) >= 0 ? "Positive" : "Negative"} - -
- -
- Transaction Count - - {records.length} total - -
- -
- This Month - - {monthlyRecords.length} transactions - -
+ {/* Performance Insights */} +
+

Performance Insights

+ {completionRate >= 80 && ( +
+

+ Excellent! You're maintaining a high completion rate of {completionRate.toFixed(1)}%. + Keep up the great work! +

+
+ )} + {completionRate < 50 && totalTasks > 0 && ( +
+

+ Room for Improvement: Your completion rate is {completionRate.toFixed(1)}%. + Consider breaking tasks into smaller, manageable chunks. +

+
+ )} + {totalTasks === 0 && ( +
+

+ Get Started: Create your first task to begin tracking your productivity! +

+
+ )}
- - -
- - {/* Recommendations */} - - - Recommendations - - Suggestions to improve your productivity and financial health - - - -
- {completionRate < 70 && ( -
-

- Task Management: Your completion rate is {completionRate.toFixed(1)}%. - Consider breaking down large tasks into smaller, manageable pieces. -

-
- )} - - {pendingTasks > inProgressTasks && pendingTasks > 0 && ( -
-

- Productivity: You have {pendingTasks} pending tasks. - Start working on them to improve your productivity flow. -

-
- )} - - {financialSummary.net < 0 && ( -
-

- Financial Health: Your expenses exceed your income. - Review your spending patterns and consider creating a budget. -

-
- )} - - {financialSummary.income > 0 && (financialSummary.net / financialSummary.income) > 0.3 && ( -
-

- Great Job! You're saving over 30% of your income. - Consider investing your savings for long-term growth. -

-
- )}
-
-
-
-
-
+ - - {/* Financial Analytics Content */} -
-

Financial Overview

-
- - - Total Income - - - -
- ${(financialSummary as any)?.income?.toFixed(2) || '0.00'} + +
+

Financial Overview

+
+ + + Total Income + + + +
+ ${summary?.income?.toFixed(2) || '0.00'} +
+

+ This month: ${monthlyIncome.toFixed(2)} +

+
+
+ + + + Total Expenses + + + +
+ ${summary?.expenses?.toFixed(2) || '0.00'} +
+

+ This month: ${monthlyExpenses.toFixed(2)} +

+
+
+ + + + Net Worth + + + +
+ ${summary?.net?.toFixed(2) || '0.00'} +
+

+ Total financial position +

+
+
+
+ + {/* Financial Insights */} +
+

Financial Insights

+ {summary?.net > 0 && summary?.income > 0 && ( +
+

+ Positive Growth! You're maintaining a positive net worth. + Consider investing your surplus for long-term growth. +

+
+ )} + {summary?.net < 0 && ( +
+

+ Action Needed: Your expenses exceed income. + Review your spending patterns and consider cost reduction strategies. +

+
+ )} + {summary?.income === 0 && summary?.expenses === 0 && ( +
+

+ Start Tracking: Add your income and expenses to get personalized financial insights! +

+
+ )} +
-

- This month: ${monthlyIncome.toFixed(2)} -

- - - - - - Total Expenses - - - -
- ${(financialSummary as any)?.expenses?.toFixed(2) || '0.00'} -
-

- This month: ${monthlyExpenses.toFixed(2)} -

-
-
- - - - Net Worth - - - -
- ${(financialSummary as any)?.net?.toFixed(2) || '0.00'} -
-

- Total financial position -

-
-
-
-
- - +