@props([ 'type' => 'violation', 'details' => '', 'timestamp' => null, 'screenshotUrl' => null, 'aiVerdict' => null, ]) @php $icoClass = 'amber'; $faIcon = 'fa-solid fa-window-restore'; $isFlag = false; if (in_array($type, ['focus_lost', 'tab_switch'])) { $icoClass = 'amber'; $faIcon = 'fa-solid fa-window-restore'; } elseif (in_array($type, ['gaze_anomaly', 'gaze_fixed_staring'])) { $icoClass = 'amber'; $faIcon = 'fa-solid fa-eye'; } elseif ($type === 'looking_away') { $icoClass = 'amber'; $faIcon = 'fa-solid fa-eye-slash'; } elseif ($type === 'face_missing') { $icoClass = 'red'; $faIcon = 'fa-solid fa-user-slash'; $isFlag = true; } elseif ($type === 'multiple_faces') { $icoClass = 'red'; $faIcon = 'fa-solid fa-users-viewfinder'; $isFlag = true; } elseif ($type === 'prolonged_looking_away') { $icoClass = 'red'; $faIcon = 'fa-solid fa-clock-rotate-left'; $isFlag = true; } elseif ($type === 'phone_detected') { $icoClass = 'red'; $faIcon = 'fa-solid fa-mobile-screen-button'; $isFlag = true; } elseif ($type === 'prolonged_corner_gaze') { $icoClass = 'amber'; $faIcon = 'fa-solid fa-arrows-to-eye'; $isFlag = true; } elseif ($type === 'talking_secondary_person') { $icoClass = 'red'; $faIcon = 'fa-solid fa-user-group'; $isFlag = true; } elseif (in_array($type, ['gaze_lower_device', 'reading_external_device'])) { $icoClass = 'red'; $faIcon = 'fa-solid fa-mobile-screen'; $isFlag = true; } elseif (in_array($type, ['question_repeat_lower', 'question_repetition'])) { $icoClass = 'red'; $faIcon = 'fa-solid fa-comments'; $isFlag = true; } elseif ($type === 'talking_on_phone') { $icoClass = 'red'; $faIcon = 'fa-solid fa-phone'; $isFlag = true; } elseif ($type === 'external_ai_detected') { $icoClass = 'red'; $faIcon = 'fa-solid fa-robot'; $isFlag = true; } elseif ($type === 'paste_event') { $icoClass = 'red'; $faIcon = 'fa-solid fa-paste'; $isFlag = true; } elseif ($type === 'copy_event') { $icoClass = 'amber'; $faIcon = 'fa-solid fa-copy'; } $titleCap = ucfirst(str_replace('_', ' ', $type)); $timeStr = $timestamp ? \Carbon\Carbon::parse($timestamp)->format('h:i:s a') : now()->format('h:i:s a'); // Human readable details parsing $detailsObj = is_array($details) ? $details : (is_string($details) && str_starts_with(trim($details), '{') ? json_decode($details, true) : null); $humanDetails = ''; if ($type === 'multiple_faces') { $count = (is_array($detailsObj) && isset($detailsObj['face_count'])) ? $detailsObj['face_count'] : 2; $humanDetails = "Multiple faces detected in camera frame ({$count} faces)"; } elseif ($type === 'face_missing') { $humanDetails = 'Candidate face is not visible in camera frame'; } elseif (in_array($type, ['looking_away', 'prolonged_looking_away'])) { if (is_array($detailsObj) && (isset($detailsObj['reasons']) || isset($detailsObj['yaw']))) { $reasonLabels = [ 'head_yaw' => 'Head Yaw', 'head_up' => 'Head Pitch Up', 'head_down' => 'Head Pitch Down', 'eye_gaze_left' => 'Eye Gaze Left', 'eye_gaze_right' => 'Eye Gaze Right', 'eye_gaze_down' => 'Eye Gaze Down' ]; $reasonsArr = isset($detailsObj['reasons']) && is_array($detailsObj['reasons']) ? array_map(fn($r) => $reasonLabels[$r] ?? str_replace('_', ' ', $r), $detailsObj['reasons']) : []; $reasonsStr = implode(', ', $reasonsArr); $prefix = ($type === 'prolonged_looking_away') ? 'Looking away continuously (>10s)' : 'Looking away from camera'; $humanDetails = $reasonsStr ? "{$prefix} ({$reasonsStr})" : $prefix; } else { $humanDetails = is_string($details) && !str_starts_with(trim($details), '{') ? $details : ($type === 'prolonged_looking_away' ? 'Candidate prolonged looking away' : 'Candidate looking away from camera'); } } elseif ($type === 'phone_detected') { $label = (is_array($detailsObj) && isset($detailsObj['label'])) ? $detailsObj['label'] : 'cell phone'; $humanDetails = "Possible mobile phone detected in camera frame ({$label})"; } elseif ($type === 'prolonged_corner_gaze') { if (is_array($detailsObj) && (isset($detailsObj['corner_label']) || isset($detailsObj['corner']))) { $cornerLabel = $detailsObj['corner_label'] ?? str_replace('_', ' ', $detailsObj['corner'] ?? 'screen corner'); $dur = $detailsObj['duration_s'] ?? round(($detailsObj['duration_ms'] ?? 18000) / 1000); $humanDetails = "Fixated on {$cornerLabel} for {$dur}s"; } else { $humanDetails = 'Candidate fixated on screen corner for prolonged period'; } } elseif ($type === 'talking_secondary_person') { $humanDetails = is_string($details) && !str_starts_with(trim($details), '{') ? $details : 'Candidate detected speaking out loud to a secondary person'; } else { $humanDetails = is_string($details) ? $details : (is_array($details) ? json_encode($details) : (string)$details); } @endphp