adding working IVANS widget
This commit is contained in:
@@ -1,109 +1,110 @@
|
||||
import { create } from 'zustand';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import { WIDGET_REGISTRY } from '../constants/widgetRegistry.jsx';
|
||||
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)
|
||||
// ==========================================
|
||||
// ==========================================
|
||||
// 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: [], // The master array of what is currently on the screen
|
||||
backupWidgets: [], // Holds the layout snapshot for the "Cancel" button
|
||||
widgets: get().backupWidgets // ⏪ Restore snapshot, instantly undoing any drags
|
||||
}),
|
||||
|
||||
// ==========================================
|
||||
// 2. ACTIONS (The Logic)
|
||||
// ==========================================
|
||||
saveEdit: async () => {
|
||||
// 1. Grab the exact current state of the grid
|
||||
const currentLayout = get().widgets;
|
||||
|
||||
enterEditMode: () => set({
|
||||
isEditing: true,
|
||||
backupWidgets: get().widgets // 📸 Take a snapshot of current positions
|
||||
}),
|
||||
// 2. Lock the UI immediately so the user feels zero lag
|
||||
set({isEditing: false, backupWidgets: []});
|
||||
|
||||
cancelEdit: () => set({
|
||||
isEditing: false,
|
||||
widgets: get().backupWidgets // ⏪ Restore snapshot, instantly undoing any drags
|
||||
}),
|
||||
// 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
|
||||
}
|
||||
},
|
||||
|
||||
saveEdit: async () => {
|
||||
// 1. Grab the exact current state of the grid
|
||||
const currentLayout = get().widgets;
|
||||
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
|
||||
)
|
||||
};
|
||||
}),
|
||||
|
||||
// 2. Lock the UI immediately so the user feels zero lag
|
||||
set({ isEditing: false, backupWidgets: [] });
|
||||
addWidget: (widgetId, sizeKey) => {
|
||||
const registryEntry = WIDGET_REGISTRY[widgetId];
|
||||
|
||||
// 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
|
||||
}
|
||||
},
|
||||
if (!registryEntry || !registryEntry.allowedSizes[sizeKey]) {
|
||||
console.error(`Invalid widget ID or Size: ${widgetId} - ${sizeKey}`);
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
};
|
||||
}),
|
||||
const dimensions = registryEntry.allowedSizes[sizeKey];
|
||||
const widgets = get().widgets;
|
||||
|
||||
addWidget: (widgetId, sizeKey) => {
|
||||
const registryEntry = WIDGET_REGISTRY[widgetId];
|
||||
let startX = 0;
|
||||
let startY = Infinity;
|
||||
|
||||
if (!registryEntry || !registryEntry.allowedSizes[sizeKey]) {
|
||||
console.error(`Invalid widget ID or Size: ${widgetId} - ${sizeKey}`);
|
||||
return;
|
||||
}
|
||||
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));
|
||||
|
||||
const dimensions = registryEntry.allowedSizes[sizeKey];
|
||||
const widgets = get().widgets;
|
||||
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]}));
|
||||
},
|
||||
|
||||
let startX = 0;
|
||||
let startY = Infinity;
|
||||
removeWidget: (id) => set((state) => ({
|
||||
widgets: state.widgets.filter(w => w.id !== id)
|
||||
})),
|
||||
|
||||
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));
|
||||
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;
|
||||
})
|
||||
}));
|
||||
},
|
||||
|
||||
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,
|
||||
x: startX,
|
||||
y: startY,
|
||||
w: dimensions.w,
|
||||
h: dimensions.h
|
||||
};
|
||||
|
||||
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 || [] })
|
||||
// NEW: Action to hydrate the store on initial page load
|
||||
setWidgets: (savedWidgets) => set({widgets: savedWidgets || []})
|
||||
}));
|
||||
Reference in New Issue
Block a user