Merge version_7 into main #7
@@ -8,6 +8,82 @@ import { Star } from "lucide-react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import type { ButtonConfig, ButtonAnimationType, CardAnimationTypeWith3D, GridVariant, TitleSegment, TextboxLayout, InvertedBackground } from "@/components/cardStack/types";
|
||||
|
||||
const TestimonialCardFlip = memo(({ testimonial, className }: { testimonial: Testimonial; className?: string }) => {
|
||||
const [isFlipped, setIsFlipped] = useState(false);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cls(
|
||||
"h-full cursor-pointer perspective",
|
||||
className
|
||||
)}
|
||||
onClick={() => setIsFlipped(!isFlipped)}
|
||||
onMouseEnter={() => setIsFlipped(true)}
|
||||
onMouseLeave={() => setIsFlipped(false)}
|
||||
style={{
|
||||
perspective: "1000px",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
transformStyle: "preserve-3d",
|
||||
transform: isFlipped ? "rotateY(180deg)" : "rotateY(0deg)",
|
||||
transition: "transform 0.6s ease-in-out",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
}}
|
||||
>
|
||||
{/* Front side - Name and Photo */}
|
||||
<div
|
||||
style={{
|
||||
backfaceVisibility: "hidden",
|
||||
WebkitBackfaceVisibility: "hidden",
|
||||
}}
|
||||
className="w-full h-full flex flex-col items-center justify-center p-6 bg-gradient-to-br from-slate-50 to-slate-100 dark:from-slate-900 dark:to-slate-800 rounded-lg border border-slate-200 dark:border-slate-700"
|
||||
>
|
||||
{testimonial.imageSrc && (
|
||||
<img
|
||||
src={testimonial.imageSrc}
|
||||
alt={testimonial.imageAlt || testimonial.name}
|
||||
className="w-24 h-24 rounded-full object-cover mb-4 border-4 border-white dark:border-slate-700 shadow-lg"
|
||||
/>
|
||||
)}
|
||||
<h3 className="text-lg font-semibold text-slate-900 dark:text-white text-center">
|
||||
{testimonial.name}
|
||||
</h3>
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400 text-center mt-1">
|
||||
{testimonial.role}
|
||||
</p>
|
||||
<p className="text-xs text-slate-500 dark:text-slate-500 text-center mt-1">
|
||||
{testimonial.company}
|
||||
</p>
|
||||
<div className="flex gap-1 mt-3">
|
||||
{Array.from({ length: testimonial.rating }).map((_, i) => (
|
||||
<Star key={i} size={16} className="fill-yellow-400 text-yellow-400" />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Back side - Testimonial Text */}
|
||||
<div
|
||||
style={{
|
||||
backfaceVisibility: "hidden",
|
||||
WebkitBackfaceVisibility: "hidden",
|
||||
transform: "rotateY(180deg)",
|
||||
}}
|
||||
className="absolute inset-0 w-full h-full flex flex-col items-center justify-center p-6 bg-gradient-to-br from-blue-50 to-indigo-50 dark:from-blue-900 dark:to-indigo-900 rounded-lg border border-blue-200 dark:border-indigo-700 shadow-lg"
|
||||
>
|
||||
<p className="text-sm text-slate-700 dark:text-slate-200 text-center leading-relaxed italic">
|
||||
"{testimonial.testimonialText || "No testimonial text provided"}"
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
TestimonialCardFlip.displayName = "TestimonialCardFlip";
|
||||
|
||||
type Testimonial = {
|
||||
id: string;
|
||||
name: string;
|
||||
|
||||
Reference in New Issue
Block a user