431 lines
25 KiB
PHP
431 lines
25 KiB
PHP
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
|
<title>{{ $interview->candidate_name }} - Assessment Review | SingleLogin</title>
|
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
|
|
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
|
<script src="https://unpkg.com/peerjs@1.5.2/dist/peerjs.min.js"></script>
|
|
<script src="//cdn.metered.ca/sdk/video/1.4.6/sdk.min.js"></script>
|
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
|
|
|
<style>
|
|
:root {
|
|
--bg: #0a0e17;
|
|
--panel: #121826;
|
|
--panel-2: #0d1220;
|
|
--border: #232b3d;
|
|
--border-soft: #1b2233;
|
|
--text: #e8ebf3;
|
|
--text-dim: #9199ad;
|
|
--text-faint: #5b637a;
|
|
--accent: #4b82f7;
|
|
--accent-soft: rgba(75,130,247,0.12);
|
|
--accent-border: rgba(75,130,247,0.35);
|
|
--success: #21c274;
|
|
--danger: #ef4a5f;
|
|
--danger-soft: rgba(239,74,95,0.1);
|
|
--warning: #f0a939;
|
|
--warning-soft: rgba(240,169,57,0.12);
|
|
--radius: 12px;
|
|
--mono: 'JetBrains Mono', monospace;
|
|
--sans: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
|
|
}
|
|
|
|
body {
|
|
background: radial-gradient(1200px 600px at 15% -10%, rgba(75,130,247,0.06), transparent 60%), var(--bg);
|
|
color: var(--text);
|
|
font-family: var(--sans);
|
|
}
|
|
|
|
/* Toggle switch */
|
|
.toggle {
|
|
width: 32px; height: 18px; border-radius: 20px; background: var(--panel-2);
|
|
border: 1px solid var(--border); position: relative; cursor: pointer; flex-shrink: 0;
|
|
display: inline-block;
|
|
}
|
|
.toggle::after {
|
|
content: ''; position: absolute; top: 2px; left: 2px; width: 12px; height: 12px;
|
|
border-radius: 50%; background: var(--text-faint); transition: left .15s ease;
|
|
}
|
|
.toggle.on { background: var(--accent-soft); border-color: var(--accent-border); }
|
|
.toggle.on::after { left: 16px; background: var(--accent); }
|
|
|
|
/* Accordion disclosure */
|
|
details.meta summary {
|
|
list-style: none; cursor: pointer; user-select: none;
|
|
}
|
|
details.meta summary::-webkit-details-marker { display: none; }
|
|
details.meta summary i.chev { transition: transform .15s ease; }
|
|
details.meta[open] summary i.chev { transform: rotate(180deg); }
|
|
</style>
|
|
</head>
|
|
<body class="min-h-screen flex flex-col antialiased" data-interview-id="{{ $interview->id }}" data-submission-id="{{ $interview->submission_unique_id }}">
|
|
|
|
<div class="w-full mx-auto px-7 py-5 pb-16 flex-1">
|
|
|
|
<!-- Top bar -->
|
|
<div class="flex items-center justify-between pb-4 mb-4 border-b border-[#1b2233]">
|
|
<div class="flex items-center gap-3">
|
|
<a href="{{ route('interview.index') }}" class="w-9 h-9 rounded-xl bg-gradient-to-br from-[#5b8bff] to-[#3b63e0] flex items-center justify-center text-sm text-white shadow-[0_4px_14px_rgba(75,130,247,0.35)] no-underline">
|
|
<i class="fa-solid fa-bolt"></i>
|
|
</a>
|
|
<div>
|
|
<h1 class="text-base font-semibold text-white m-0 tracking-tight">Candidate Assessment Review</h1>
|
|
<p class="text-xs text-[#5b637a] m-0 mt-0.5">Live proctored session & review room</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-1.5">
|
|
<a href="{{ route('interview.index') }}">
|
|
<x-button variant="ghost" icon="fa-solid fa-arrow-left">Back to assessments</x-button>
|
|
</a>
|
|
@if(Auth::user()->isAdmin())
|
|
<a href="{{ route('admin.dashboard') }}">
|
|
<x-button variant="ghost" icon="fa-solid fa-sliders">Control panel</x-button>
|
|
</a>
|
|
@endif
|
|
<form action="{{ route('logout') }}" method="POST" id="logout-form" class="inline">
|
|
@csrf
|
|
<x-button type="button" onclick="interviewerLogoutAction()" variant="ghost" icon="fa-solid fa-arrow-right-from-bracket">Logout</x-button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
@if(session('success'))
|
|
<div class="mb-4 bg-[#21c274]/15 border border-[#21c274]/35 text-[#21c274] px-4 py-2.5 rounded-lg text-xs font-medium">
|
|
{{ session('success') }}
|
|
</div>
|
|
@endif
|
|
|
|
<!-- Session Panel -->
|
|
<div class="bg-[#121826] border border-[#1b2233] rounded-[12px] mb-4 overflow-hidden">
|
|
<div class="flex items-center justify-between p-5 gap-4 flex-wrap">
|
|
<div class="flex items-center gap-3.5">
|
|
@php
|
|
$parts = preg_split('/\s+/', trim($interview->candidate_name));
|
|
$candInitials = count($parts) >= 2 ? strtoupper(substr($parts[0],0,1).substr(end($parts),0,1)) : strtoupper(substr($interview->candidate_name,0,2));
|
|
@endphp
|
|
<div class="w-[42px] h-[42px] rounded-full bg-gradient-to-br from-[#5b8bff] to-[#3b63e0] flex items-center justify-center text-white font-semibold text-[15px] shrink-0">
|
|
{{ $candInitials }}
|
|
</div>
|
|
<div>
|
|
<div class="flex items-center gap-2 mb-0.5">
|
|
<h2 id="modal-cand-name" class="text-[15px] font-semibold text-white m-0 leading-none">{{ $interview->candidate_name }}</h2>
|
|
<span id="candidate-joined-pill" class="pill gray inline-flex items-center gap-1.5 font-semibold text-[11px] px-2.5 py-0.5 rounded-full border border-slate-700 text-slate-400 bg-slate-800/60">
|
|
<i class="fa-solid fa-circle text-[8px] text-slate-500"></i> Not Joined
|
|
</span>
|
|
</div>
|
|
<div class="text-xs text-[#5b637a] font-mono">{{ $interview->candidate_email }} · {{ $interview->candidate_phone }}</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex items-center gap-1.5 flex-wrap">
|
|
@if($interview->isExpired())
|
|
<x-pill id="timeline-status-pill" variant="red" icon="fa-solid fa-circle">Expired</x-pill>
|
|
@elseif($interview->status === 'completed')
|
|
<x-pill id="timeline-status-pill" variant="success" icon="fa-solid fa-circle">Completed</x-pill>
|
|
@elseif($interview->call_status === 'active')
|
|
<x-pill id="timeline-status-pill" variant="blue" class="live" icon="fa-solid fa-circle">Call in progress</x-pill>
|
|
@elseif($interview->isActiveTimeline())
|
|
<x-pill id="timeline-status-pill" variant="blue" class="live" icon="fa-solid fa-circle">Timeline live</x-pill>
|
|
@else
|
|
<x-pill id="timeline-status-pill" variant="secondary" icon="fa-solid fa-clock">Scheduled</x-pill>
|
|
@endif
|
|
|
|
<div class="w-px h-[18px] bg-[#232b3d] mx-1"></div>
|
|
|
|
<div class="flex items-center gap-2 text-xs text-[#9199ad] cursor-pointer" onclick="toggleSosAutoTrigger()">
|
|
<span class="toggle" id="sosToggle"></span> SOS auto-trigger
|
|
</div>
|
|
|
|
<div class="w-px h-[18px] bg-[#232b3d] mx-1"></div>
|
|
|
|
<x-button onclick="regenerateCandidatePassword()" variant="secondary" icon="fa-solid fa-key">Password</x-button>
|
|
<x-button onclick="openReportPage()" variant="secondary" icon="fa-solid fa-file-pdf">PDF report</x-button>
|
|
<x-button onclick="blockCandidateAction()" variant="secondary" icon="fa-solid fa-ban">Block</x-button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Submission Details Disclosure Accordion -->
|
|
<details class="meta border-t border-[#1b2233]">
|
|
<summary class="flex items-center gap-2 px-5 py-2.5 text-xs text-[#5b637a] font-medium hover:text-[#9199ad] transition-colors">
|
|
<i class="fa-solid fa-chevron-down chev text-[10px]"></i> Show submission details
|
|
</summary>
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-2.5 px-5 pb-4">
|
|
<div class="bg-[#0d1220] border border-[#1b2233] rounded-lg p-2.5">
|
|
<div class="text-[10.5px] text-[#5b637a] uppercase tracking-wider mb-1">Submission ID</div>
|
|
<div id="modal-cand-uid" class="text-xs font-mono text-[#9199ad] break-all">{{ $interview->submission_unique_id }}</div>
|
|
</div>
|
|
<div class="bg-[#0d1220] border border-[#1b2233] rounded-lg p-2.5">
|
|
<div class="text-[10.5px] text-[#5b637a] uppercase tracking-wider mb-1">Temp Pass</div>
|
|
<div class="text-xs font-mono text-[#9199ad]">{{ $interview->temp_password }}</div>
|
|
</div>
|
|
<div class="bg-[#0d1220] border border-[#1b2233] rounded-lg p-2.5">
|
|
<div class="text-[10.5px] text-[#5b637a] uppercase tracking-wider mb-1">Language</div>
|
|
<div class="text-xs font-mono text-[#9199ad] uppercase">{{ $interview->language }}</div>
|
|
</div>
|
|
<div class="bg-[#0d1220] border border-[#1b2233] rounded-lg p-2.5">
|
|
<div class="text-[10.5px] text-[#5b637a] uppercase tracking-wider mb-1">Timeline</div>
|
|
<div class="text-xs font-mono text-[#9199ad]">{{ ($interview->scheduled_at ?? $interview->created_at)->format('M d, H:i') }} – {{ $interview->expires_at->format('H:i') }}</div>
|
|
</div>
|
|
</div>
|
|
</details>
|
|
</div>
|
|
|
|
<!-- Call Panel -->
|
|
<x-card>
|
|
<x-slot:headerExtra>
|
|
<div class="flex items-center gap-2">
|
|
<!-- 1. Mic Toggle (Icon Only) -->
|
|
<x-button id="btn-toggle-interviewer-mic" onclick="toggleInterviewerMic()" variant="ghost" icon="fa-solid fa-microphone" style="display: none;" title="Mic On / Mute"></x-button>
|
|
|
|
<!-- 2. Cam Toggle (Icon Only) -->
|
|
<x-button id="btn-toggle-interviewer-cam" onclick="toggleInterviewerCam()" variant="ghost" icon="fa-solid fa-video" style="display: none;" title="Cam On / Off"></x-button>
|
|
|
|
<!-- 3. Start / Join / Restart Call -->
|
|
<x-button id="btn-start-call" onclick="startInterviewerCall()" variant="primary" icon="fa-solid fa-phone">
|
|
Start / Join Call
|
|
</x-button>
|
|
|
|
<!-- 4. Record Call (Silent) -->
|
|
<x-button id="btn-start-recording" onclick="startCallRecording()" variant="secondary" icon="fa-solid fa-circle-dot">
|
|
Record Call (Silent)
|
|
</x-button>
|
|
<x-button id="btn-stop-recording" onclick="stopCallRecording()" variant="danger" icon="fa-solid fa-square" style="display: none;" class="animate-pulse" title="Stop & Save Recording"></x-button>
|
|
|
|
<!-- 5. Leave Call -->
|
|
<x-button id="btn-leave-call" onclick="leaveInterviewerCall()" variant="secondary" icon="fa-solid fa-arrow-right-from-bracket" style="display: none;">
|
|
Leave Call
|
|
</x-button>
|
|
|
|
<!-- 6. End Call for All (Icon Only, Far Right) -->
|
|
<x-button id="btn-end-all-call" onclick="endCallForAll()" variant="danger" icon="fa-solid fa-phone-slash" style="display: none;" title="End Call for All"></x-button>
|
|
</div>
|
|
</x-slot:headerExtra>
|
|
|
|
<!-- Video Grid -->
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-3.5 p-5">
|
|
<!-- Candidate Video -->
|
|
<x-video-tile
|
|
id="cand-video-wrapper"
|
|
videoId="interviewer-cand-video"
|
|
placeholderId="cand-video-placeholder"
|
|
badgeText="Candidate video"
|
|
micStatusId="cand-mic-status"
|
|
camStatusId="cand-cam-status"
|
|
showZoom="true"
|
|
zoomInFn="zoomCandVideo(0.25)"
|
|
zoomOutFn="zoomCandVideo(-0.25)"
|
|
zoomResetFn="zoomCandVideo(0)"
|
|
avatarCircleId="modal-cand-avatar-circle"
|
|
avatarNameId="cand-avatar-name"
|
|
avatarTitle="{{ $interview->candidate_name }}"
|
|
initials="{{ $candInitials }}">
|
|
<span id="cand-status-text">Waiting for candidate…</span>
|
|
</x-video-tile>
|
|
|
|
<!-- Candidate Shared Screen -->
|
|
<x-video-tile
|
|
id="screen-wrapper"
|
|
videoId="interviewer-screen-video"
|
|
placeholderId="screen-video-placeholder"
|
|
badgeText="Shared screen"
|
|
focused="true"
|
|
showZoom="true"
|
|
showFullscreen="true"
|
|
zoomInFn="zoomScreen(0.25)"
|
|
zoomOutFn="zoomScreen(-0.25)"
|
|
zoomResetFn="resetZoomScreen()"
|
|
fullscreenFn="toggleFullscreenScreen()"
|
|
containerId="screen-zoom-container"
|
|
avatarTitle="Candidate live screen"
|
|
initials="CD">
|
|
Waiting for candidate to share screen…
|
|
</x-video-tile>
|
|
|
|
<!-- Panelist Self -->
|
|
@php
|
|
$usrWords = preg_split('/\s+/', trim(Auth::user()->name));
|
|
$usrInitials = count($usrWords) >= 2 ? strtoupper(substr($usrWords[0],0,1).substr(end($usrWords),0,1)) : strtoupper(substr(trim(Auth::user()->name),0,2));
|
|
@endphp
|
|
<x-video-tile
|
|
id="self-video-wrapper"
|
|
videoId="interviewer-self-video"
|
|
placeholderId="self-video-placeholder"
|
|
badgeText="Panelist self"
|
|
micStatusId="self-mic-status"
|
|
camStatusId="self-cam-status"
|
|
avatarTitle="{{ Auth::user()->name }}"
|
|
initials="{{ $usrInitials }}">
|
|
Panelist (self)
|
|
</x-video-tile>
|
|
</div>
|
|
|
|
<!-- Multi-Party Panelist Video Grid -->
|
|
<div id="panelist-mesh-grid" class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-3.5 px-5 pb-5"></div>
|
|
</x-card>
|
|
|
|
<!-- Inspector Panel -->
|
|
<x-card>
|
|
<div class="inline-flex gap-1 p-1 bg-[#0d1220] border border-[#1b2233] rounded-[10px] mx-5 mt-4">
|
|
<x-tab-button id="tab-btn-code" tabKey="code" active="true" icon="fa-solid fa-code" onclick="switchIdeTab('code')">Live IDE code</x-tab-button>
|
|
<x-tab-button id="tab-btn-notes" tabKey="notes" active="false" icon="fa-solid fa-note-sticky" onclick="switchIdeTab('notes')">Candidate notepad</x-tab-button>
|
|
<x-tab-button id="tab-btn-drawing" tabKey="drawing" active="false" icon="fa-solid fa-pen" onclick="switchIdeTab('drawing')">Candidate drawing</x-tab-button>
|
|
<x-tab-button id="tab-btn-recordings" tabKey="recordings" active="false" icon="fa-solid fa-film" onclick="switchIdeTab('recordings')">Saved recordings</x-tab-button>
|
|
<x-tab-button id="tab-btn-screenshots" tabKey="screenshots" active="false" icon="fa-solid fa-image" onclick="switchIdeTab('screenshots')">Tab switch screenshots</x-tab-button>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 lg:grid-cols-5 gap-4 p-5">
|
|
<!-- Left 3 Cols: Tab Content -->
|
|
<div class="lg:col-span-3">
|
|
<!-- Tab 1: Live IDE Code -->
|
|
<div id="tab-content-code" class="block">
|
|
<div class="text-[11.5px] text-[#5b637a] mb-2 font-medium">Current code solution — visible even if candidate does not share screen</div>
|
|
<pre id="modal-code-display" class="bg-[#0d1220] border border-[#1b2233] rounded-[9px] p-3.5 font-mono text-[13px] text-[#6ee7c9] min-h-[220px] max-h-[300px] overflow-y-auto whitespace-pre-wrap"></pre>
|
|
|
|
<div class="text-[11.5px] text-[#5b637a] mt-4 mb-2 font-medium">Execution stdout / stderr</div>
|
|
<pre id="modal-output-display" class="bg-[#0d1220] border border-[#1b2233] rounded-[9px] p-3 font-mono text-xs text-[#5b637a] max-h-[100px] overflow-y-auto whitespace-pre-wrap"></pre>
|
|
</div>
|
|
|
|
<!-- Tab 2: Candidate Notepad -->
|
|
<div id="tab-content-notes" class="hidden">
|
|
<div class="text-[11.5px] text-[#5b637a] mb-2 font-medium">Candidate live notepad notes (auto-synced)</div>
|
|
<pre id="modal-notes-display" class="bg-[#0d1220] border border-[#1b2233] rounded-[9px] p-3.5 font-mono text-xs text-slate-200 min-h-[250px] max-h-[350px] overflow-y-auto whitespace-pre-wrap"></pre>
|
|
</div>
|
|
|
|
<!-- Tab 3: Candidate Canvas Drawing -->
|
|
<div id="tab-content-drawing" class="hidden">
|
|
<div class="text-[11.5px] text-[#5b637a] mb-2 font-medium">Candidate live drawing / architecture diagram</div>
|
|
<div class="bg-[#0d1220] border border-[#1b2233] rounded-[9px] p-3 flex justify-center items-center min-h-[250px]">
|
|
<img id="modal-drawing-img" src="" alt="Candidate Drawing Board" class="max-w-full max-h-[320px] hidden rounded-lg border border-dashed border-[#232b3d]" />
|
|
<div id="no-drawing-placeholder" class="text-[#5b637a] text-xs">No drawing data submitted by candidate yet.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab 4: Saved Video Recordings -->
|
|
<div id="tab-content-recordings" class="hidden">
|
|
<div class="text-[11.5px] text-[#5b637a] mb-2 font-medium">Saved candidate video sessions (sorted by newest first)</div>
|
|
<div id="modal-recordings-container" class="bg-[#0d1220] border border-[#1b2233] rounded-[9px] p-3 min-h-[250px] max-h-[420px] overflow-y-auto">
|
|
<div class="text-[#5b637a] text-xs text-center pt-10">No video recordings saved for this candidate yet.</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab 5: Tab-Switch Screenshots -->
|
|
<div id="tab-content-screenshots" class="hidden">
|
|
<div class="text-[11.5px] text-[#5b637a] mb-2 font-medium flex justify-between items-center">
|
|
<span>Candidate tab-switch captured screenshots</span>
|
|
<div class="flex items-center gap-2">
|
|
<span class="text-xs text-[#9199ad]">Admin Screenshot Capture:</span>
|
|
<x-button id="modal-toggle-screenshot-btn" onclick="toggleTabScreenshotCapture()" variant="success" size="sm" icon="fa-solid fa-camera">
|
|
ENABLED
|
|
</x-button>
|
|
</div>
|
|
</div>
|
|
<div id="modal-screenshots-container" class="bg-[#0d1220] border border-[#1b2233] rounded-[9px] p-3 min-h-[250px] max-h-[420px] overflow-y-auto">
|
|
<div class="text-[#5b637a] text-xs text-center pt-10">No tab-switch screenshots captured for this candidate yet.</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Right 2 Cols: Audit Log & Chat -->
|
|
<div class="lg:col-span-2">
|
|
<h3 class="text-[12.5px] font-semibold text-white mb-2.5 flex items-center gap-2 m-0">
|
|
Proctoring logs
|
|
</h3>
|
|
|
|
<x-audit-log id="modal-logs-display" :logs="$interview->proctor_logs ?? []" />
|
|
|
|
<div class="mt-4">
|
|
<h3 class="text-[12.5px] font-semibold text-white mb-2.5 flex items-center gap-2 m-0">
|
|
Live Chat
|
|
</h3>
|
|
<x-chat-panel id="interviewer-chat-history" class="mb-2.5" :warnings="$interview->warnings ?? []" :candidateName="$interview->candidate_name" />
|
|
<div class="flex gap-2">
|
|
<input type="text" id="warning-input" placeholder="Type message to candidate…" onkeydown="if(event.key==='Enter') sendSilentWarning()" class="flex-1 bg-[#0d1220] border border-[#232b3d] rounded-lg px-3 py-2 text-white text-xs outline-none focus:border-[rgba(75,130,247,0.35)] placeholder-[#5b637a]">
|
|
<x-button onclick="sendSilentWarning()" variant="primary" icon="fa-solid fa-paper-plane">Send</x-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</x-card>
|
|
|
|
</div>
|
|
|
|
<!-- SOS CHEATING ALERT MODAL -->
|
|
<x-modal id="sos-modal" title="candidate might cheating" maxWidth="lg" onClose="stopSosAlarm">
|
|
<div id="sos-violation-list" class="bg-[rgba(239,74,95,0.1)] border border-[rgba(239,74,95,0.32)] rounded-lg p-3.5 text-xs text-[#ef4a5f] mb-4 max-h-[180px] overflow-y-auto">
|
|
Violation details loading...
|
|
</div>
|
|
<div class="flex justify-end gap-2">
|
|
<x-button onclick="stopSosAlarm()" variant="secondary" size="md" icon="fa-solid fa-check">
|
|
Acknowledge Alert
|
|
</x-button>
|
|
<x-button onclick="disableSosAndStopAlarm()" variant="danger" size="md" icon="fa-solid fa-bell-slash">
|
|
Acknowledge & Disable SOS
|
|
</x-button>
|
|
</div>
|
|
</x-modal>
|
|
|
|
<!-- INCOMING CALL RING MODAL -->
|
|
<x-modal id="incoming-call-modal" maxWidth="md">
|
|
<div class="text-center p-2">
|
|
<div class="relative w-[90px] h-[90px] mx-auto mb-5 flex items-center justify-center">
|
|
<div class="absolute -inset-4 rounded-full border-2 border-[#21c274]/60 animate-ping"></div>
|
|
<div class="w-20 h-20 rounded-full bg-gradient-to-br from-[#5b8bff] to-[#3b63e0] flex items-center justify-center text-3xl font-extrabold text-white shadow-xl shadow-[#4b82f7]/50 z-10">
|
|
<i class="fa-solid fa-phone"></i>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="text-xs uppercase tracking-wider text-[#21c274] font-extrabold mb-1">
|
|
⚡ INCOMING INTERVIEW CALL
|
|
</div>
|
|
|
|
<h3 id="incoming-cand-name" class="font-outfit text-2xl font-extrabold text-white mb-1">
|
|
{{ $interview->candidate_name }}
|
|
</h3>
|
|
|
|
<div id="incoming-starter-info" class="text-xs text-[#4b82f7] mb-4">
|
|
Initiated by Panelist
|
|
</div>
|
|
|
|
<div class="bg-white/5 border border-white/10 rounded-xl p-3 text-xs text-slate-300 mb-6 leading-relaxed">
|
|
Another interviewer has started calling the candidate. Click <strong>Accept Call</strong> to join live, or <strong>Decline</strong> if busy.
|
|
</div>
|
|
|
|
<div class="flex gap-3 justify-center">
|
|
<x-button id="incoming-decline-btn" onclick="declineIncomingCall()" variant="danger" size="md" icon="fa-solid fa-xmark" class="flex-1">
|
|
Decline / Miss
|
|
</x-button>
|
|
<x-button id="incoming-accept-btn" onclick="acceptIncomingCall()" variant="success" size="md" icon="fa-solid fa-phone" class="flex-[1.3] font-extrabold animate-pulse">
|
|
Accept Call
|
|
</x-button>
|
|
</div>
|
|
</div>
|
|
</x-modal>
|
|
|
|
<!-- Page Initialization Script -->
|
|
<script>
|
|
window.currentUserId = {{ Auth::id() }};
|
|
window.currentUserName = "{{ addslashes(Auth::user()->name) }}";
|
|
window.currentUserRole = "{{ Auth::user()->is_admin ? 'admin' : 'interviewer' }}";
|
|
window.csrfToken = "{{ csrf_token() }}";
|
|
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
openReviewModal(
|
|
{{ $interview->id }},
|
|
"{{ addslashes($interview->candidate_name) }}",
|
|
"{{ $interview->submission_unique_id }}",
|
|
{{ request('join_call') == '1' ? 'true' : 'false' }}
|
|
);
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|