feat(agents): add public agent profile page at /agents/[id]
Implements a public-facing agent profile page with: - Backend: new GET /agents/:agentId/profile public API endpoint with agent info, active listings, quality score, and review stats - Frontend: server-rendered profile page with generateMetadata for SEO, JSON-LD structured data (RealEstateAgent schema), breadcrumbs - Agent profile displays bio, service areas, quality score gauge, active listing cards, reviews with star ratings, and contact CTA - Mobile responsive layout with sticky contact sidebar on desktop - Vietnamese UI text throughout, consistent with existing patterns Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Controller, Get, Param, Post, UseGuards } from '@nestjs/common';
|
||||
import { Controller, Get, NotFoundException, Param, Post, UseGuards } from '@nestjs/common';
|
||||
import { type CommandBus, type QueryBus } from '@nestjs/cqrs';
|
||||
import {
|
||||
ApiBearerAuth,
|
||||
@@ -16,7 +16,8 @@ import {
|
||||
} from '@modules/auth';
|
||||
import { RecalculateQualityScoreCommand } from '../../application/commands/recalculate-quality-score/recalculate-quality-score.command';
|
||||
import { GetAgentDashboardQuery } from '../../application/queries/get-agent-dashboard/get-agent-dashboard.query';
|
||||
import { type AgentDashboardData } from '../../domain/repositories/agent.repository';
|
||||
import { GetAgentPublicProfileQuery } from '../../application/queries/get-agent-public-profile/get-agent-public-profile.query';
|
||||
import { type AgentDashboardData, type AgentPublicProfileData } from '../../domain/repositories/agent.repository';
|
||||
|
||||
@ApiTags('agents')
|
||||
@Controller('agents')
|
||||
@@ -41,6 +42,23 @@ export class AgentsController {
|
||||
return this.queryBus.execute(new GetAgentDashboardQuery(user.sub));
|
||||
}
|
||||
|
||||
@ApiOperation({ summary: 'Get public agent profile' })
|
||||
@ApiParam({ name: 'agentId', description: 'Agent ID' })
|
||||
@ApiResponse({ status: 200, description: 'Agent public profile data' })
|
||||
@ApiResponse({ status: 404, description: 'Agent not found' })
|
||||
@Get(':agentId/profile')
|
||||
async getPublicProfile(
|
||||
@Param('agentId') agentId: string,
|
||||
): Promise<AgentPublicProfileData> {
|
||||
const profile = await this.queryBus.execute(
|
||||
new GetAgentPublicProfileQuery(agentId),
|
||||
);
|
||||
if (!profile) {
|
||||
throw new NotFoundException('Không tìm thấy môi giới');
|
||||
}
|
||||
return profile;
|
||||
}
|
||||
|
||||
@ApiBearerAuth('JWT')
|
||||
@ApiOperation({ summary: 'Recalculate quality score (admin/system)' })
|
||||
@ApiParam({ name: 'agentId', description: 'Agent ID' })
|
||||
|
||||
Reference in New Issue
Block a user