Code
tsx 53 lines 1.79 KB
Raw
1 import {
2 CardTitle,
3 CardDescription,
4 CardHeader,
5 CardContent,
6 Card,
7 } from "@/components/ui/card";
8 import { Product } from "@/lib/types";
9 import { summarizeReviews } from "@/lib/ai-summary";
10 import { FiveStarRating } from "./five-star-rating";
11
12 export async function AIReviewSummary({ product }: { product: Product }) {
13 const summary = await summarizeReviews(product);
14 const averageRating =
15 product.reviews.reduce((acc, review) => acc + review.stars, 0) /
16 product.reviews.length;
17 return (
18 <Card className="w-full max-w-prose p-10 grid gap-10">
19 <CardHeader className="items-center space-y-0 gap-4 p-0">
20 <div className="grid gap-1 text-center">
21 <CardTitle className="text-lg">Review Summary</CardTitle>
22 <CardDescription className="text-xs">
23 Based on {product.reviews.length} customer ratings
24 </CardDescription>
25 </div>
26 <div className="bg-gray-100 px-3 rounded-full flex items-center py-2 dark:bg-gray-800">
27 <FiveStarRating rating={Math.round(averageRating)} />
28 <span className="text-sm ml-4 text-gray-500 dark:text-gray-400">
29 {numberWithOneDecimal(averageRating)} out of 5
30 </span>
31 <a
32 href="https://maps.app.goo.gl/f4irVqGC9KGHzRDP9"
33 target="_blank"
34 rel="noopener noreferrer"
35 className="ml-6 underline text-xs text-blue-600"
36 >
37 Google page
38 </a>
39 </div>
40 </CardHeader>
41 <CardContent className="p-0 grid gap-4">
42 <p className="text-sm leading-loose text-gray-500 dark:text-gray-400">
43 {summary}
44 </p>
45 </CardContent>
46 </Card>
47 );
48 }
49
50 function numberWithOneDecimal(num: number) {
51 if (num === Math.round(num)) return num;
52 return Math.round(num * 10) / 10;
53 }