feat(fe): trader-style agent profile — TEC-3061
Refactors /agents/[id] from card-avatar layout to a data-dense trading-floor style profile per TEC-3037 §5 mockup. - Profile header: avatar, KYC badge, quality score, years exp, service areas - KPI strip (5 cards): total listings, active, deals, avg price, rating - Performance line chart (12m): published vs sold, derived from real listings - Listings table (DataTable): sortable by price/area/views/inquiries, dense rows - Reviews panel: EmptyState when none, ReviewRow cards otherwise - Sticky right sidebar: contact card + quality donut + bio - fetchAgentListings() server fn (agents-server.ts) via GET /listings?agentId - SearchListingsParams.agentId added (listings-api.ts) - page.tsx fetches listings in parallel with agent + reviews - Test suite updated for new props (listings/listingsTotal) + new text copy - Web unit tests: 82/82 files pass, 697/697 tests pass Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -6,7 +6,11 @@ import {
|
||||
generateAgentJsonLd,
|
||||
generateBreadcrumbJsonLd,
|
||||
} from '@/components/seo/json-ld';
|
||||
import { fetchAgentProfile, fetchAgentReviews } from '@/lib/agents-server';
|
||||
import {
|
||||
fetchAgentProfile,
|
||||
fetchAgentReviews,
|
||||
fetchAgentListings,
|
||||
} from '@/lib/agents-server';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Constants
|
||||
@@ -85,9 +89,10 @@ export async function generateMetadata({ params: paramsPromise }: PageProps): Pr
|
||||
|
||||
export default async function AgentProfilePage({ params: paramsPromise }: PageProps) {
|
||||
const params = await paramsPromise;
|
||||
const [agent, reviewsResult] = await Promise.all([
|
||||
const [agent, reviewsResult, listingsResult] = await Promise.all([
|
||||
fetchAgentProfile(params.id),
|
||||
fetchAgentReviews(params.id, 1, 10),
|
||||
fetchAgentListings(params.id, 1, 50),
|
||||
]);
|
||||
|
||||
if (!agent) {
|
||||
@@ -98,6 +103,7 @@ export default async function AgentProfilePage({ params: paramsPromise }: PagePr
|
||||
const agentJsonLd = generateAgentJsonLd(agent, siteUrl);
|
||||
const breadcrumbJsonLd = generateBreadcrumbJsonLd([
|
||||
{ name: 'Trang chủ', url: siteUrl },
|
||||
{ name: 'Môi giới', url: `${siteUrl}/${params.locale}/agents` },
|
||||
{ name: agent.fullName, url: `${siteUrl}/${params.locale}/agents/${params.id}` },
|
||||
]);
|
||||
|
||||
@@ -108,7 +114,12 @@ export default async function AgentProfilePage({ params: paramsPromise }: PagePr
|
||||
<JsonLd data={breadcrumbJsonLd} />
|
||||
|
||||
{/* Interactive client component */}
|
||||
<AgentProfileClient agent={agent} reviews={reviewsResult.data} />
|
||||
<AgentProfileClient
|
||||
agent={agent}
|
||||
reviews={reviewsResult.data}
|
||||
listings={listingsResult.data}
|
||||
listingsTotal={listingsResult.total}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user