mkcart / frontend /src /components /EnhancedAnalytics.jsx
Kumar
updated
c2efbe6
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;