196 lines
5.0 KiB
JavaScript

/**
* Configuration utilities for handling settings and form submissions
*/
class ConfigHandler {
constructor(options = {}) {
this.options = {
apiEndpoint: options.apiEndpoint || "/config/api/update_config",
...options,
};
}
/**
* Update configuration via API
* @param {object} configData - Configuration data to send
* @returns {Promise} API response promise
*/
async updateConfig(configData) {
try {
const response = await fetch(this.options.apiEndpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(configData),
});
const data = await response.json();
if (data.success) {
showFlashMessage(
data.message || "Configuration updated successfully!",
"success"
);
} else {
const errorMessage =
data.updates?.[0]?.message ||
data.message ||
"Error updating configuration";
showFlashMessage(errorMessage, "error");
}
return data;
} catch (error) {
console.error("Error updating configuration:", error);
showFlashMessage("Network error occurred", "error");
throw error;
}
}
/**
* Update volume configuration
* @param {number} volume - New volume value
*/
async updateVolume(volume) {
return this.updateConfig({ volume: volume });
}
/**
* Update schedule configuration
* @param {object} schedule - Schedule configuration object
*/
async updateSchedule(schedule) {
return this.updateConfig({ schedule: schedule });
}
/**
* Create an Alpine.js data object for schedule management
* Reads configuration from JSON script tag in the template
* @returns {object} Alpine.js data object
*/
createScheduleManager() {
const self = this;
// Read configuration from JSON script tag
const configElement = document.getElementById("schedule-config");
const config = configElement ? JSON.parse(configElement.textContent) : {};
const initialSchedule = config.initialSchedule || {};
const volume = config.totalVolume || 0;
return {
schedule: { ...initialSchedule },
volume: volume,
selectedHours: [],
newWeight: 1.0,
volumeValue: volume,
isDragging: false,
dragOperation: null,
formatHour(h) {
return String(h).padStart(2, "0") + ":00";
},
async updateVolume() {
try {
const data = await self.updateVolume(this.volumeValue);
if (data.success) {
this.volume = parseFloat(this.volumeValue);
}
} catch (error) {
// Error handling is done in updateConfig
}
},
getBackgroundStyle(hour) {
const weight = parseFloat(this.schedule[hour]);
const maxWeight = 2.5;
// Normalize weight (0.0 to 1.0)
const t = Math.min(weight / maxWeight, 1.0);
// Interpolate HSL lightness: 95% (light) to 30% (dark)
const lightness = 95 - t * 65;
const backgroundColor = `hsl(210, 10%, ${lightness}%)`;
const textColor = t > 0.65 ? "white" : "black";
return {
backgroundColor,
color: textColor,
};
},
startDrag(event, hour) {
event.preventDefault();
this.isDragging = true;
this.dragOperation = this.isSelected(hour) ? "remove" : "add";
this.toggleSelect(hour);
},
dragSelect(hour) {
if (!this.isDragging) return;
const selected = this.isSelected(hour);
if (this.dragOperation === "add" && !selected) {
this.selectedHours.push(hour);
} else if (this.dragOperation === "remove" && selected) {
this.selectedHours = this.selectedHours.filter((h) => h !== hour);
}
},
endDrag() {
this.isDragging = false;
},
toggleSelect(hour) {
if (this.isSelected(hour)) {
this.selectedHours = this.selectedHours.filter((h) => h !== hour);
} else {
this.selectedHours.push(hour);
}
},
isSelected(hour) {
return this.selectedHours.includes(hour);
},
applyWeight() {
this.selectedHours.forEach((hour) => {
this.schedule[hour] = parseFloat(this.newWeight).toFixed(1);
});
this.selectedHours = [];
},
getTotalWeight() {
return Object.values(this.schedule).reduce(
(sum, w) => sum + parseFloat(w),
0
);
},
getPapersPerHour(hour) {
const total = this.getTotalWeight();
if (total === 0) return 0;
return (
(parseFloat(this.schedule[hour]) / total) *
this.volume
).toFixed(1);
},
async saveSchedule() {
try {
await self.updateSchedule(this.schedule);
} catch (error) {
// Error handling is done in updateConfig
}
},
};
}
}
/**
* Global instance for easy access
*/
window.configHandler = new ConfigHandler();