BetaUnder active development — content may be incomplete or change without notice.

Testimonial 3

A section with left-aligned header and two testimonials with star ratings.

0px
Loading Preview...

Testimonial 3 is a section with a left-aligned header and description at the top, followed by two testimonials in a 2-column grid (stacks on mobile). Each testimonial includes a star rating, quote, avatar, name, position, and company logo separated by a vertical divider.

Fields Reference

Field NameTypeRequiredLocalizedDescription
headertextYesYesThe main header text for the testimonials section.
descriptionrichtextNoYesA description or subtitle for the testimonials section.
testimonialsarrayYesYesAn array of 1-2 testimonial items.
testimonials.quoterichtextYesYesThe testimonial quote text.
testimonials.avataruploadNoNoAuthor's avatar image referencing the media collection.
testimonials.nametextYesYesThe author's name.
testimonials.positiontextNoYesThe author's position and company name.
testimonials.logouploadNoNoCompany logo image referencing the media collection.
testimonials.ratingnumberNoNoStar rating from 1-5 (defaults to 5).

Code

//@ts-nocheck
import React from 'react'
import { Star, Image as ImageIcon } from "lucide-react"
import RichText from '@/components/cms/RichText'
import { Testimonial3Type } from '@/payload-types'

const Testimonial3Component: React.FC<Testimonial3Type> = ({ header, description, testimonials }: Testimonial3Type) => {
    const StarRating = ({ rating = 5 }: { rating?: number }) => (
        <div className="flex gap-1 mb-4">
            {[...Array(5)].map((_, i) => (
                <Star
                    key={i}
                    className={`w-5 h-5 ${i < rating ? 'fill-foreground text-foreground' : 'fill-muted text-muted'}`}
                />
            ))}
        </div>
    )

    return (
        <section className="w-full min-h-screen bg-background py-16 px-6 md:py-24 lg:py-32">
            <div className="container mx-auto flex flex-col items-start">

                {/* Section Header - Left Aligned */}
                <div className="mb-16 md:mb-20 max-w-2xl text-left">
                    <h1 className="text-4xl md:text-5xl font-semibold tracking-tight text-foreground mb-6">
                        {header}
                    </h1>
                    {description && (
                        <RichText
                            data={description}
                            enableGutter={false}
                            className="mx-0 [&_p]:text-muted-foreground [&_p]:text-lg"
                        />
                    )}
                </div>

                {/* Testimonials Grid */}
                <div className="grid grid-cols-1 lg:grid-cols-2 gap-12 lg:gap-16 w-full">
                    {testimonials?.map((testimonial, index) => (
                        <div key={index} className="flex flex-col items-start text-left gap-6">
                            <StarRating rating={testimonial.rating ?? 5} />

                            {/* Quote */}
                            <blockquote className="text-lg md:text-xl font-semibold leading-relaxed text-foreground mx-0">
                                <RichText
                                    data={testimonial.quote}
                                    enableGutter={false}
                                    className="[&_p]:text-lg [&_p]:md:text-xl [&_p]:font-semibold [&_p]:leading-relaxed [&_p]:text-foreground"
                                />
                            </blockquote>

                            {/* User Info */}
                            <div className="flex items-center gap-4 pt-2">
                                {/* Avatar */}
                                <div className="w-12 h-12 rounded-full bg-muted flex items-center justify-center border border-border overflow-hidden">
                                    {testimonial.avatar && typeof testimonial.avatar === 'object' && testimonial.avatar.url ? (
                                        <img
                                            src={testimonial.avatar.url}
                                            alt={testimonial.avatar.alt || testimonial.name}
                                            className="w-full h-full object-cover"
                                        />
                                    ) : (
                                        <ImageIcon className="w-5 h-5 text-muted-foreground/40" />
                                    )}
                                </div>

                                <div className="flex items-center gap-4 h-10">
                                    <div>
                                        <cite className="not-italic font-semibold text-foreground text-sm block">
                                            {testimonial.name}
                                        </cite>
                                        {testimonial.position && (
                                            <p className="text-muted-foreground text-xs">
                                                {testimonial.position}
                                            </p>
                                        )}
                                    </div>

                                    {/* Vertical Divider */}
                                    {testimonial.logo && typeof testimonial.logo === 'object' && testimonial.logo.url && (
                                        <>
                                            <div className="w-[1px] h-full bg-border" />

                                            {/* Logo */}
                                            <a
                                                href="#"
                                                className="transition-opacity hover:opacity-80"
                                            >
                                                <img
                                                    src={testimonial.logo.url}
                                                    alt={testimonial.logo.alt || 'Company Logo'}
                                                    style={{ width: '120px' }}
                                                    className="h-auto object-contain dark:invert"
                                                />
                                            </a>
                                        </>
                                    )}
                                </div>
                            </div>
                        </div>
                    ))}
                </div>
            </div>
        </section>
    )
}

export default Testimonial3Component