···
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";
···
<Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent className="max-w-3xl">
···
<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 font-medium">
···
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { toast } from "@/hooks/use-toast";
+
import { useState, useEffect, useMemo } from "react";
import { getLinkClickStats, getLinkSourceStats } from "../api/client";
import { ClickStats, SourceStats } from "../types/api";
···
+
const aggregatedSources = useMemo(() => {
+
const sourceMap = sourcesData.reduce<Record<string, number>>(
+
(acc, { source, count }) => ({
+
[source]: (acc[source] || 0) + count
+
return Object.entries(sourceMap)
+
.map(([source, count]) => ({ source, count }))
+
.sort((a, b) => b.count - a.count);
<Dialog open={isOpen} onOpenChange={onClose}>
<DialogContent className="max-w-3xl">
···
<ul className="space-y-2">
+
{aggregatedSources.map((source, index) => (
className="flex items-center justify-between py-2 border-b last:border-0"
···
+
<span className="text-sm font-medium">{source.count} clicks</span>