feat: compare (premium), rating-history trend, hover previews
Build & Push Docker Image / build (push) Successful in 2m47s

This commit is contained in:
opencode
2026-08-02 12:48:02 +02:00
parent 0c27982098
commit c77610786b
18 changed files with 911 additions and 13 deletions
+35 -1
View File
@@ -7,6 +7,8 @@ import {
getListToolRatingsQueryKey,
useGetRatingDistribution,
getGetRatingDistributionQueryKey,
useGetToolRatingHistory,
getGetToolRatingHistoryQueryKey,
useCreateRating,
getGetTopToolsQueryKey,
getGetAnalyticsSummaryQueryKey,
@@ -38,7 +40,7 @@ import {
SelectValue,
} from "@/components/ui/select";
import { useToast } from "@/hooks/use-toast";
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from "recharts";
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, LineChart, Line, Legend } from "recharts";
import { ExternalLink, Star, ArrowLeft, Plus, Pencil, Trash2, Link as LinkIcon, DollarSign, Euro } from "lucide-react";
import { Link } from "wouter";
import { useAuth } from "@/hooks/use-auth";
@@ -203,6 +205,10 @@ export default function ToolDetail() {
query: { enabled: !!id, queryKey: getGetRatingDistributionQueryKey({ toolId: id }) }
});
const { data: ratingHistory, isLoading: loadingRatingHistory } = useGetToolRatingHistory(id, {
query: { enabled: !!id, queryKey: getGetToolRatingHistoryQueryKey(id) }
});
const createRating = useCreateRating();
const form = useForm<RatingFormValues>({
@@ -695,6 +701,34 @@ export default function ToolDetail() {
)}
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle>Score Trend</CardTitle>
</CardHeader>
<CardContent>
{loadingRatingHistory ? (
<Skeleton className="h-48 w-full" />
) : ratingHistory && ratingHistory.length > 1 ? (
<div className="h-48">
<ResponsiveContainer width="100%" height="100%">
<LineChart data={ratingHistory} margin={{ top: 5, right: 10, bottom: 0, left: -20 }}>
<CartesianGrid strokeDasharray="3 3" opacity={0.2} />
<XAxis dataKey="date" hide />
<YAxis domain={[0, 5]} tick={{ fill: 'hsl(var(--foreground))', fontSize: 12 }} axisLine={false} tickLine={false} />
<Tooltip labelFormatter={(_, payload) => (payload?.[0] ? format(new Date(payload[0].payload.date), "dd.MM.yyyy HH:mm") : "")} />
<Legend wrapperStyle={{ fontSize: 12 }} />
<Line type="monotone" dataKey="combined" name="Combined" stroke="hsl(var(--primary))" strokeWidth={2} dot={false} />
<Line type="monotone" dataKey="usefulness" name="Usefulness" stroke="hsl(var(--success))" strokeWidth={1.5} dot={false} strokeDasharray="4 3" />
<Line type="monotone" dataKey="usability" name="Usability" stroke="hsl(var(--warning))" strokeWidth={1.5} dot={false} strokeDasharray="4 3" />
</LineChart>
</ResponsiveContainer>
</div>
) : (
<p className="text-sm text-muted-foreground">Not enough ratings yet to show a trend.</p>
)}
</CardContent>
</Card>
</div>
{/* Right Column: Reviews */}