feat(web): add khu-cong-nghiep, chuyen-nhuong, and reports pages
Add three new frontend page sections: - Industrial parks (khu-cong-nghiep): listing, detail, filter bar - Transfer listings (chuyen-nhuong): search, category tabs, detail - AI reports dashboard: list, create, viewer with TOC Includes components, API clients, hooks, server helpers, i18n keys, navigation links in public and dashboard layouts, and lint fixes. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
78
apps/web/lib/reports-api.ts
Normal file
78
apps/web/lib/reports-api.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { apiClient } from './api-client';
|
||||
|
||||
// ─── Types ──────────────────────────────────────────────
|
||||
|
||||
export type ReportType =
|
||||
| 'RESIDENTIAL_MARKET'
|
||||
| 'INDUSTRIAL_MARKET'
|
||||
| 'DISTRICT_ANALYSIS'
|
||||
| 'INVESTMENT_FEASIBILITY'
|
||||
| 'INDUSTRIAL_LOCATION'
|
||||
| 'PROPERTY_VALUATION'
|
||||
| 'PORTFOLIO';
|
||||
|
||||
export type ReportStatus = 'GENERATING' | 'READY' | 'FAILED';
|
||||
|
||||
export interface Report {
|
||||
id: string;
|
||||
type: ReportType;
|
||||
title: string;
|
||||
params: Record<string, unknown>;
|
||||
content: Record<string, unknown> | null;
|
||||
pdfUrl: string | null;
|
||||
status: ReportStatus;
|
||||
errorMsg: string | null;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface ListReportsResponse {
|
||||
data: Report[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface GenerateReportResponse {
|
||||
reportId: string;
|
||||
}
|
||||
|
||||
export interface ReportStatusResponse {
|
||||
id: string;
|
||||
status: ReportStatus;
|
||||
errorMsg: string | null;
|
||||
pdfUrl: string | null;
|
||||
}
|
||||
|
||||
// ─── API Calls ──────────────────────────────────────────
|
||||
|
||||
export function listReports(params?: {
|
||||
type?: ReportType;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
}): Promise<ListReportsResponse> {
|
||||
const searchParams = new URLSearchParams();
|
||||
if (params?.type) searchParams.set('type', params.type);
|
||||
if (params?.limit) searchParams.set('limit', String(params.limit));
|
||||
if (params?.offset) searchParams.set('offset', String(params.offset));
|
||||
const qs = searchParams.toString();
|
||||
return apiClient.get<ListReportsResponse>(`/reports${qs ? `?${qs}` : ''}`);
|
||||
}
|
||||
|
||||
export function getReport(id: string): Promise<Report> {
|
||||
return apiClient.get<Report>(`/reports/${id}`);
|
||||
}
|
||||
|
||||
export function getReportStatus(id: string): Promise<ReportStatusResponse> {
|
||||
return apiClient.get<ReportStatusResponse>(`/reports/${id}/status`);
|
||||
}
|
||||
|
||||
export function generateReport(data: {
|
||||
type: ReportType;
|
||||
title: string;
|
||||
params: Record<string, unknown>;
|
||||
}): Promise<GenerateReportResponse> {
|
||||
return apiClient.post<GenerateReportResponse>('/reports/generate', data);
|
||||
}
|
||||
|
||||
export function deleteReport(id: string): Promise<void> {
|
||||
return apiClient.delete<void>(`/reports/${id}`);
|
||||
}
|
||||
Reference in New Issue
Block a user