Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | 'use client';
import { useState, useCallback } from 'react';
import { ReviewList } from './ReviewList';
import { ReviewForm } from './ReviewForm';
import { cn } from '@/lib/core';
export interface ReviewSectionProps {
productId: number;
showForm?: boolean;
className?: string;
}
/**
* ReviewSection - Complete reviews section with list and form
*
* Combines ReviewList and ReviewForm into a single component
* with automatic refresh when a new review is submitted.
*
* @example
* ```tsx
* <ReviewSection productId={123} />
*
* // Without form (read-only)
* <ReviewSection productId={123} showForm={false} />
* ```
*/
export function ReviewSection({
productId,
showForm = true,
className}: ReviewSectionProps) {
const [refreshKey, setRefreshKey] = useState(0);
const handleReviewSubmitted = useCallback(() => {
// Trigger a refresh of the reviews list
setRefreshKey((k) => k + 1);
}, []);
return (
<section className={cn('space-y-8', className)}>
<h2 className="text-2xl font-bold">Customer Reviews</h2>
{/* Reviews List */}
<ReviewList key={refreshKey} productId={productId} />
{/* Review Form - below existing reviews */}
{showForm && (
<ReviewForm productId={productId} onSuccess={handleReviewSubmitted} />
)}
</section>
);
}
|