import {create} from 'zustand'; import {v4 as uuid} from 'uuid'; import {WIDGET_REGISTRY} from '../constants/widgetRegistry.jsx'; // 1. Import your database messenger import useAuthStore from './authStore'; export const useDashboardStore = create((set, get) => ({ // ========================================== // 1. STATE (The Data) // ========================================== isEditing: false, widgets: [], // The master array of what is currently on the screen backupWidgets: [], // Holds the layout snapshot for the "Cancel" button // ========================================== // 2. ACTIONS (The Logic) // ========================================== enterEditMode: () => set({ isEditing: true, backupWidgets: get().widgets // 📸 Take a snapshot of current positions }), cancelEdit: () => set({ isEditing: false, widgets: get().backupWidgets // ⏪ Restore snapshot, instantly undoing any drags }), saveEdit: async () => { // 1. Grab the exact current state of the grid const currentLayout = get().widgets; // 2. Lock the UI immediately so the user feels zero lag set({isEditing: false, backupWidgets: []}); // 3. Reach outside this store and trigger the Django API call! try { await useAuthStore.getState().saveDashboardLayout(currentLayout); } catch (error) { console.error("Failed to sync layout to MariaDB:", error); // If the database save fails, you could technically revert the UI here if needed } }, updateWidgetSettings: (id, newSettings) => set((state) => { // console.log("2. Zustand updating widget:", id, "with:", newSettings); return { widgets: state.widgets.map(widget => widget.id === id ? {...widget, settings: {...widget.settings, ...newSettings}} : widget ) }; }), addWidget: (widgetId, sizeKey) => { const registryEntry = WIDGET_REGISTRY[widgetId]; if (!registryEntry || !registryEntry.allowedSizes[sizeKey]) { console.error(`Invalid widget ID or Size: ${widgetId} - ${sizeKey}`); return; } const dimensions = registryEntry.allowedSizes[sizeKey]; const widgets = get().widgets; let startX = 0; let startY = Infinity; if (widgets.length > 0) { const bottomRowY = Math.max(...widgets.map(w => w.y)); const bottomRowWidgets = widgets.filter(w => w.y === bottomRowY); const rightmostEdge = Math.max(...bottomRowWidgets.map(w => w.x + w.w)); if (rightmostEdge + dimensions.w <= 12) { startX = rightmostEdge; // ...tuck it right next to the last widget! startY = bottomRowY; // ...and keep it on the same row. } } const newWidget = { id: uuid(), type: widgetId, size: sizeKey, settings: registryEntry.defaultSettings, x: startX, y: startY, w: dimensions.w, h: dimensions.h }; console.log("newWidget: ", newWidget); set((state) => ({widgets: [...state.widgets, newWidget]})); }, removeWidget: (id) => set((state) => ({ widgets: state.widgets.filter(w => w.id !== id) })), updateLayoutPositions: (rglLayout) => { set((state) => ({ widgets: state.widgets.map(widget => { const gridItem = rglLayout.find(l => l.i === widget.id); return gridItem ? {...widget, x: gridItem.x, y: gridItem.y} : widget; }) })); }, // NEW: Action to hydrate the store on initial page load setWidgets: (savedWidgets) => set({widgets: savedWidgets || []}) }));