Refactor CropZoningMap and related components for improved API integration and UI enhancements

- Updated CropZoningMap to utilize new ZoneInitialData type for zone click handling and added zonesData prop for API-driven zone rendering.
- Removed deprecated crop zoning mock data file and integrated grid creation logic for initial zone fetching.
- Enhanced CropZoningWrapper to manage area and zone data loading states, improving user experience with asynchronous data fetching.
- Updated ZoneDetailPanel to handle loading states and display product labels dynamically based on fetched data.
- Refactored ZoneLegend to conditionally render items based on available product data, enhancing visual feedback during loading.
This commit is contained in:
2026-02-26 00:17:32 +03:30
parent aad5b1c2bd
commit 3db9a86cbf
9 changed files with 981 additions and 158 deletions
@@ -0,0 +1,77 @@
/**
* Crop Zoning API
* @see CROP_ZONING_APIS.md
*/
import type { Feature, FeatureCollection, Polygon } from 'geojson'
import { apiClient } from '../client'
const PREFIX = '/api/crop-zoning'
export interface Product {
id: string
label: string
color: string
}
export interface ZoneInitialData {
zoneId: string
geometry: Polygon
crop: string
matchPercent: number
waterNeed: string
estimatedProfit: string
}
export interface ZonesInitialResponse {
total_area_hectares: number
total_area_sqm: number
zone_count: number
zones: ZoneInitialData[]
}
export interface AreaResponse {
area: Feature<Polygon>
}
export interface ZoneDetailData {
zoneId: string
crop: string
matchPercent: number
waterNeed: string
estimatedProfit: string
reason: string
criteria: { name: string; value: number }[]
area_hectares?: number
}
interface ApiResponse<T> {
status: string
data: T
}
async function unwrap<T>(promise: Promise<ApiResponse<T>>): Promise<T> {
const res = await promise
return res.data
}
export const cropZoningService = {
getProducts(): Promise<{ products: Product[] }> {
return unwrap(apiClient.get<ApiResponse<{ products: Product[] }>>(`${PREFIX}/products/`))
},
getZonesInitial(body: {
zones: FeatureCollection<Polygon>
products?: string[]
}): Promise<ZonesInitialResponse> {
return unwrap(apiClient.post<ApiResponse<ZonesInitialResponse>>(`${PREFIX}/zones/initial/`, body))
},
getZoneDetails(zoneId: string): Promise<ZoneDetailData> {
return unwrap(apiClient.get<ApiResponse<ZoneDetailData>>(`${PREFIX}/zones/${zoneId}/details/`))
},
getArea(): Promise<AreaResponse> {
return unwrap(apiClient.get<ApiResponse<AreaResponse>>(`${PREFIX}/area/`))
}
}