feat: add market dashboard web app
This commit is contained in:
64
apps/web/src/lib/api.ts
Normal file
64
apps/web/src/lib/api.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
export type AreaScore = {
|
||||
area_id: string;
|
||||
name: string;
|
||||
district: string;
|
||||
segment: string;
|
||||
month: string;
|
||||
investment_score: number;
|
||||
recommendation: string;
|
||||
liquidity_score: number;
|
||||
momentum_score: number;
|
||||
rent_support_score: number;
|
||||
safety_margin_score: number;
|
||||
credit_support_score: number;
|
||||
supply_risk_score: number;
|
||||
valuation_pressure_score: number;
|
||||
transaction_count: number;
|
||||
transaction_price_psm: number;
|
||||
listing_count: number;
|
||||
listing_price_psm: number;
|
||||
rent_price_psm: number;
|
||||
median_days_on_market: number;
|
||||
annual_rent_yield_pct: number;
|
||||
listing_pressure_ratio: number;
|
||||
discount_pct: number;
|
||||
price_momentum_pct: number;
|
||||
volume_momentum_pct: number;
|
||||
};
|
||||
|
||||
export type AreaScoreSummary = {
|
||||
area_id: string;
|
||||
name: string;
|
||||
district: string;
|
||||
investment_score: number;
|
||||
recommendation: string;
|
||||
};
|
||||
|
||||
export type MarketOverview = {
|
||||
month: string;
|
||||
area_count: number;
|
||||
average_investment_score: number;
|
||||
average_rent_yield_pct: number;
|
||||
top_area: AreaScoreSummary | null;
|
||||
weakest_area: AreaScoreSummary | null;
|
||||
highest_supply_risk_area: AreaScoreSummary | null;
|
||||
};
|
||||
|
||||
const API_BASE_URL =
|
||||
process.env.NEXT_PUBLIC_API_BASE_URL?.replace(/\/$/, "") ?? "http://127.0.0.1:8080";
|
||||
|
||||
export async function fetchMarketOverview(month: string): Promise<MarketOverview> {
|
||||
return fetchJson(`/api/v1/market/overview?month=${encodeURIComponent(month)}`);
|
||||
}
|
||||
|
||||
export async function fetchAreaScores(month: string): Promise<AreaScore[]> {
|
||||
return fetchJson(`/api/v1/areas/scores?month=${encodeURIComponent(month)}`);
|
||||
}
|
||||
|
||||
async function fetchJson<T>(path: string): Promise<T> {
|
||||
const response = await fetch(`${API_BASE_URL}${path}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`API request failed with ${response.status}`);
|
||||
}
|
||||
return response.json() as Promise<T>;
|
||||
}
|
||||
Reference in New Issue
Block a user