mirror of
https://github.com/vercel/flags.git
synced 2026-09-19 03:49:23 +08:00
64 lines
2.0 KiB
TypeScript
64 lines
2.0 KiB
TypeScript
import { headers } from 'next/headers';
|
|
import type { Review } from '#/types/review';
|
|
import { ProductReviewCard } from '#/components/product-review-card';
|
|
import { delayReviews } from '#/lib/constants';
|
|
|
|
export async function Reviews({ showRating }: { showRating: boolean }) {
|
|
const headersStore = await headers();
|
|
const skipDelay = headersStore.has('next-action');
|
|
const reviews = await fetch(
|
|
// We intentionally delay the response to simulate a slow data
|
|
// request that would benefit from streaming
|
|
`https://app-playground-api.vercel.app/api/reviews?delay=${
|
|
skipDelay ? 0 : delayReviews
|
|
}`,
|
|
{
|
|
// We intentionally disable Next.js Cache to better demo
|
|
// streaming
|
|
cache: 'no-store',
|
|
},
|
|
).then<Review[]>((res) => res.json());
|
|
|
|
return (
|
|
<div className="space-y-6" data-headers={headersStore}>
|
|
<div className="text-lg font-medium text-white">Customer Reviews</div>
|
|
<div className="space-y-8">
|
|
{reviews.map((review) => {
|
|
return (
|
|
<ProductReviewCard
|
|
key={review.id}
|
|
review={review}
|
|
showRating={showRating}
|
|
/>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const shimmer = `relative overflow-hidden before:absolute before:inset-0 before:-translate-x-full before:animate-[shimmer_1.5s_infinite] before:bg-gradient-to-r before:from-transparent before:via-white/10 before:to-transparent`;
|
|
|
|
function Skeleton() {
|
|
return (
|
|
<div className="space-y-4">
|
|
<div className="h-6 w-2/6 rounded-lg bg-gray-900" />
|
|
<div className="h-4 w-1/6 rounded-lg bg-gray-900" />
|
|
<div className="h-4 w-full rounded-lg bg-gray-900" />
|
|
<div className="h-4 w-4/6 rounded-lg bg-gray-900" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function ReviewsSkeleton() {
|
|
return (
|
|
<div className="space-y-6">
|
|
<div className={`h-7 w-2/5 rounded-lg bg-gray-900 ${shimmer}`} />
|
|
<div className="space-y-8">
|
|
<Skeleton />
|
|
<Skeleton />
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|