import api from './api'; export interface LayoutProperty { id: string; name: string; address?: string; licenseNum?: string; buildings: LayoutBuilding[]; createdAt?: string; } export interface LayoutBuilding { id: string; propertyId: string; name: string; code: string; type: string; floors: LayoutFloor[]; } export interface LayoutFloor { id: string; buildingId: string; name: string; number: number; width: number; height: number; ceilingHeight?: number; defaultTiers?: number; rooms: LayoutRoom[]; } export interface LayoutRoom { id: string; floorId: string; name: string; code: string; type: 'VEG' | 'FLOWER' | 'DRY' | 'CURE' | 'MOTHER' | 'CLONE' | 'FACILITY'; posX: number; posY: number; width: number; height: number; rotation: number; color?: string; sections?: LayoutSection[]; } export interface LayoutPosition { id: string; sectionId: string; row: number; column: number; tier: number; slot: number; status: string; plantId?: string; plant?: any; } export interface LayoutSection { id: string; roomId: string; name: string; code: string; type: string; posX: number; posY: number; width: number; height: number; rows: number; columns: number; tiers: number; spacing?: number; positions?: LayoutPosition[]; } // 3D Visualization Types export interface Position3D { id: string; row: number; column: number; tier: number; status: string; plant: { id: string; tagNumber: string; status: string; batchId: string | null; batchName: string | null; plantTypeId: string | null; strain: string | null; stage: string | null; } | null; } export interface Section3D { id: string; name: string; code: string; type: string; posX: number; posY: number; width: number; height: number; rows: number; columns: number; positions: Position3D[]; } export interface Room3D { id: string; name: string; code: string; type: string; posX: number; posY: number; width: number; height: number; color: string | null; sections: Section3D[]; } export interface Floor3DData { floor: { id: string; name: string; number: number; width: number; height: number; building: string; property: string; }; rooms: Room3D[]; stats: { totalRooms: number; totalSections: number; totalPositions: number; occupiedPositions: number; }; } // ======================================== // API Functions // ======================================== export const layoutApi = { // Properties async getProperties(): Promise { const response = await api.get('/layout/properties'); return response.data; }, async createProperty(data: { name: string; address?: string; licenseNum?: string }): Promise { const response = await api.post('/layout/properties', data); return response.data; }, // Buildings async createBuilding(data: { propertyId: string; name: string; code: string; type: string }): Promise { const response = await api.post('/layout/buildings', data); return response.data; }, // Floors async getFloor(id: string): Promise { const response = await api.get(`/layout/floors/${id}`); return response.data; }, async createFloor(data: { buildingId: string; name: string; number: number; width?: number; height?: number; ceilingHeight?: number; defaultTiers?: number; }): Promise { const response = await api.post('/layout/floors', data); return response.data; }, // 3D Visualization async getFloor3D(id: string): Promise { const response = await api.get(`/layout/floors/${id}/3d`); return response.data; }, async saveFloorLayout(floorId: string, rooms: LayoutRoom[]): Promise { const roomsForApi = rooms.map(r => ({ id: r.id, name: r.name, code: r.code, type: r.type, posX: r.posX, posY: r.posY, width: r.width, height: r.height, color: r.color, rotation: r.rotation, sections: r.sections // Include sections in save })); const response = await api.post(`/layout/floors/${floorId}/layout`, { rooms: roomsForApi }); return response.data; }, async generateRoom(data: { floorId: string; name: string; code: string; type: string; setupType: string; tiers: number; racksCount: number; rowsPerRack: number; colsPerRack: number; }): Promise { const response = await api.post('/layout/rooms/generate', data); return response.data; }, // Rooms async createRoom(data: Partial): Promise { const response = await api.post('/layout/rooms', data); return response.data; }, async updateRoom(id: string, data: Partial): Promise { const response = await api.put(`/layout/rooms/${id}`, data); return response.data; }, async deleteRoom(id: string): Promise { await api.delete(`/layout/rooms/${id}`); }, // Sections async createSection(data: Partial & { rows: number; columns: number }): Promise { const response = await api.post('/layout/sections', data); return response.data; }, async getRoomSections(roomId: string): Promise { const response = await api.get(`/layout/rooms/${roomId}/sections`); return response.data; }, async occupyPosition(positionId: string, data: { batchId?: string; plantTypeId?: string }): Promise { await api.post(`/layout/positions/${positionId}/occupy`, data); }, async fillSection(sectionId: string, batchId: string, maxCount?: number): Promise<{ plantsCreated: number; message: string }> { const response = await api.post(`/layout/sections/${sectionId}/fill`, { batchId, maxCount }); return response.data; }, async movePlant(plantId: string, targetPositionId: string, reason?: string): Promise<{ newAddress: string; message: string }> { const response = await api.post(`/layout/plants/${plantId}/move`, { targetPositionId, reason }); return response.data; }, async getSection(id: string): Promise { const response = await api.get(`/layout/sections/${id}`); return response.data; }, async updateSection(id: string, updates: { name?: string; code?: string; type?: string; rows?: number; columns?: number; }): Promise { const response = await api.patch(`/layout/sections/${id}`, updates); return response.data; }, // ======================================== // Plant Type Library (Rackula-inspired) // ======================================== async getPlantTypes(): Promise { const response = await api.get('/layout/plant-types'); return response.data; }, async getPlantType(slug: string): Promise { const response = await api.get(`/layout/plant-types/${slug}`); return response.data; }, async createPlantType(data: CreatePlantTypeData): Promise { const response = await api.post('/layout/plant-types', data); return response.data; }, async updatePlantType(slug: string, data: Partial): Promise { const response = await api.put(`/layout/plant-types/${slug}`, data); return response.data; }, async deletePlantType(slug: string): Promise { await api.delete(`/layout/plant-types/${slug}`); } }; // Plant Type Library Types export interface LayoutPlantType { id: string; slug: string; name: string; strain?: string; category: 'VEG' | 'FLOWER' | 'MOTHER' | 'CLONE' | 'SEEDLING'; colour: string; growthDays?: number; yieldGrams?: number; notes?: string; tags?: string[]; customFields?: Record; createdAt?: string; updatedAt?: string; } export interface CreatePlantTypeData { name: string; strain?: string; category: 'VEG' | 'FLOWER' | 'MOTHER' | 'CLONE' | 'SEEDLING'; colour: string; growthDays?: number; yieldGrams?: number; notes?: string; tags?: string[]; customFields?: Record; }