"use client"; import { useState, useEffect } from "react"; import { ThumbsUp, ThumbsDown, ExternalLink, MessageSquare } from "lucide-react"; import { cn } from "@/lib/utils"; interface SteamReview { recommendationid: string; author: { steamid: string; playtime_forever: number; }; language: string; review: string; timestamp_created: number; voted_up: boolean; votes_up: number; votes_funny: number; } interface SteamReviewsData { success: number; query_summary: { num_reviews: number; review_score_desc: string; total_positive: number; total_negative: number; total_reviews: number; }; reviews: SteamReview[]; } interface SteamReviewsProps { gameId: string; steamAppId: number; className?: string; } export function SteamReviews({ gameId, steamAppId, className }: SteamReviewsProps) { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [offset, setOffset] = useState(0); const fetchReviews = async (newOffset: number) => { setLoading(true); setError(null); try { const res = await fetch( `/api/steam-reviews/${gameId}?offset=${newOffset}&limit=5&language=english` ); if (!res.ok) { const errData = await res.json().catch(() => null); throw new Error(errData?.error || `HTTP ${res.status}`); } const result = await res.json(); setData(result); setOffset(newOffset); } catch (err) { setError(err instanceof Error ? err.message : "Unknown error"); } finally { setLoading(false); } }; useEffect(() => { fetchReviews(0); }, [gameId]); // Loading skeleton if (loading && !data) { return (
{[...Array(3)].map((_, i) => (
))}
); } // Error state if (error) { return (

Steam reviews unavailable

{error}

View on Steam
); } // No data or no summary if (!data?.query_summary) { return (

No Steam reviews available

View on Steam
); } const { query_summary: summary } = data; const totalReviews = summary.total_reviews ?? 0; const totalPositive = summary.total_positive ?? 0; const positivePercent = totalReviews > 0 ? Math.round((totalPositive / totalReviews) * 100) : 0; // No reviews case if (totalReviews === 0) { return (

No reviews yet

Be the first to review on Steam
); } return (
{/* Summary header */}

Steam Reviews

{summary.review_score_desc ?? "No reviews"} — {positivePercent}% positive ({totalReviews.toLocaleString()} reviews)

View on Steam
{/* Review cards */}
{(data.reviews ?? []).map((review) => (
{review.voted_up ? ( ) : ( )} {review.voted_up ? "Recommended" : "Not Recommended"}
{Math.floor((review.author?.playtime_forever ?? 0) / 60)}h played

{review.review}

{review.votes_up} found helpful {review.votes_funny > 0 && ( {review.votes_funny} funny )}
))}
{/* Pagination */} {totalReviews > 5 && (
Showing {offset + 1}-{Math.min(offset + 5, totalReviews)} of {totalReviews}
)}
); }