sls/resources/views/interview/show.blade.php
kushal.saha 9f25fdd648 refactor: UI Layouts and components
Interview module is refactored to use layouts and re-usable components
along with domain components. Style remains identitical to previous
design.
2026-08-17 07:03:55 +00:00

140 lines
6.6 KiB
PHP

<x-layouts.interview
:title="$interview->candidate_name . ' - Assessment Review'"
data-interview-id="{{ $interview->id }}"
data-submission-id="{{ $interview->submission_unique_id }}"
>
@push('head-scripts')
<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>
@endpush
<!-- Candidate Session Summary Card -->
<x-interview.candidate-header :interview="$interview" />
<!-- Video & Screen Call Panel -->
<x-card>
<x-slot:headerExtra>
<x-interview.call-controls :interview="$interview" />
</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="{{ $interview->candidate_initials }}">
<span id="cand-status-text">Waiting for candidate&hellip;</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&hellip;
</x-video-tile>
<!-- Panelist Self -->
@php
$usrWords = preg_split('/\s+/', trim(Auth::user()->name ?? 'Interviewer'));
$usrInitials = count($usrWords) >= 2 ? strtoupper(substr($usrWords[0],0,1).substr(end($usrWords),0,1)) : strtoupper(substr(trim(Auth::user()->name ?? 'IV'),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 ?? 'Interviewer' }}"
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 (Tabs & Audit Log / Live Chat) -->
<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 Panes -->
<div class="lg:col-span-3">
<x-interview.tabs.code-tab />
<x-interview.tabs.notes-tab />
<x-interview.tabs.drawing-tab />
<x-interview.tabs.recordings-tab />
<x-interview.tabs.screenshots-tab />
</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&hellip;" 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>
<!-- SOS Cheating Alert Modal -->
<x-interview.sos-modal />
@push('scripts')
<script>
document.addEventListener('DOMContentLoaded', function() {
openReviewModal(
{{ $interview->id }},
"{{ addslashes($interview->candidate_name) }}",
"{{ $interview->submission_unique_id }}",
{{ request('join_call') == '1' ? 'true' : 'false' }}
);
});
</script>
@endpush
</x-layouts.interview>