| import React, { useState, useEffect, useCallback } from 'react'; |
| import { motion, AnimatePresence } from 'framer-motion'; |
| import { |
| BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer, CartesianGrid, |
| LineChart, Line, PieChart, Pie, Cell, AreaChart, Area, RadarChart, |
| PolarGrid, PolarAngleAxis, PolarRadiusAxis, Radar |
| } from 'recharts'; |
| import { |
| TrendingUp, TrendingDown, Users, DollarSign, ShoppingCart, |
| Activity, Zap, Target, Award, Download, RefreshCw, Eye, |
| BarChart3, PieChart as PieChartIcon, LineChart as LineChartIcon |
| } from 'lucide-react'; |
| import styles from '../styles/EnhancedAnalytics.module.css'; |
|
|
| const EnhancedAnalytics = () => { |
| const [analyticsData, setAnalyticsData] = useState(null); |
| const [selectedPeriod, setSelectedPeriod] = useState('30d'); |
| const [selectedChart, setSelectedChart] = useState('line'); |
| const [isLoading, setIsLoading] = useState(true); |
| const [realTimeData, setRealTimeData] = useState({}); |
| const [lastUpdate, setLastUpdate] = useState(new Date()); |
|
|
| const generateRealTimeData = useCallback(() => { |
| const now = new Date(); |
| const data = { |
| activeUsers: Math.floor(Math.random() * 100) + 50, |
| currentRevenue: Math.floor(Math.random() * 5000) + 2000, |
| pendingOrders: Math.floor(Math.random() * 20) + 5, |
| systemLoad: Math.floor(Math.random() * 30) + 20, |
| timestamp: now |
| }; |
| setRealTimeData(data); |
| setLastUpdate(now); |
| }, []); |
|
|
| const generateAnalyticsData = useCallback(() => { |
| const periods = { |
| '7d': 7, |
| '30d': 30, |
| '90d': 90 |
| }; |
| |
| const days = periods[selectedPeriod]; |
| const data = []; |
| |
| for (let i = days - 1; i >= 0; i--) { |
| const date = new Date(); |
| date.setDate(date.getDate() - i); |
| |
| data.push({ |
| date: date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }), |
| users: Math.floor(Math.random() * 50) + 20, |
| revenue: Math.floor(Math.random() * 5000) + 1000, |
| orders: Math.floor(Math.random() * 30) + 10, |
| conversion: Math.floor(Math.random() * 20) + 5, |
| engagement: Math.floor(Math.random() * 40) + 20 |
| }); |
| } |
| |
| return data; |
| }, [selectedPeriod]); |
|
|
| useEffect(() => { |
| setIsLoading(true); |
| setTimeout(() => { |
| setAnalyticsData(generateAnalyticsData()); |
| generateRealTimeData(); |
| setIsLoading(false); |
| }, 1000); |
| }, [selectedPeriod, generateAnalyticsData, generateRealTimeData]); |
|
|
| useEffect(() => { |
| const interval = setInterval(() => { |
| generateRealTimeData(); |
| }, 8000); |
|
|
| return () => clearInterval(interval); |
| }, [generateRealTimeData]); |
|
|
| const chartColors = { |
| primary: '#3b82f6', |
| secondary: '#1e40af', |
| accent: '#3730a3', |
| success: '#10b981', |
| warning: '#f59e0b', |
| danger: '#ef4444', |
| purple: '#8b5cf6', |
| pink: '#ec4899' |
| }; |
|
|
| const RealTimeMetric = ({ title, value, icon: Icon, color, trend, change }) => ( |
| <motion.div |
| className={styles['real-time-metric']} |
| initial={{ opacity: 0, y: 20 }} |
| animate={{ opacity: 1, y: 0 }} |
| whileHover={{ scale: 1.05, y: -5 }} |
| transition={{ duration: 0.3 }} |
| > |
| <div className={styles['metric-icon']} style={{ background: color }}> |
| <Icon size={24} color="#fff" /> |
| </div> |
| <div className={styles['metric-content']}> |
| <h4>{title}</h4> |
| <div className={styles['metric-value']}> |
| <span className={styles['value']}>{value}</span> |
| {trend && ( |
| <span className={`${styles['trend']} ${styles[trend]}`}> |
| {trend === 'up' ? <TrendingUp size={16} /> : <TrendingDown size={16} />} |
| {change}% |
| </span> |
| )} |
| </div> |
| </div> |
| </motion.div> |
| ); |
|
|
| const EnhancedChart = ({ data, type, title, color, height = 300 }) => { |
| const renderChart = () => { |
| switch (type) { |
| case 'line': |
| return ( |
| <LineChart data={data}> |
| <CartesianGrid strokeDasharray="3 3" stroke="rgba(255,255,255,0.1)" /> |
| <XAxis |
| dataKey="date" |
| tick={{ fill: 'rgba(255,255,255,0.8)', fontSize: 12 }} |
| axisLine={{ stroke: 'rgba(255,255,255,0.2)' }} |
| /> |
| <YAxis |
| tick={{ fill: 'rgba(255,255,255,0.8)', fontSize: 12 }} |
| axisLine={{ stroke: 'rgba(255,255,255,0.2)' }} |
| /> |
| <Tooltip |
| contentStyle={{ |
| background: 'rgba(255,255,255,0.1)', |
| border: '1px solid rgba(255,255,255,0.2)', |
| borderRadius: '12px', |
| color: '#fff', |
| backdropFilter: 'blur(20px)' |
| }} |
| /> |
| <Line |
| type="monotone" |
| dataKey="users" |
| stroke={color} |
| strokeWidth={3} |
| dot={{ fill: color, strokeWidth: 2, r: 6 }} |
| activeDot={{ r: 8, stroke: color, strokeWidth: 2 }} |
| /> |
| </LineChart> |
| ); |
| |
| case 'area': |
| return ( |
| <AreaChart data={data}> |
| <CartesianGrid strokeDasharray="3 3" stroke="rgba(255,255,255,0.1)" /> |
| <XAxis |
| dataKey="date" |
| tick={{ fill: 'rgba(255,255,255,0.8)', fontSize: 12 }} |
| axisLine={{ stroke: 'rgba(255,255,255,0.2)' }} |
| /> |
| <YAxis |
| tick={{ fill: 'rgba(255,255,255,0.8)', fontSize: 12 }} |
| axisLine={{ stroke: 'rgba(255,255,255,0.2)' }} |
| /> |
| <Tooltip |
| contentStyle={{ |
| background: 'rgba(255,255,255,0.1)', |
| border: '1px solid rgba(255,255,255,0.2)', |
| borderRadius: '12px', |
| color: '#fff', |
| backdropFilter: 'blur(20px)' |
| }} |
| /> |
| <Area |
| type="monotone" |
| dataKey="revenue" |
| stroke={color} |
| fill={`${color}40`} |
| strokeWidth={2} |
| /> |
| </AreaChart> |
| ); |
| |
| case 'bar': |
| return ( |
| <BarChart data={data}> |
| <CartesianGrid strokeDasharray="3 3" stroke="rgba(255,255,255,0.1)" /> |
| <XAxis |
| dataKey="date" |
| tick={{ fill: 'rgba(255,255,255,0.8)', fontSize: 12 }} |
| axisLine={{ stroke: 'rgba(255,255,255,0.2)' }} |
| /> |
| <YAxis |
| tick={{ fill: 'rgba(255,255,255,0.8)', fontSize: 12 }} |
| axisLine={{ stroke: 'rgba(255,255,255,0.2)' }} |
| /> |
| <Tooltip |
| contentStyle={{ |
| background: 'rgba(255,255,255,0.1)', |
| border: '1px solid rgba(255,255,255,0.2)', |
| borderRadius: '12px', |
| color: '#fff', |
| backdropFilter: 'blur(20px)' |
| }} |
| /> |
| <Bar |
| dataKey="orders" |
| fill={color} |
| radius={[8, 8, 0, 0]} |
| /> |
| </BarChart> |
| ); |
| |
| default: |
| return null; |
| } |
| }; |
|
|
| return ( |
| <motion.div |
| className={styles['enhanced-chart-card']} |
| initial={{ opacity: 0, y: 20 }} |
| animate={{ opacity: 1, y: 0 }} |
| whileHover={{ y: -5 }} |
| transition={{ duration: 0.3 }} |
| > |
| <div className={styles['chart-header']}> |
| <h3>{title}</h3> |
| <div className={styles['chart-actions']}> |
| <button |
| className={`${styles['chart-type-btn']} ${selectedChart === 'line' ? styles['active'] : ''}`} |
| onClick={() => setSelectedChart('line')} |
| > |
| <LineChartIcon size={16} /> |
| </button> |
| <button |
| className={`${styles['chart-type-btn']} ${selectedChart === 'area' ? styles['active'] : ''}`} |
| onClick={() => setSelectedChart('area')} |
| > |
| <BarChart3 size={16} /> |
| </button> |
| <button |
| className={`${styles['chart-type-btn']} ${selectedChart === 'bar' ? styles['active'] : ''}`} |
| onClick={() => setSelectedChart('bar')} |
| > |
| <PieChartIcon size={16} /> |
| </button> |
| </div> |
| </div> |
| <div className={styles['chart-container']} style={{ height }}> |
| <ResponsiveContainer width="100%" height="100%"> |
| {renderChart()} |
| </ResponsiveContainer> |
| </div> |
| </motion.div> |
| ); |
| }; |
|
|
| if (isLoading) { |
| return ( |
| <div className={styles['analytics-loading']}> |
| <motion.div |
| className={styles['loading-spinner']} |
| animate={{ rotate: 360 }} |
| transition={{ duration: 1, repeat: Infinity, ease: "linear" }} |
| > |
| <Activity size={40} /> |
| </motion.div> |
| <motion.h2 |
| initial={{ opacity: 0 }} |
| animate={{ opacity: 1 }} |
| transition={{ delay: 0.5 }} |
| > |
| Loading Analytics... |
| </motion.h2> |
| </div> |
| ); |
| } |
|
|
| return ( |
| <div className={styles['enhanced-analytics']}> |
| {} |
| <motion.div |
| className={styles['analytics-header']} |
| initial={{ opacity: 0, y: -20 }} |
| animate={{ opacity: 1, y: 0 }} |
| transition={{ duration: 0.5 }} |
| > |
| <div className={styles['header-left']}> |
| <h1>Analytics & Reports</h1> |
| <p>Real-time insights and performance metrics</p> |
| <div className={styles['live-indicator']}> |
| <div className={styles['live-dot']}></div> |
| <span>Live Data</span> |
| <span>•</span> |
| <span>Last updated: {lastUpdate.toLocaleTimeString()}</span> |
| </div> |
| </div> |
| <div className={styles['header-right']}> |
| <select |
| value={selectedPeriod} |
| onChange={(e) => setSelectedPeriod(e.target.value)} |
| className={styles['period-select']} |
| > |
| <option value="7d">Last 7 days</option> |
| <option value="30d">Last 30 days</option> |
| <option value="90d">Last 90 days</option> |
| </select> |
| <motion.button |
| className={styles['export-btn']} |
| whileHover={{ scale: 1.05 }} |
| whileTap={{ scale: 0.95 }} |
| > |
| <Download size={20} /> |
| Export Report |
| </motion.button> |
| </div> |
| </motion.div> |
| |
| {} |
| <motion.div |
| className={styles['real-time-metrics']} |
| initial={{ opacity: 0, y: 20 }} |
| animate={{ opacity: 1, y: 0 }} |
| transition={{ duration: 0.5, delay: 0.2 }} |
| > |
| <RealTimeMetric |
| title="Active Users" |
| value={realTimeData.activeUsers} |
| icon={Users} |
| color={chartColors.primary} |
| trend="up" |
| change="12" |
| /> |
| <RealTimeMetric |
| title="Current Revenue" |
| value={`$${realTimeData.currentRevenue?.toLocaleString()}`} |
| icon={DollarSign} |
| color={chartColors.success} |
| trend="up" |
| change="8" |
| /> |
| <RealTimeMetric |
| title="Pending Orders" |
| value={realTimeData.pendingOrders} |
| icon={ShoppingCart} |
| color={chartColors.warning} |
| trend="down" |
| change="3" |
| /> |
| <RealTimeMetric |
| title="System Load" |
| value={`${realTimeData.systemLoad}%`} |
| icon={Activity} |
| color={chartColors.purple} |
| trend="up" |
| change="5" |
| /> |
| </motion.div> |
| |
| {} |
| <motion.div |
| className={styles['charts-grid']} |
| initial={{ opacity: 0, y: 20 }} |
| animate={{ opacity: 1, y: 0 }} |
| transition={{ duration: 0.5, delay: 0.4 }} |
| > |
| <EnhancedChart |
| data={analyticsData} |
| type={selectedChart} |
| title="User Growth" |
| color={chartColors.primary} |
| height={300} |
| /> |
| <EnhancedChart |
| data={analyticsData} |
| type="area" |
| title="Revenue Analytics" |
| color={chartColors.success} |
| height={300} |
| /> |
| <EnhancedChart |
| data={analyticsData} |
| type="bar" |
| title="Order Analytics" |
| color={chartColors.warning} |
| height={300} |
| /> |
| </motion.div> |
| |
| {} |
| <motion.div |
| className={styles['performance-metrics']} |
| initial={{ opacity: 0, y: 20 }} |
| animate={{ opacity: 1, y: 0 }} |
| transition={{ duration: 0.5, delay: 0.6 }} |
| > |
| <div className={styles['metric-card']}> |
| <div className={styles['metric-header']}> |
| <h3>Conversion Rate</h3> |
| <Target size={20} color={chartColors.primary} /> |
| </div> |
| <div className={styles['metric-value']}>24.5%</div> |
| <div className={`${styles['metric-trend']} ${styles['positive']}`}> |
| <TrendingUp size={16} /> |
| +2.3% from last month |
| </div> |
| </div> |
| <div className={styles['metric-card']}> |
| <div className={styles['metric-header']}> |
| <h3>Average Order Value</h3> |
| <Award size={20} color={chartColors.success} /> |
| </div> |
| <div className={styles['metric-value']}>$156.78</div> |
| <div className={`${styles['metric-trend']} ${styles['positive']}`}> |
| <TrendingUp size={16} /> |
| +5.7% from last month |
| </div> |
| </div> |
| <div className={styles['metric-card']}> |
| <div className={styles['metric-header']}> |
| <h3>Customer Satisfaction</h3> |
| <Zap size={20} color={chartColors.warning} /> |
| </div> |
| <div className={styles['metric-value']}>4.8/5.0</div> |
| <div className={`${styles['metric-trend']} ${styles['positive']}`}> |
| <TrendingUp size={16} /> |
| +0.2 from last month |
| </div> |
| </div> |
| </motion.div> |
| </div> |
| ); |
| }; |
|
|
| export default EnhancedAnalytics; |