Fertig
This commit is contained in:
76
components/testimonials-carousel.tsx
Normal file
76
components/testimonials-carousel.tsx
Normal file
@@ -0,0 +1,76 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
type Review = {
|
||||
name: string;
|
||||
rating: string;
|
||||
dateLabel: string;
|
||||
quote: string;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
reviews: Review[];
|
||||
};
|
||||
|
||||
function StarRating({ rating }: { rating: string }) {
|
||||
const score = parseFloat(rating);
|
||||
const full = Math.floor(score);
|
||||
return (
|
||||
<div className="tc-stars" aria-label={`${rating} stars`}>
|
||||
{Array.from({ length: 5 }).map((_, i) => (
|
||||
<span key={i} className={i < full ? "tc-star filled" : "tc-star"}>
|
||||
★
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ReviewCard({ review }: { review: Review }) {
|
||||
return (
|
||||
<motion.article
|
||||
className="tc-card"
|
||||
whileHover={{ y: -6, boxShadow: "0 20px 40px rgba(0,0,0,0.12)" }}
|
||||
transition={{ duration: 0.25, ease: "easeOut" }}
|
||||
>
|
||||
<div className="tc-card-top">
|
||||
<StarRating rating={review.rating} />
|
||||
<span className="tc-date">{review.dateLabel}</span>
|
||||
</div>
|
||||
<blockquote className="tc-quote">"{review.quote}"</blockquote>
|
||||
<footer className="tc-author">
|
||||
<div className="tc-avatar" aria-hidden="true">
|
||||
{review.name[0]}
|
||||
</div>
|
||||
<div>
|
||||
<strong className="tc-name">{review.name}</strong>
|
||||
<span className="tc-source">Google Review</span>
|
||||
</div>
|
||||
</footer>
|
||||
</motion.article>
|
||||
);
|
||||
}
|
||||
|
||||
export function TestimonialsCarousel({ reviews }: Props) {
|
||||
// Triple the items for a seamless infinite loop at any scroll speed
|
||||
const tripled = [...reviews, ...reviews, ...reviews];
|
||||
|
||||
return (
|
||||
<div className="tc-wrapper">
|
||||
<div className="tc-track-container">
|
||||
<div className="tc-track">
|
||||
{tripled.map((review, i) => (
|
||||
<div className="tc-slide" key={i}>
|
||||
<ReviewCard review={review} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Edge fade overlays */}
|
||||
<div className="tc-fade-left" aria-hidden="true" />
|
||||
<div className="tc-fade-right" aria-hidden="true" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user