logincontroller update

This commit is contained in:
2026-07-02 10:54:23 +02:00
parent 27cbc9f449
commit c675eb766e
2 changed files with 223 additions and 8 deletions
@@ -113,10 +113,16 @@ class LoginController extends Controller
return redirect()->to('userarea/production_dashboard.php'); return redirect()->to('userarea/production_dashboard.php');
} elseif ($user->hasRole('HR')) { } elseif ($user->hasRole('HR')) {
return redirect()->to('userarea/production_dashboard.php'); return redirect()->to('userarea/production_dashboard.php');
} elseif ($user->hasRole('employee-hr')) {
return redirect()->to('userarea/production_dashboard.php');
} elseif ($user->hasRole('SuperUser')) { } elseif ($user->hasRole('SuperUser')) {
return redirect()->to('userarea/production_dashboard.php'); return redirect()->to('userarea/production_dashboard.php');
} elseif ($user->hasRole('Management')) { } elseif ($user->hasRole('Management')) {
return redirect()->to('userarea/production_dashboard.php'); return redirect()->to('userarea/production_dashboard.php');
} elseif ($user->hasRole('manager')) {
return redirect()->to('userarea/production_dashboard.php');
} elseif ($user->hasRole('employee')) {
return redirect()->to('userarea/production_dashboard.php');
} elseif ($user->hasRole('Quality')) { } elseif ($user->hasRole('Quality')) {
return redirect()->to('userarea/production_dashboard.php'); return redirect()->to('userarea/production_dashboard.php');
} }
+217 -8
View File
@@ -468,6 +468,10 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
✏️ 3. Disegna profilo ✏️ 3. Disegna profilo
</button> </button>
<button type="button" id="edgeSnapBtn" class="btn btn-outline-warning">
🧲 Magnete bordo OFF
</button>
<button type="button" id="toolHoleBtn" class="btn btn-outline-danger"> <button type="button" id="toolHoleBtn" class="btn btn-outline-danger">
4. Area da escludere 4. Area da escludere
</button> </button>
@@ -600,6 +604,13 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
const POINT_HIT_RADIUS = 12; const POINT_HIT_RADIUS = 12;
const SEGMENT_HIT_RADIUS = 12; const SEGMENT_HIT_RADIUS = 12;
let edgeSnapEnabled = false;
let edgeSnapPreviewPoint = null;
const EDGE_SNAP_RADIUS = 45;
const EDGE_DARK_THRESHOLD = 245;
const EDGE_GRADIENT_THRESHOLD = 8;
let lastManualResult = null; let lastManualResult = null;
$(document).ready(function() { $(document).ready(function() {
@@ -1057,6 +1068,15 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
document.getElementById('saveManualAreaBtn').disabled = true; document.getElementById('saveManualAreaBtn').disabled = true;
document.getElementById('manualCoordsPreview').innerText = 'Nessun dato calcolato.'; document.getElementById('manualCoordsPreview').innerText = 'Nessun dato calcolato.';
edgeSnapEnabled = false;
const edgeSnapBtn = document.getElementById('edgeSnapBtn');
if (edgeSnapBtn) {
edgeSnapBtn.classList.remove('btn-warning', 'active');
edgeSnapBtn.classList.add('btn-outline-warning');
edgeSnapBtn.innerText = '🧲 Magnete bordo OFF';
}
setTool('roi'); setTool('roi');
} }
@@ -1100,7 +1120,8 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (selectedEditPoint) { if (selectedEditPoint) {
isDraggingEditPoint = true; isDraggingEditPoint = true;
editDragMoved = false; editDragMoved = false;
updateSelectedPointPosition(pos); const finalPos = getSnappedPoint(pos);
updateSelectedPointPosition(finalPos);
markManualResultDirty(); markManualResultDirty();
redrawManualOverlay(); redrawManualOverlay();
updateManualPreview(); updateManualPreview();
@@ -1141,13 +1162,24 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
} }
if (currentTool === 'edit' && isDraggingEditPoint && selectedEditPoint) { if (currentTool === 'edit' && isDraggingEditPoint && selectedEditPoint) {
updateSelectedPointPosition(pos); const finalPos = getSnappedPoint(pos);
updateSelectedPointPosition(finalPos);
editDragMoved = true; editDragMoved = true;
markManualResultDirty(); markManualResultDirty();
redrawManualOverlay(); redrawManualOverlay();
updateManualPreview(); updateManualPreview();
return; return;
} }
if (edgeSnapEnabled && ['polygon', 'hole', 'edit'].includes(currentTool)) {
edgeSnapPreviewPoint = snapToNearestEdge(pos, EDGE_SNAP_RADIUS);
redrawManualOverlay();
return;
}
if (edgeSnapPreviewPoint) {
edgeSnapPreviewPoint = null;
redrawManualOverlay();
}
}; };
manualOverlayCanvas.onmouseup = function() { manualOverlayCanvas.onmouseup = function() {
@@ -1262,6 +1294,123 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
}; };
} }
function getSnappedPoint(pos) {
if (!edgeSnapEnabled) {
return pos;
}
if (!manualPdfCanvas || !manualPdfCtx) {
return pos;
}
if (!['polygon', 'hole', 'edit'].includes(currentTool)) {
return pos;
}
const snapped = snapToNearestEdge(pos, EDGE_SNAP_RADIUS);
if (snapped) {
edgeSnapPreviewPoint = snapped;
return snapped;
}
edgeSnapPreviewPoint = null;
return pos;
}
function snapToNearestEdge(pos, radius) {
const canvasWidth = manualPdfCanvas.width;
const canvasHeight = manualPdfCanvas.height;
const cx = Math.round(pos.x);
const cy = Math.round(pos.y);
const x0 = Math.max(1, cx - radius);
const y0 = Math.max(1, cy - radius);
const x1 = Math.min(canvasWidth - 2, cx + radius);
const y1 = Math.min(canvasHeight - 2, cy + radius);
const w = x1 - x0 + 1;
const h = y1 - y0 + 1;
if (w <= 3 || h <= 3) {
return null;
}
let imageData;
try {
imageData = manualPdfCtx.getImageData(x0, y0, w, h);
} catch (e) {
console.warn('Edge snap getImageData failed:', e);
return null;
}
const data = imageData.data;
function grayAt(localX, localY) {
const index = (localY * w + localX) * 4;
const r = data[index];
const g = data[index + 1];
const b = data[index + 2];
return (r + g + b) / 3;
}
let best = null;
let bestScore = -Infinity;
for (let yy = 1; yy < h - 1; yy++) {
for (let xx = 1; xx < w - 1; xx++) {
const globalX = x0 + xx;
const globalY = y0 + yy;
const dx = globalX - pos.x;
const dy = globalY - pos.y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist > radius) {
continue;
}
const center = grayAt(xx, yy);
const gx = Math.abs(grayAt(xx + 1, yy) - grayAt(xx - 1, yy));
const gy = Math.abs(grayAt(xx, yy + 1) - grayAt(xx, yy - 1));
const gradient = gx + gy;
const isDarkEnough = center < EDGE_DARK_THRESHOLD;
const isRealEdge = gradient > EDGE_GRADIENT_THRESHOLD;
if (!isDarkEnough && !isRealEdge) {
continue;
}
/*
* Prefer:
* - dark strokes
* - real contrast edges
* - points close to the cursor
*/
const darknessScore = Math.max(0, 255 - center);
const gradientScore = gradient * 3;
const distancePenalty = dist * 4;
const score = darknessScore + gradientScore - distancePenalty;
if (score > bestScore) {
bestScore = score;
best = {
x: globalX,
y: globalY
};
}
}
}
return best;
}
function handleCalibrationClick(pos) { function handleCalibrationClick(pos) {
if (calibrationPoints.length >= 2) { if (calibrationPoints.length >= 2) {
calibrationPoints = []; calibrationPoints = [];
@@ -1334,7 +1483,8 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
return; return;
} }
polygonPoints.push(pos); const finalPos = getSnappedPoint(pos);
polygonPoints.push(finalPos);
selectedEditPoint = { selectedEditPoint = {
type: 'outer', type: 'outer',
pointIndex: polygonPoints.length - 1 pointIndex: polygonPoints.length - 1
@@ -1364,7 +1514,8 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
return; return;
} }
currentHolePoints.push(pos); const finalPos = getSnappedPoint(pos);
currentHolePoints.push(finalPos);
selectedEditPoint = { selectedEditPoint = {
type: 'currentHole', type: 'currentHole',
pointIndex: currentHolePoints.length - 1 pointIndex: currentHolePoints.length - 1
@@ -1409,6 +1560,32 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
drawCalibration(); drawCalibration();
drawPolygon(); drawPolygon();
drawHoles(); drawHoles();
drawEdgeSnapPreview();
}
function drawEdgeSnapPreview() {
if (!edgeSnapEnabled || !edgeSnapPreviewPoint) {
return;
}
manualOverlayCtx.save();
manualOverlayCtx.strokeStyle = 'rgba(245, 158, 11, 1)';
manualOverlayCtx.fillStyle = 'rgba(245, 158, 11, 0.95)';
manualOverlayCtx.lineWidth = 2;
manualOverlayCtx.beginPath();
manualOverlayCtx.arc(edgeSnapPreviewPoint.x, edgeSnapPreviewPoint.y, 8, 0, Math.PI * 2);
manualOverlayCtx.stroke();
manualOverlayCtx.beginPath();
manualOverlayCtx.moveTo(edgeSnapPreviewPoint.x - 13, edgeSnapPreviewPoint.y);
manualOverlayCtx.lineTo(edgeSnapPreviewPoint.x + 13, edgeSnapPreviewPoint.y);
manualOverlayCtx.moveTo(edgeSnapPreviewPoint.x, edgeSnapPreviewPoint.y - 13);
manualOverlayCtx.lineTo(edgeSnapPreviewPoint.x, edgeSnapPreviewPoint.y + 13);
manualOverlayCtx.stroke();
manualOverlayCtx.restore();
} }
function drawRoi() { function drawRoi() {
@@ -1838,9 +2015,11 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
return false; return false;
} }
const finalPos = getSnappedPoint(pos);
arr.splice(segment.insertIndex, 0, { arr.splice(segment.insertIndex, 0, {
x: pos.x, x: finalPos.x,
y: pos.y y: finalPos.y
}); });
selectedEditPoint = { selectedEditPoint = {
@@ -2411,9 +2590,12 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
function getCanvasMousePosition(event, canvas) { function getCanvasMousePosition(event, canvas) {
const rect = canvas.getBoundingClientRect(); const rect = canvas.getBoundingClientRect();
const scaleX = canvas.width / rect.width;
const scaleY = canvas.height / rect.height;
return { return {
x: event.clientX - rect.left, x: (event.clientX - rect.left) * scaleX,
y: event.clientY - rect.top y: (event.clientY - rect.top) * scaleY
}; };
} }
@@ -2442,6 +2624,33 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);
setTool('polygon'); setTool('polygon');
}); });
document.getElementById('edgeSnapBtn').addEventListener('click', function() {
edgeSnapEnabled = !edgeSnapEnabled;
const btn = document.getElementById('edgeSnapBtn');
if (edgeSnapEnabled) {
btn.classList.remove('btn-outline-warning');
btn.classList.add('btn-warning', 'active');
btn.innerText = '🧲 Magnete bordo ON';
setManualStatus(
'Magnete bordo attivo: quando disegni o sposti punti, il sistema prova ad agganciarli al bordo scuro più vicino.'
);
} else {
btn.classList.remove('btn-warning', 'active');
btn.classList.add('btn-outline-warning');
btn.innerText = '🧲 Magnete bordo OFF';
edgeSnapPreviewPoint = null;
redrawManualOverlay();
setManualStatus(
'Magnete bordo disattivato: i punti verranno inseriti esattamente dove clicchi.'
);
}
});
document.getElementById('undoPointBtn').addEventListener('click', function() { document.getElementById('undoPointBtn').addEventListener('click', function() {
if (currentTool === 'hole' && currentHolePoints.length > 0) { if (currentTool === 'hole' && currentHolePoints.length > 0) {
currentHolePoints.pop(); currentHolePoints.pop();