'use client';
import {
BadgeCheck,
Building2,
Calendar,
MapPin,
Phone,
Mail,
Star,
Home,
MessageSquare,
} from 'lucide-react';
import Image from 'next/image';
import * as React from 'react';
import { InquiryModal } from '@/components/listings/inquiry-modal';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Link } from '@/i18n/navigation';
import type { AgentPublicProfile, AgentReviewItem } from '@/lib/agents-api';
import { formatPrice } from '@/lib/currency';
import { shimmerBlurDataURL } from '@/lib/image-blur';
// ---------------------------------------------------------------------------
// Props
// ---------------------------------------------------------------------------
interface AgentProfileClientProps {
agent: AgentPublicProfile;
reviews: AgentReviewItem[];
}
// ---------------------------------------------------------------------------
// Main Component
// ---------------------------------------------------------------------------
export function AgentProfileClient({ agent, reviews }: AgentProfileClientProps) {
const [inquiryOpen, setInquiryOpen] = React.useState(false);
const firstListing = agent.activeListings[0] ?? null;
const handleMessageClick = React.useCallback(() => {
if (firstListing) {
setInquiryOpen(true);
} else {
window.location.href = `sms:${agent.phone}`;
}
}, [firstListing, agent.phone]);
return (
{/* Breadcrumb */}
{/* Profile Header */}
{/* Avatar */}
{agent.avatarUrl ? (
) : (
{agent.fullName.charAt(0).toUpperCase()}
)}
{/* Agent Info */}
{agent.fullName}
{agent.isVerified && (
Đã xác minh
)}
{agent.agency && (
{agent.agency}
)}
{agent.licenseNumber && (
Mã giấy phép: {agent.licenseNumber}
)}
Thành viên từ {new Date(agent.memberSince).toLocaleDateString('vi-VN', {
month: 'long',
year: 'numeric',
})}
{/* Quick stats */}
}
label="Đánh giá"
value={agent.totalReviews > 0
? `${agent.avgReviewRating}/5 (${agent.totalReviews})`
: 'Chưa có'}
/>
}
label="Tin đăng"
value={`${agent.activeListings.length}`}
/>
}
label="Giao dịch"
value={`${agent.totalDeals}`}
/>
{/* CTA Sidebar (desktop) */}
{/* Main Content */}
{/* Bio */}
{agent.bio && (
Giới thiệu
{agent.bio}
)}
{/* Service Areas */}
{agent.serviceAreas.length > 0 && (
Khu vực hoạt động
{agent.serviceAreas.map((area) => (
{area}
))}
)}
{/* Quality Score */}
Chỉ số chất lượng
{agent.qualityScore >= 80
? 'Xuất sắc'
: agent.qualityScore >= 60
? 'Tốt'
: agent.qualityScore >= 40
? 'Trung bình'
: 'Cần cải thiện'}
Dựa trên phản hồi, thời gian phản hồi và giao dịch thành công
{/* Active Listings */}
{agent.activeListings.length > 0 && (
Tin đăng đang hoạt động ({agent.activeListings.length})
{agent.activeListings.map((listing) => (
))}
)}
{/* Reviews */}
Đánh giá ({agent.totalReviews})
{reviews.length > 0 ? (
{reviews.map((review) => (
))}
) : (
Chưa có đánh giá nào
)}
{/* Sidebar (mobile + desktop fallback) */}
{firstListing && (
)}
);
}
// ---------------------------------------------------------------------------
// Sub-Components
// ---------------------------------------------------------------------------
function StatPill({
icon,
label,
value,
}: {
icon: React.ReactNode;
label: string;
value: string;
}) {
return (
);
}
function ContactCard({ agent, onMessageClick }: { agent: AgentPublicProfile; onMessageClick: () => void }) {
return (
Liên hệ môi giới
{agent.email && (
)}
Số điện thoại
{agent.phone}
{agent.email && (
<>
Email
{agent.email}
>
)}
);
}
function ListingCard({ listing }: { listing: AgentPublicProfile['activeListings'][number] }) {
const { property } = listing;
return (
{/* Image */}
{property.imageUrl ? (
) : (
)}
{listing.transactionType === 'SALE' ? 'Bán' : 'Cho thuê'}
{/* Content */}
{property.title}
{property.district}, {property.city}
{formatPrice(listing.priceVND)} VND
{property.areaM2} m²
{property.bedrooms != null && {property.bedrooms} PN}
);
}
function ReviewCard({ review }: { review: AgentReviewItem }) {
return (
{(review.userName ?? 'Ẩn danh').charAt(0).toUpperCase()}
{review.userName ?? 'Ẩn danh'}
{new Date(review.createdAt).toLocaleDateString('vi-VN')}
{Array.from({ length: 5 }).map((_, i) => (
))}
{review.comment && (
{review.comment}
)}
);
}