//src/components/dashboard/AnalyticsDashboard.jsx import React, { useState, useEffect } from "react"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Checkbox } from "@/components/ui/checkbox"; import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, } from "recharts"; import { Loader2 } from "lucide-react"; import { googleAnalyticsService } from "../../services/googleAnalyticsService"; export const AnalyticsDashboard = () => { const [data, setData] = useState([]); const [loading, setLoading] = useState(true); const [timeRange, setTimeRange] = useState("30"); useEffect(() => { const fetchData = async () => { setLoading(true); try { const result = await googleAnalyticsService.getBasicMetrics({ startDate: `${timeRange}daysAgo`, }); if (result) { const processedData = result.map((item) => ({ ...item, date: formatGADate(item.date), })); const sortedData = processedData.sort((a, b) => a.date - b.date); setData(sortedData); } else { console.log("No result data received"); } } catch (error) { console.error("Failed to fetch analytics:", error); } finally { setLoading(false); } }; fetchData(); }, [timeRange]); const formatGADate = (gaDate) => { const year = gaDate.substring(0, 4); const month = gaDate.substring(4, 6); const day = gaDate.substring(6, 8); return new Date(year, month - 1, day); }; const [selectedMetrics, setSelectedMetrics] = useState({ activeUsers: true, newUsers: true, pageViews: true, conversions: true, }); const MetricToggle = ({ label, checked, onChange }) => (
); const CustomLegend = ({ metrics, selectedMetrics }) => { // Separate items for left and right axes const leftAxisItems = Object.entries(metrics).filter( ([key, metric]) => metric.yAxis === "left" && selectedMetrics[key] ); const rightAxisItems = Object.entries(metrics).filter( ([key, metric]) => metric.yAxis === "right" && selectedMetrics[key] ); return (

Left Axis

{leftAxisItems.map(([key, metric]) => (
{metric.label}
))}

Right Axis

{rightAxisItems.map(([key, metric]) => (
{metric.label}
))}
); }; const metrics = { activeUsers: { label: "Active Users", color: "#8b5cf6" }, newUsers: { label: "New Users", color: "#10b981" }, pageViews: { label: "Page Views", color: "#f59e0b" }, conversions: { label: "Conversions", color: "#3b82f6" }, }; const calculateSummary = () => { if (!data.length) return null; const totals = data.reduce( (acc, day) => ({ activeUsers: acc.activeUsers + (Number(day.activeUsers) || 0), newUsers: acc.newUsers + (Number(day.newUsers) || 0), pageViews: acc.pageViews + (Number(day.pageViews) || 0), conversions: acc.conversions + (Number(day.conversions) || 0), avgSessionDuration: acc.avgSessionDuration + (Number(day.avgSessionDuration) || 0), bounceRate: acc.bounceRate + (Number(day.bounceRate) || 0), }), { activeUsers: 0, newUsers: 0, pageViews: 0, conversions: 0, avgSessionDuration: 0, bounceRate: 0, } ); return { ...totals, avgSessionDuration: totals.avgSessionDuration / data.length, bounceRate: totals.bounceRate / data.length, }; }; const summary = calculateSummary(); if (loading) { return ( ); } const formatXAxisDate = (date) => { if (!(date instanceof Date)) return ""; return `${date.getMonth() + 1}/${date.getDate()}`; }; const CustomTooltip = ({ active, payload, label }) => { if (active && payload && payload.length) { return (

{label instanceof Date ? label.toLocaleDateString() : label}

{payload.map((entry, index) => (

{`${entry.name}: ${Number(entry.value).toLocaleString()}`}

))}
); } return null; }; return (
Analytics Overview
{summary && (
Total Users
{summary.activeUsers.toLocaleString()}
New Users
{summary.newUsers.toLocaleString()}
Page Views
{summary.pageViews.toLocaleString()}
Conversions
{summary.conversions.toLocaleString()}
)}
setSelectedMetrics((prev) => ({ ...prev, activeUsers: checked })) } /> setSelectedMetrics((prev) => ({ ...prev, newUsers: checked })) } /> setSelectedMetrics((prev) => ({ ...prev, pageViews: checked })) } /> setSelectedMetrics((prev) => ({ ...prev, conversions: checked })) } />
} /> ( {value} )} /> {/* Always render Lines and control visibility */} {Object.entries(metrics).map(([key, { color, label }]) => ( ))}
); }; export default AnalyticsDashboard;