Files
GRH/upload-panel/src/api/upload.ts
Exteban08 71db4219ca Add CSV upload panel for meters and readings
- Add CSV upload service with upsert logic for meters
- Add CSV upload routes (POST /csv-upload/meters, POST /csv-upload/readings)
- Add template download endpoints for CSV format
- Create standalone upload-panel React app on port 5174
- Support concentrator_serial lookup for meter creation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 11:08:30 +00:00

66 lines
1.4 KiB
TypeScript

const API_BASE_URL = import.meta.env.VITE_API_URL || 'http://localhost:3000/api';
export interface UploadError {
row: number;
field?: string;
message: string;
data?: Record<string, unknown>;
}
export interface UploadResult {
total: number;
inserted: number;
updated: number;
errors: UploadError[];
}
export interface ApiResponse {
success: boolean;
message: string;
data?: UploadResult;
}
/**
* Upload meters CSV file
*/
export async function uploadMetersCSV(file: File): Promise<ApiResponse> {
const formData = new FormData();
formData.append('file', file);
const response = await fetch(`${API_BASE_URL}/csv-upload/meters`, {
method: 'POST',
body: formData,
});
return response.json();
}
/**
* Upload readings CSV file
*/
export async function uploadReadingsCSV(file: File): Promise<ApiResponse> {
const formData = new FormData();
formData.append('file', file);
const response = await fetch(`${API_BASE_URL}/csv-upload/readings`, {
method: 'POST',
body: formData,
});
return response.json();
}
/**
* Download meters CSV template
*/
export function downloadMetersTemplate(): void {
window.open(`${API_BASE_URL}/csv-upload/meters/template`, '_blank');
}
/**
* Download readings CSV template
*/
export function downloadReadingsTemplate(): void {
window.open(`${API_BASE_URL}/csv-upload/readings/template`, '_blank');
}