import Image from "next/image"; import Link from "next/link"; import { MapPin, CalendarDays, UserRound, BadgeCheck, Sparkles, } from "lucide-react"; import { formatRupiah } from "@/lib/utils"; import { formatTripCalendarDateRangeLong } from "@/lib/trip-dates"; import { categoryMeta } from "@/lib/activity-category"; import { vibeMeta } from "@/lib/vibe"; import type { ActivityCategory, Vibe } from "@/app/generated/prisma/enums"; interface TripCardParticipant { id: string; name: string; image: string | null; interests: string[]; } interface TripCardProps { id: string; title: string; category: ActivityCategory; vibe?: Vibe | null; destination: string; location: string; date: Date | string; endDate?: Date | string | null; price: number; maxParticipants: number; participantCount: number; organizerName: string; status: string; coverImage?: string | null; priority?: boolean; isVerifiedOrganizer?: boolean; /** Daftar peserta CONFIRMED (subset, untuk preview avatar). Optional. */ participants?: TripCardParticipant[]; /** Interests user yang sedang melihat — untuk hitung overlap. Optional. */ viewerInterests?: string[]; } export function TripCard({ id, title, category, vibe, destination, location, date, endDate, price, maxParticipants, participantCount, organizerName, status, coverImage, priority, isVerifiedOrganizer, participants, viewerInterests, }: TripCardProps) { const spotsLeft = maxParticipants - participantCount; const isSmallGroup = maxParticipants <= 10; const meta = categoryMeta(category); const vMeta = vibe ? vibeMeta(vibe) : null; const previewParticipants = participants?.slice(0, 3) ?? []; const moreCount = participants && participants.length > 3 ? participants.length - 3 : 0; let overlapCount = 0; if (viewerInterests && viewerInterests.length > 0 && participants) { const viewerSet = new Set(viewerInterests.map((i) => i.toLowerCase())); overlapCount = participants.filter((p) => p.interests.some((tag) => viewerSet.has(tag.toLowerCase())) ).length; } return (
{destination}