"Refactor calendar blueprint and test printer creation"
This commit is contained in:
@@ -1065,14 +1065,42 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
const priority = document.getElementById('eventPriority').value;
|
||||
|
||||
if (printerSelect.value === '' && startTime && endTime) {
|
||||
// Dynamische Empfehlung anzeigen
|
||||
showSmartRecommendation(startTime, endTime, priority);
|
||||
// Echte API-Empfehlung abrufen
|
||||
fetchSmartRecommendation(startTime, endTime, priority);
|
||||
} else {
|
||||
hideSmartRecommendation();
|
||||
}
|
||||
}
|
||||
|
||||
function showSmartRecommendation(start, end, priority) {
|
||||
async function fetchSmartRecommendation(start, end, priority) {
|
||||
try {
|
||||
const response = await fetch('/api/calendar/smart-recommendation', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
|
||||
},
|
||||
body: JSON.stringify({
|
||||
start: start,
|
||||
end: end,
|
||||
priority: priority
|
||||
})
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success && data.recommendation) {
|
||||
showSmartRecommendation(data.recommendation);
|
||||
} else {
|
||||
showNoRecommendationMessage(data.message || 'Keine Empfehlung verfügbar');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Fehler beim Abrufen der Empfehlung:', error);
|
||||
showNoRecommendationMessage('Fehler beim Abrufen der Empfehlung');
|
||||
}
|
||||
}
|
||||
|
||||
function showSmartRecommendation(recommendation) {
|
||||
let existingRecommendation = document.getElementById('smart-recommendation');
|
||||
if (existingRecommendation) {
|
||||
existingRecommendation.remove();
|
||||
@@ -1083,32 +1111,46 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
recommendationDiv.id = 'smart-recommendation';
|
||||
recommendationDiv.className = 'mt-3 p-4 bg-gradient-to-r from-green-50 to-blue-50 dark:from-green-900/20 dark:to-blue-900/20 rounded-lg border border-green-200 dark:border-green-800 transition-all duration-300';
|
||||
|
||||
// Simuliere intelligente Empfehlung basierend auf Zeit und Priorität
|
||||
const recommendations = getSmartRecommendation(start, end, priority);
|
||||
// Optimierungsindikator
|
||||
const optimizedBadge = recommendation.priority_optimized
|
||||
? '<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/50 dark:text-green-300 ml-2">✨ Priorität optimiert</span>'
|
||||
: '';
|
||||
|
||||
recommendationDiv.innerHTML = `
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="w-8 h-8 bg-gradient-to-br from-green-400 to-blue-500 rounded-full flex items-center justify-center">
|
||||
<div class="w-8 h-8 bg-gradient-to-br from-green-400 to-blue-500 rounded-full flex items-center justify-center animate-pulse">
|
||||
<svg class="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h4 class="font-semibold text-green-800 dark:text-green-300 mb-2">🎯 Intelligente Empfehlung</h4>
|
||||
<h4 class="font-semibold text-green-800 dark:text-green-300 mb-2 flex items-center">
|
||||
🎯 Intelligente Empfehlung${optimizedBadge}
|
||||
</h4>
|
||||
<div class="text-sm text-green-700 dark:text-green-400">
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<span class="font-medium">Empfohlener Drucker:</span>
|
||||
<span class="px-2 py-1 bg-white dark:bg-slate-800 rounded-full border border-green-300 dark:border-green-600">
|
||||
🖨️ ${recommendations.printer}
|
||||
<span class="px-2 py-1 bg-white dark:bg-slate-800 rounded-full border border-green-300 dark:border-green-600 font-medium">
|
||||
🖨️ ${recommendation.printer_name}
|
||||
</span>
|
||||
${recommendation.location ? `<span class="text-xs text-green-600 dark:text-green-500">(📍 ${recommendation.location})</span>` : ''}
|
||||
</div>
|
||||
<div class="text-xs text-green-600 dark:text-green-500 mt-2">
|
||||
💡 ${recommendations.reason}
|
||||
💡 ${recommendation.reason}
|
||||
</div>
|
||||
<div class="flex items-center gap-4 mt-2 text-xs">
|
||||
<span>⚡ Verfügbarkeit: ${recommendations.availability}</span>
|
||||
<span>📊 Auslastung: ${recommendations.utilization}</span>
|
||||
<span>🎯 Eignung: ${recommendations.suitability}</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="w-2 h-2 bg-green-500 rounded-full"></span>
|
||||
Verfügbarkeit: ${recommendation.availability}
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="w-2 h-2 bg-blue-500 rounded-full"></span>
|
||||
Auslastung: ${recommendation.utilization}
|
||||
</span>
|
||||
<span class="flex items-center gap-1">
|
||||
<span class="w-2 h-2 bg-purple-500 rounded-full"></span>
|
||||
Eignung: ${recommendation.suitability}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1120,10 +1162,43 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
// Animation
|
||||
setTimeout(() => {
|
||||
recommendationDiv.classList.add('animate-pulse');
|
||||
setTimeout(() => recommendationDiv.classList.remove('animate-pulse'), 1000);
|
||||
setTimeout(() => recommendationDiv.classList.remove('animate-pulse'), 1500);
|
||||
}, 100);
|
||||
}
|
||||
|
||||
function showNoRecommendationMessage(message) {
|
||||
let existingRecommendation = document.getElementById('smart-recommendation');
|
||||
if (existingRecommendation) {
|
||||
existingRecommendation.remove();
|
||||
}
|
||||
|
||||
const printerContainer = document.getElementById('eventPrinter').parentElement;
|
||||
const recommendationDiv = document.createElement('div');
|
||||
recommendationDiv.id = 'smart-recommendation';
|
||||
recommendationDiv.className = 'mt-3 p-4 bg-gradient-to-r from-yellow-50 to-orange-50 dark:from-yellow-900/20 dark:to-orange-900/20 rounded-lg border border-yellow-200 dark:border-yellow-800 transition-all duration-300';
|
||||
|
||||
recommendationDiv.innerHTML = `
|
||||
<div class="flex items-start gap-3">
|
||||
<div class="w-8 h-8 bg-gradient-to-br from-yellow-400 to-orange-500 rounded-full flex items-center justify-center">
|
||||
<svg class="w-4 h-4 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.864-.833-2.634 0L4.18 16.5c-.77.833.192 2.5 1.732 2.5z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h4 class="font-semibold text-yellow-800 dark:text-yellow-300 mb-2">⚠️ Keine automatische Zuweisung möglich</h4>
|
||||
<div class="text-sm text-yellow-700 dark:text-yellow-400">
|
||||
${message}
|
||||
<div class="mt-2 text-xs">
|
||||
Bitte wählen Sie einen spezifischen Drucker aus der Liste oder ändern Sie den Zeitraum.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
printerContainer.appendChild(recommendationDiv);
|
||||
}
|
||||
|
||||
function hideSmartRecommendation() {
|
||||
const existingRecommendation = document.getElementById('smart-recommendation');
|
||||
if (existingRecommendation) {
|
||||
@@ -1133,48 +1208,6 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
}
|
||||
|
||||
function getSmartRecommendation(start, end, priority) {
|
||||
// Simuliere intelligente Logik basierend auf Zeit und Priorität
|
||||
const startHour = new Date(start).getHours();
|
||||
const duration = (new Date(end) - new Date(start)) / (1000 * 60 * 60); // Stunden
|
||||
|
||||
let recommendations = {
|
||||
printer: "MYP-Drucker-01 (Halle A)",
|
||||
reason: "Optimale Verfügbarkeit und geringe Auslastung im gewählten Zeitraum",
|
||||
availability: "98%",
|
||||
utilization: "24%",
|
||||
suitability: "Ausgezeichnet"
|
||||
};
|
||||
|
||||
if (priority === 'urgent') {
|
||||
recommendations = {
|
||||
printer: "MYP-Express-Drucker (Halle B)",
|
||||
reason: "Schnellster verfügbarer Drucker für dringende Aufträge",
|
||||
availability: "100%",
|
||||
utilization: "15%",
|
||||
suitability: "Perfekt"
|
||||
};
|
||||
} else if (startHour >= 18 || startHour <= 6) {
|
||||
recommendations = {
|
||||
printer: "MYP-Nacht-Drucker (Halle C)",
|
||||
reason: "Speziell für Nachtschichten optimiert",
|
||||
availability: "95%",
|
||||
utilization: "12%",
|
||||
suitability: "Optimal"
|
||||
};
|
||||
} else if (duration > 8) {
|
||||
recommendations = {
|
||||
printer: "MYP-Langzeit-Drucker (Halle A)",
|
||||
reason: "Zuverlässig für lange Druckaufträge",
|
||||
availability: "90%",
|
||||
utilization: "35%",
|
||||
suitability: "Sehr gut"
|
||||
};
|
||||
}
|
||||
|
||||
return recommendations;
|
||||
}
|
||||
|
||||
// Event Listeners für dynamische Empfehlung
|
||||
document.getElementById('eventStart').addEventListener('change', updatePrinterRecommendation);
|
||||
document.getElementById('eventEnd').addEventListener('change', updatePrinterRecommendation);
|
||||
|
Reference in New Issue
Block a user