All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 2m42s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 29s
Deploy to Staging / Verify Staging (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
- Remove CostInterval type and TCOResponse interface from frontend types - Remove insurance/registration cost fields from VehicleForm schema and UI - Keep purchasePrice and purchaseDate fields on vehicle form - Remove TCODisplay component from VehicleDetailPage - Delete TCODisplay.tsx component file - Remove getTCO method from vehicles API client Legacy TCO fields moved to ownership-costs feature in #29. Backend endpoint preserved for future reporting feature. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
93 lines
3.4 KiB
TypeScript
93 lines
3.4 KiB
TypeScript
/**
|
|
* @ai-summary API calls for vehicles feature
|
|
*/
|
|
|
|
import { apiClient } from '../../../core/api/client';
|
|
import { Vehicle, CreateVehicleRequest, UpdateVehicleRequest, DecodedVehicleData } from '../types/vehicles.types';
|
|
|
|
// All requests (including dropdowns) use authenticated apiClient
|
|
|
|
export const vehiclesApi = {
|
|
getAll: async (): Promise<Vehicle[]> => {
|
|
const response = await apiClient.get('/vehicles');
|
|
return response.data;
|
|
},
|
|
|
|
getById: async (id: string): Promise<Vehicle> => {
|
|
const response = await apiClient.get(`/vehicles/${id}`);
|
|
return response.data;
|
|
},
|
|
|
|
create: async (data: CreateVehicleRequest): Promise<Vehicle> => {
|
|
const response = await apiClient.post('/vehicles', data);
|
|
return response.data;
|
|
},
|
|
|
|
update: async (id: string, data: UpdateVehicleRequest): Promise<Vehicle> => {
|
|
const response = await apiClient.put(`/vehicles/${id}`, data);
|
|
return response.data;
|
|
},
|
|
|
|
delete: async (id: string): Promise<void> => {
|
|
await apiClient.delete(`/vehicles/${id}`);
|
|
},
|
|
|
|
// Dropdown API methods (authenticated) - proxied through vehicles capsule
|
|
getYears: async (): Promise<number[]> => {
|
|
const response = await apiClient.get('/vehicles/dropdown/years');
|
|
return response.data;
|
|
},
|
|
|
|
getMakes: async (year: number): Promise<string[]> => {
|
|
const response = await apiClient.get(`/vehicles/dropdown/makes?year=${year}`);
|
|
return response.data;
|
|
},
|
|
|
|
getModels: async (year: number, make: string): Promise<string[]> => {
|
|
const response = await apiClient.get(`/vehicles/dropdown/models?year=${year}&make=${encodeURIComponent(make)}`);
|
|
return response.data;
|
|
},
|
|
|
|
getTransmissions: async (year: number, make: string, model: string, trim: string): Promise<string[]> => {
|
|
const response = await apiClient.get(`/vehicles/dropdown/transmissions?year=${year}&make=${encodeURIComponent(make)}&model=${encodeURIComponent(model)}&trim=${encodeURIComponent(trim)}`);
|
|
return response.data;
|
|
},
|
|
|
|
getEngines: async (year: number, make: string, model: string, trim: string): Promise<string[]> => {
|
|
const response = await apiClient.get(`/vehicles/dropdown/engines?year=${year}&make=${encodeURIComponent(make)}&model=${encodeURIComponent(model)}&trim=${encodeURIComponent(trim)}`);
|
|
return response.data;
|
|
},
|
|
|
|
getTrims: async (year: number, make: string, model: string): Promise<string[]> => {
|
|
const response = await apiClient.get(`/vehicles/dropdown/trims?year=${year}&make=${encodeURIComponent(make)}&model=${encodeURIComponent(model)}`);
|
|
return response.data;
|
|
},
|
|
|
|
uploadImage: async (vehicleId: string, file: File): Promise<Vehicle> => {
|
|
const formData = new FormData();
|
|
formData.append('file', file);
|
|
const response = await apiClient.post(`/vehicles/${vehicleId}/image`, formData, {
|
|
headers: { 'Content-Type': 'multipart/form-data' },
|
|
timeout: 60000 // 60 seconds for file uploads
|
|
});
|
|
return response.data;
|
|
},
|
|
|
|
deleteImage: async (vehicleId: string): Promise<void> => {
|
|
await apiClient.delete(`/vehicles/${vehicleId}/image`);
|
|
},
|
|
|
|
getImageUrl: (vehicleId: string): string => {
|
|
return `/api/vehicles/${vehicleId}/image`;
|
|
},
|
|
|
|
/**
|
|
* Decode VIN using NHTSA vPIC API
|
|
* Requires Pro or Enterprise tier
|
|
*/
|
|
decodeVin: async (vin: string): Promise<DecodedVehicleData> => {
|
|
const response = await apiClient.post('/vehicles/decode-vin', { vin });
|
|
return response.data;
|
|
}
|
|
};
|