import type { ReactNode } from 'react' import UserIdentity from '@/components/consumer/UserIdentity' import HeatIconFill from '@/components/icons/HeatIconFill' import { formatPersianDate, formatRelativeTimePersian } from '@/lib/formatters' import { texts } from '@/texts' /** Styling-token variant: which surface the card is rendered on. */ export type ReviewCardTone = 'consumer' | 'organizer' interface ReviewCardProps { rating: number createdAt: string body?: string | null hostReplyBody?: string | null tone: ReviewCardTone authorName?: string authorAvatarUrl?: string | null /** When set, avatar + name link to the author's public `/u/:id` profile. */ authorUserId?: string | null /** Optional content rendered between the header row and the body, e.g. an event link. */ headerExtra?: ReactNode footer?: ReactNode className?: string } const TONE_STYLES: Record< ReviewCardTone, { date: string body: string replyContainer: string replyTitle: string replyBody: string useRelativeTime: boolean } > = { consumer: { date: 'text-[10px] font-medium text-secondary-30', body: 'mt-2 text-sm font-medium leading-7 text-secondary-30', replyContainer: 'mt-3 rounded-xl bg-tertiary-900/5 p-3', replyTitle: 'text-xs font-medium text-tertiary-900', replyBody: 'mt-1 text-sm font-medium leading-6 text-secondary-30', useRelativeTime: true, }, organizer: { date: 'text-sm text-tertiary-400', body: 'mt-2 text-sm leading-7 text-tertiary-500', replyContainer: 'mt-3 rounded-xl bg-primary-25 p-3', replyTitle: 'text-xs font-bold text-primary', replyBody: 'mt-1 text-sm leading-6', useRelativeTime: false, }, } /** Shared review list item: author + heart rating + optional body + host reply. */ const ReviewCard = ({ rating, createdAt, body, hostReplyBody, tone, authorName, authorAvatarUrl, authorUserId, headerExtra, footer, className, }: ReviewCardProps) => { const styles = TONE_STYLES[tone] const dateLabel = styles.useRelativeTime ? formatRelativeTimePersian(createdAt) : formatPersianDate(createdAt) return (
  • {dateLabel}

    } userId={authorUserId} variant="circle" />
    {Math.round(rating).toLocaleString('fa-IR')}
    {headerExtra} {body ?

    {body}

    : null} {hostReplyBody ? (

    {texts.reviews.hostReply}

    {hostReplyBody}

    ) : null} {footer}
  • ) } export default ReviewCard