import { apiClient } from './client'; // Frontend Interface (CamelCase) export interface Asset { id: string; parentId?: string; // DB: parent_id parentName?: string; // Joined name: string; category: string; model: string; // DB: model_name serialNumber: string; // DB: serial_number manufacturer: string; location: string; purchaseDate: string; // DB: purchase_date manager: string; status: 'active' | 'maintain' | 'broken' | 'disposed'; purchasePrice?: number; // DB: purchase_price image?: string; // DB: image_url calibrationCycle?: string; // DB: calibration_cycle specs?: string; quantity?: number; children?: Partial[]; // List of sub-assets } // DB Interface (SnakeCase) - for internal mapping interface DBAsset { id: string; parent_id?: string; parent_name?: string; // Joined or added in response name: string; category: string; model_name: string; serial_number: string; manufacturer: string; location: string; purchase_date: string; manager: string; status: 'active' | 'maintain' | 'broken' | 'disposed'; purchase_price?: number; image_url?: string; calibration_cycle: string; specs: string; quantity?: number; created_at: string; updated_at: string; children?: any[]; } export interface MaintenanceRecord { id: number; asset_id: string; maintenance_date: string; type: string; content: string; image_url?: string; // Legacy images?: string[]; // New: Multiple images created_at?: string; parts?: PartUsage[]; } export interface PartUsage { id?: number; // maintenance_parts id part_id: string; // asset id part_name?: string; // joined model_name?: string; // joined quantity: number; } // Manual Interface export interface Manual { id: number; asset_id: string; file_name: string; file_url: string; created_at?: string; } export const assetApi = { getAll: async (): Promise => { try { const response = await apiClient.get('/assets'); if (!response.data || !Array.isArray(response.data)) return []; return response.data.map(mapDBToAsset); } catch (err) { console.error('API Error in getAll:', err); throw err; } }, getById: async (id: string): Promise => { const response = await apiClient.get(`/assets/${id}`); const asset = mapDBToAsset(response.data); if (response.data.children) { asset.children = response.data.children.map(c => ({ id: c.id, name: c.name, category: c.category, status: c.status, location: c.location })); } if (response.data.parent_name) { asset.parentName = response.data.parent_name; } return asset; }, create: (data: Partial) => { const dbData = mapAssetToDB(data); return apiClient.post<{ message: string, id: string }>('/assets', dbData); }, update: (id: string, data: Partial) => { const dbData = mapAssetToDB(data); return apiClient.put(`/assets/${id}`, dbData); }, uploadImage: (file: File) => { const formData = new FormData(); formData.append('image', file); return apiClient.post<{ url: string }>('/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' } }); }, // Maintenance History getMaintenanceHistory: async (assetId: string): Promise => { const response = await apiClient.get(`/assets/${assetId}/maintenance`); return response.data.map(record => ({ ...record, // Ensure images is parsed as array if it comes as string from DB images: typeof record.images === 'string' ? JSON.parse(record.images) : (record.images || []) })); }, addMaintenance: async (assetId: string, data: Partial) => { return apiClient.post(`/assets/${assetId}/maintenance`, data); }, deleteMaintenance: async (id: number) => { return apiClient.delete(`/maintenance/${id}`); }, updateMaintenance: async (id: number, data: Partial) => { return apiClient.put(`/maintenance/${id}`, data); }, // Manuals / Instructions getManuals: async (assetId: string): Promise => { const response = await apiClient.get(`/assets/${assetId}/manuals`); return response.data; }, addManual: async (assetId: string, data: { file_name: string; file_url: string }) => { return apiClient.post(`/assets/${assetId}/manuals`, data); }, deleteManual: async (id: number) => { return apiClient.delete(`/manuals/${id}`); }, // Accessories getAccessories: async (assetId: string): Promise => { const response = await apiClient.get(`/assets/${assetId}/accessories`); return response.data; }, addAccessory: async (assetId: string, data: { name: string, spec: string, quantity: number }) => { return apiClient.post(`/assets/${assetId}/accessories`, data); }, deleteAccessory: async (id: number) => { return apiClient.delete(`/accessories/${id}`); } }; // Helper Mappers const mapDBToAsset = (db: DBAsset): Asset => ({ id: db.id, parentId: db.parent_id, name: db.name, category: db.category, model: db.model_name || '', serialNumber: db.serial_number || '', manufacturer: db.manufacturer || '', location: db.location || '', purchaseDate: db.purchase_date ? new Date(db.purchase_date).toISOString().split('T')[0] : '', // Format YYYY-MM-DD manager: db.manager || '', status: db.status, purchasePrice: db.purchase_price, image: db.image_url, calibrationCycle: db.calibration_cycle || '', specs: db.specs || '', quantity: db.quantity }); const mapAssetToDB = (asset: Partial): Partial => { const db: any = { ...asset }; if (asset.parentId !== undefined) { db.parent_id = asset.parentId; delete db.parentId; } if (asset.model !== undefined) { db.model_name = asset.model; delete db.model; } if (asset.serialNumber !== undefined) { db.serial_number = asset.serialNumber; delete db.serialNumber; } if (asset.purchaseDate !== undefined) { db.purchase_date = asset.purchaseDate; delete db.purchaseDate; } if (asset.purchasePrice !== undefined) { db.purchase_price = asset.purchasePrice; delete db.purchasePrice; } if (asset.image !== undefined) { db.image_url = asset.image; delete db.image; } if (asset.calibrationCycle !== undefined) { db.calibration_cycle = asset.calibrationCycle; delete db.calibrationCycle; } return db; };