···
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
-
import { toast } from "@/hooks/use-toast"
import { useState, useEffect } from "react";
-
import { getLinkClickStats, getLinkSourceStats } from '../api/client';
-
import { ClickStats, SourceStats } from '../types/api';
interface StatisticsModalProps {
export function StatisticsModal({ isOpen, onClose, linkId }: StatisticsModalProps) {
-
const [clicksOverTime, setClicksOverTime] = useState<ClickStats[]>([]);
-
const [sourcesData, setSourcesData] = useState<SourceStats[]>([]);
-
const [loading, setLoading] = useState(true);
-
if (isOpen && linkId) {
-
const fetchData = async () => {
-
const [clicksData, sourcesData] = await Promise.all([
-
getLinkClickStats(linkId),
-
getLinkSourceStats(linkId),
-
setClicksOverTime(clicksData);
-
setSourcesData(sourcesData);
-
console.error("Failed to fetch statistics:", error);
-
variant: "destructive",
-
description: error.response?.data || "Failed to load statistics",
-
<Dialog open={isOpen} onOpenChange={onClose}>
-
<DialogContent className="max-w-3xl">
-
<DialogTitle>Link Statistics</DialogTitle>
-
<div className="flex items-center justify-center h-64">Loading...</div>
-
<div className="grid gap-4">
-
<CardTitle>Clicks Over Time</CardTitle>
-
<div className="h-[300px]">
-
<ResponsiveContainer width="100%" height="100%">
-
<LineChart data={clicksOverTime}>
-
<CartesianGrid strokeDasharray="3 3" />
-
<XAxis dataKey="date" />
-
<CardTitle>Top Sources</CardTitle>
-
<ul className="space-y-2">
-
{sourcesData.map((source, index) => (
-
className="flex items-center justify-between py-2 border-b last:border-0"
-
<span className="text-sm">
-
<span className="font-medium text-muted-foreground mr-2">
-
<span className="text-sm font-medium">
···
import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
+
import { toast } from "@/hooks/use-toast";
import { useState, useEffect } from "react";
+
import { getLinkClickStats, getLinkSourceStats } from "../api/client";
+
import { ClickStats, SourceStats } from "../types/api";
interface StatisticsModalProps {
+
interface EnhancedClickStats extends ClickStats {
+
sources?: { source: string; count: number }[];
+
const CustomTooltip = ({
+
if (active && payload && payload.length > 0) {
+
const data = payload[0].payload;
+
<div className="bg-background text-foreground p-4 rounded-lg shadow-lg border">
+
<p className="font-medium">{label}</p>
+
<p className="text-sm">Clicks: {data.clicks}</p>
+
{data.sources && data.sources.length > 0 && (
+
<p className="font-medium text-sm">Sources:</p>
+
<ul className="text-sm">
+
{data.sources.map((source: { source: string; count: number }) => (
+
<li key={source.source}>
+
{source.source}: {source.count}
export function StatisticsModal({ isOpen, onClose, linkId }: StatisticsModalProps) {
+
const [clicksOverTime, setClicksOverTime] = useState<EnhancedClickStats[]>([]);
+
const [sourcesData, setSourcesData] = useState<SourceStats[]>([]);
+
const [loading, setLoading] = useState(true);
+
if (isOpen && linkId) {
+
const fetchData = async () => {
+
const [clicksData, sourcesData] = await Promise.all([
+
getLinkClickStats(linkId),
+
getLinkSourceStats(linkId),
+
// Enhance clicks data with source information
+
const enhancedClicksData = clicksData.map((clickData) => ({
+
sources: sourcesData.filter((source) => source.date === clickData.date),
+
setClicksOverTime(enhancedClicksData);
+
setSourcesData(sourcesData);
+
console.error("Failed to fetch statistics:", error);
+
variant: "destructive",
+
description: error.response?.data || "Failed to load statistics",
+
<Dialog open={isOpen} onOpenChange={onClose}>
+
<DialogContent className="max-w-3xl">
+
<DialogTitle>Link Statistics</DialogTitle>
+
<div className="flex items-center justify-center h-64">Loading...</div>
+
<div className="grid gap-4">
+
<CardTitle>Clicks Over Time</CardTitle>
+
<div className="h-[300px]">
+
<ResponsiveContainer width="100%" height="100%">
+
<LineChart data={clicksOverTime}>
+
<CartesianGrid strokeDasharray="3 3" />
+
<XAxis dataKey="date" />
+
<Tooltip content={<CustomTooltip />} />
+
<CardTitle>Top Sources</CardTitle>
+
<ul className="space-y-2">
+
{sourcesData.map((source, index) => (
+
className="flex items-center justify-between py-2 border-b last:border-0"
+
<span className="text-sm">
+
<span className="font-medium text-muted-foreground mr-2">
+
<span className="text-sm font-medium">