'use client'; import { Activity, Anchor, MapPin, MoreHorizontal, Pencil } from 'lucide-react'; import { useRouter, useParams } from 'next/navigation'; import { Button } from '@/components/ui/button'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; import { TagBadge } from '@/components/shared/tag-badge'; import { ListCard, ListCardAvatar, ListCardMeta } from '@/components/shared/list-card'; import { cn } from '@/lib/utils'; import type { BerthRow } from './berth-columns'; const STATUS_VARIANTS: Record = { available: 'bg-green-100 text-green-800 border-green-200', under_offer: 'bg-yellow-100 text-yellow-800 border-yellow-200', sold: 'bg-red-100 text-red-800 border-red-200', }; const STATUS_LABELS: Record = { available: 'Available', under_offer: 'Under Offer', sold: 'Sold', }; const ACCENT_CLASS: Record = { available: 'bg-emerald-400', under_offer: 'bg-amber-400', sold: 'bg-slate-400', }; function formatPrice(price: string, currency: string): string { try { return new Intl.NumberFormat('en-US', { style: 'currency', currency: currency || 'USD', maximumFractionDigits: 0, }).format(Number(price)); } catch { return `${currency} ${price}`; } } interface BerthCardProps { berth: BerthRow; } export function BerthCard({ berth }: BerthCardProps) { const router = useRouter(); const params = useParams<{ portSlug: string }>(); const portSlug = params?.portSlug ?? ''; const statusLabel = STATUS_LABELS[berth.status] ?? berth.status; const statusColor = STATUS_VARIANTS[berth.status] ?? 'bg-muted text-muted-foreground border-muted'; const accentClass = ACCENT_CLASS[berth.status] ?? 'bg-slate-300'; // Dimensions string let dimText: string | null = null; if (berth.lengthM || berth.widthM) { const l = berth.lengthM ?? '?'; const w = berth.widthM ?? '?'; dimText = `${l}m × ${w}m`; } const metaParts: string[] = []; if (dimText) metaParts.push(dimText); if (berth.price) metaParts.push(formatPrice(berth.price, berth.priceCurrency)); const tags = berth.tags ?? []; return ( { e.stopPropagation(); router.push(`/${portSlug}/berths/${berth.id}`); }} > View details { e.stopPropagation(); router.push(`/${portSlug}/berths/${berth.id}?edit=true`); }} > Edit } >
} />
{/* Title row + spacer for actions button */}

{berth.mooringNumber}

{/* Area subtitle */} {berth.area ? (

{berth.area}

) : null} {/* Dimensions · Price meta line */} {metaParts.length > 0 ? (
{metaParts.map((part, i) => ( {i > 0 ? · : null} {part} ))}
) : null} {/* Status pill */}
{statusLabel}
{/* Tags */} {tags.length > 0 ? (
{tags.slice(0, 2).map((tag) => ( ))} {tags.length > 2 ? ( +{tags.length - 2} ) : null}
) : null}
); }