From c675eb766e88ae8b1af5a7b8dd61a462bb3ab9ce Mon Sep 17 00:00:00 2001 From: solocla Date: Thu, 2 Jul 2026 10:54:23 +0200 Subject: [PATCH] logincontroller update --- .../Controllers/Web/Auth/LoginController.php | 6 + public/userarea/cad-area.php | 225 +++++++++++++++++- 2 files changed, 223 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/Web/Auth/LoginController.php b/app/Http/Controllers/Web/Auth/LoginController.php index 7f60e66..0f1071b 100644 --- a/app/Http/Controllers/Web/Auth/LoginController.php +++ b/app/Http/Controllers/Web/Auth/LoginController.php @@ -113,10 +113,16 @@ class LoginController extends Controller return redirect()->to('userarea/production_dashboard.php'); } elseif ($user->hasRole('HR')) { return redirect()->to('userarea/production_dashboard.php'); + } elseif ($user->hasRole('employee-hr')) { + return redirect()->to('userarea/production_dashboard.php'); } elseif ($user->hasRole('SuperUser')) { return redirect()->to('userarea/production_dashboard.php'); } elseif ($user->hasRole('Management')) { 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')) { return redirect()->to('userarea/production_dashboard.php'); } diff --git a/public/userarea/cad-area.php b/public/userarea/cad-area.php index 9a2b2d4..6a9a22d 100644 --- a/public/userarea/cad-area.php +++ b/public/userarea/cad-area.php @@ -468,6 +468,10 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); ✏️ 3. Disegna profilo + + @@ -600,6 +604,13 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); const POINT_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; $(document).ready(function() { @@ -1057,6 +1068,15 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); document.getElementById('saveManualAreaBtn').disabled = true; 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'); } @@ -1100,7 +1120,8 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); if (selectedEditPoint) { isDraggingEditPoint = true; editDragMoved = false; - updateSelectedPointPosition(pos); + const finalPos = getSnappedPoint(pos); + updateSelectedPointPosition(finalPos); markManualResultDirty(); redrawManualOverlay(); updateManualPreview(); @@ -1141,13 +1162,24 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); } if (currentTool === 'edit' && isDraggingEditPoint && selectedEditPoint) { - updateSelectedPointPosition(pos); + const finalPos = getSnappedPoint(pos); + updateSelectedPointPosition(finalPos); editDragMoved = true; markManualResultDirty(); redrawManualOverlay(); updateManualPreview(); return; } + if (edgeSnapEnabled && ['polygon', 'hole', 'edit'].includes(currentTool)) { + edgeSnapPreviewPoint = snapToNearestEdge(pos, EDGE_SNAP_RADIUS); + redrawManualOverlay(); + return; + } + + if (edgeSnapPreviewPoint) { + edgeSnapPreviewPoint = null; + redrawManualOverlay(); + } }; 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) { if (calibrationPoints.length >= 2) { calibrationPoints = []; @@ -1334,7 +1483,8 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); return; } - polygonPoints.push(pos); + const finalPos = getSnappedPoint(pos); + polygonPoints.push(finalPos); selectedEditPoint = { type: 'outer', pointIndex: polygonPoints.length - 1 @@ -1364,7 +1514,8 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); return; } - currentHolePoints.push(pos); + const finalPos = getSnappedPoint(pos); + currentHolePoints.push(finalPos); selectedEditPoint = { type: 'currentHole', pointIndex: currentHolePoints.length - 1 @@ -1409,6 +1560,32 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); drawCalibration(); drawPolygon(); 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() { @@ -1838,9 +2015,11 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); return false; } + const finalPos = getSnappedPoint(pos); + arr.splice(segment.insertIndex, 0, { - x: pos.x, - y: pos.y + x: finalPos.x, + y: finalPos.y }); selectedEditPoint = { @@ -2411,9 +2590,12 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); function getCanvasMousePosition(event, canvas) { const rect = canvas.getBoundingClientRect(); + const scaleX = canvas.width / rect.width; + const scaleY = canvas.height / rect.height; + return { - x: event.clientX - rect.left, - y: event.clientY - rect.top + x: (event.clientX - rect.left) * scaleX, + y: (event.clientY - rect.top) * scaleY }; } @@ -2442,6 +2624,33 @@ $jobs = $stmt->fetchAll(PDO::FETCH_ASSOC); 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() { if (currentTool === 'hole' && currentHolePoints.length > 0) { currentHolePoints.pop();