feat: Add banner toggle and soldout tracking to Cars page
- Add is_banner, soldout fields to Car model
- Add banner toggle API (POST /hero-banners/admin/toggle/{car_id})
- Add soldout APIs (POST/DELETE /cars/{car_id}/soldout)
- Add nightly soldout checker in agent (runs at 3:00 AM)
- Update Local Cars UI with banner checkbox and status column
- Remove hero-banners admin page (functionality moved to Cars page)
- Banner cars sorted to top with purple background
- Soldout cars displayed with gray overlay
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -70,6 +70,22 @@ export const carsApi = {
|
||||
const { data } = await api.get('/cars/models/', { params });
|
||||
return data;
|
||||
},
|
||||
|
||||
// Soldout APIs
|
||||
markSoldout: async (carId: number): Promise<{ car_id: number; soldout: boolean; message: string }> => {
|
||||
const { data } = await api.post(`/cars/${carId}/soldout`);
|
||||
return data;
|
||||
},
|
||||
|
||||
markAvailable: async (carId: number): Promise<{ car_id: number; soldout: boolean; message: string }> => {
|
||||
const { data } = await api.delete(`/cars/${carId}/soldout`);
|
||||
return data;
|
||||
},
|
||||
|
||||
getSoldoutStats: async (): Promise<{ total_active: number; soldout: number; available: number; soldout_percentage: number }> => {
|
||||
const { data } = await api.get('/cars/admin/soldout-stats');
|
||||
return data;
|
||||
},
|
||||
};
|
||||
|
||||
// Auth API
|
||||
@@ -187,6 +203,22 @@ export const heroBannersApi = {
|
||||
const { data } = await api.put('/hero-banners/admin/settings', settings);
|
||||
return data;
|
||||
},
|
||||
|
||||
// Banner Toggle & Ordering
|
||||
adminToggleBanner: async (carId: number): Promise<{ car_id: number; is_banner: boolean; banner_id?: number; message: string }> => {
|
||||
const { data } = await api.post(`/hero-banners/admin/toggle/${carId}`);
|
||||
return data;
|
||||
},
|
||||
|
||||
adminReorderBanners: async (carIds: number[]): Promise<{ message: string; count: number }> => {
|
||||
const { data } = await api.put('/hero-banners/admin/reorder', carIds);
|
||||
return data;
|
||||
},
|
||||
|
||||
adminGetBannerCars: async (): Promise<{ car_ids: number[]; count: number }> => {
|
||||
const { data } = await api.get('/hero-banners/admin/banner-cars');
|
||||
return data;
|
||||
},
|
||||
};
|
||||
|
||||
// Translations API
|
||||
|
||||
Reference in New Issue
Block a user