'use client'; import React from 'react'; import { cn } from '../../lib/utils'; import { Star, Quote } from 'lucide-react'; export interface TestimonialCardProps { quote: string; author?: string; role?: string; company?: string; rating?: number; avatar?: string; variant?: 'default' | 'highlight' | 'compact'; className?: string; } /** * TestimonialCard Component * Displays customer testimonials with optional ratings and author info * Maps to WordPress testimonial patterns and quote blocks */ export const TestimonialCard: React.FC = ({ quote, author, role, company, rating = 0, avatar, variant = 'default', className = '' }) => { // Generate star rating const renderStars = () => { if (!rating || rating === 0) return null; const stars = []; const fullStars = Math.floor(rating); const hasHalfStar = rating % 1 >= 0.5; for (let i = 0; i < fullStars; i++) { stars.push( ); } if (hasHalfStar) { stars.push( ); } const emptyStars = 5 - stars.length; for (let i = 0; i < emptyStars; i++) { stars.push( ); } return
{stars}
; }; // Variant-specific styles const variantStyles = { default: 'bg-white border border-gray-200 shadow-sm', highlight: 'bg-gradient-to-br from-primary/5 to-secondary/5 border-primary/20 shadow-lg', compact: 'bg-gray-50 border border-gray-100 shadow-sm' }; const paddingStyles = { default: 'p-6 md:p-8', highlight: 'p-6 md:p-8', compact: 'p-4 md:p-6' }; const quoteIconStyles = { default: 'w-8 h-8 text-primary/30', highlight: 'w-10 h-10 text-primary/50', compact: 'w-6 h-6 text-primary/30' }; return (
{/* Quote Icon */}
{/* Main Content */}
{/* Quote Text */}
"{quote}"
{/* Rating */} {rating > 0 && (
{renderStars()} {rating.toFixed(1)}
)} {/* Author Info */} {(author || role || company || avatar) && (
{/* Avatar */} {avatar && (
{author
)} {/* Author Details */}
{author && (
{author}
)} {(role || company) && (
{[role, company].filter(Boolean).join(' • ')}
)}
)}
{/* Decorative corner accent for highlight variant */} {variant === 'highlight' && (
)}
); }; // Helper function to parse WordPress testimonial content export function parseWpTestimonial(content: string): Partial { // This would parse WordPress testimonial patterns // For now, returns basic structure return { quote: content.replace(/<[^>]*>/g, '').trim().substring(0, 300) // Strip HTML, limit length }; } // Grid wrapper for multiple testimonials export const TestimonialGrid: React.FC<{ testimonials: TestimonialCardProps[]; columns?: 1 | 2 | 3; gap?: 'sm' | 'md' | 'lg'; className?: string; }> = ({ testimonials, columns = 2, gap = 'md', className = '' }) => { const gapStyles = { sm: 'gap-4', md: 'gap-6', lg: 'gap-8' }; const columnStyles = { 1: 'grid-cols-1', 2: 'grid-cols-1 md:grid-cols-2', 3: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3' }; return (
{testimonials.map((testimonial, index) => ( ))}
); }; export default TestimonialCard;