Build the valuation page at /dashboard/valuation with form input, AI-powered price estimation results, comparable properties display, and valuation history. Add "Dinh gia AI" button to listing detail sidebar for quick per-listing estimates. Co-Authored-By: Paperclip <noreply@paperclip.ing>
86 lines
2.0 KiB
TypeScript
86 lines
2.0 KiB
TypeScript
import { apiClient } from './api-client';
|
|
|
|
// ─── Types ──────────────────────────────────────────────
|
|
|
|
export interface ValuationRequest {
|
|
propertyType: string;
|
|
area: number;
|
|
district: string;
|
|
city: string;
|
|
bedrooms?: number;
|
|
bathrooms?: number;
|
|
floors?: number;
|
|
frontage?: number;
|
|
roadWidth?: number;
|
|
yearBuilt?: number;
|
|
hasLegalPaper?: boolean;
|
|
}
|
|
|
|
export interface ValuationComparable {
|
|
id: string;
|
|
title: string;
|
|
address: string;
|
|
district: string;
|
|
priceVND: string;
|
|
areaM2: number;
|
|
pricePerM2: number;
|
|
similarity: number;
|
|
latitude?: number;
|
|
longitude?: number;
|
|
}
|
|
|
|
export interface PriceDriver {
|
|
feature: string;
|
|
impact: number;
|
|
direction: 'positive' | 'negative';
|
|
}
|
|
|
|
export interface ValuationResult {
|
|
id: string;
|
|
estimatedPriceVND: number;
|
|
confidence: number;
|
|
pricePerM2: number;
|
|
priceRangeLow: number;
|
|
priceRangeHigh: number;
|
|
comparables: ValuationComparable[];
|
|
priceDrivers: PriceDriver[];
|
|
modelVersion: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface ValuationHistoryItem {
|
|
id: string;
|
|
propertyType: string;
|
|
district: string;
|
|
city: string;
|
|
area: number;
|
|
estimatedPriceVND: number;
|
|
confidence: number;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface ValuationHistoryResponse {
|
|
data: ValuationHistoryItem[];
|
|
total: number;
|
|
page: number;
|
|
limit: number;
|
|
}
|
|
|
|
// ─── API ────────────────────────────────────────────────
|
|
|
|
export const valuationApi = {
|
|
predict: (data: ValuationRequest) =>
|
|
apiClient.post<ValuationResult>('/valuation/predict', data),
|
|
|
|
getHistory: (page = 1, limit = 10) =>
|
|
apiClient.get<ValuationHistoryResponse>(
|
|
`/valuation/history?page=${page}&limit=${limit}`,
|
|
),
|
|
|
|
getById: (id: string) =>
|
|
apiClient.get<ValuationResult>(`/valuation/${id}`),
|
|
|
|
predictForListing: (listingId: string) =>
|
|
apiClient.post<ValuationResult>(`/valuation/predict-listing/${listingId}`),
|
|
};
|