diff --git a/app/Models/Interview.php b/app/Models/Interview.php index 2c158c3..a81f96b 100644 --- a/app/Models/Interview.php +++ b/app/Models/Interview.php @@ -101,4 +101,44 @@ public function isAssignedInterviewer($userId): bool $interviewers = array_map('strval', (array) $this->assigned_interviewers); return in_array((string) $userId, $interviewers, true); } + + /** + * Get computed initials for candidate (e.g. "John Doe" -> "JD"). + */ + public function getCandidateInitialsAttribute(): string + { + $parts = preg_split('/\s+/', trim($this->candidate_name ?? '')); + if (count($parts) >= 2) { + return strtoupper(substr($parts[0], 0, 1) . substr(end($parts), 0, 1)); + } + $nameStr = trim($this->candidate_name ?? ''); + return strtoupper(substr($nameStr, 0, 1) . (strlen($nameStr) > 1 ? substr($nameStr, -1) : '')); + } + + /** + * Get proctoring alert metrics summary. + */ + public function getProctorMetricsAttribute(): array + { + $logs = $this->proctor_logs ?? []; + return [ + 'tab_switches' => count(array_filter($logs, fn($l) => ($l['type'] ?? '') === 'tab_switch')), + 'focus_lost' => count(array_filter($logs, fn($l) => ($l['type'] ?? '') === 'focus_lost')), + 'gaze_alerts' => count(array_filter($logs, fn($l) => in_array($l['type'] ?? '', ['gaze_anomaly', 'gaze_fixed_staring', 'looking_away']))), + 'lower_gaze' => count(array_filter($logs, fn($l) => ($l['type'] ?? '') === 'gaze_lower_device')), + 'question_repeat' => count(array_filter($logs, fn($l) => in_array($l['type'] ?? '', ['question_repeat_lower', 'question_repetition']))), + 'external_ai' => count(array_filter($logs, fn($l) => ($l['type'] ?? '') === 'external_ai_detected')), + 'paste_events' => count(array_filter($logs, fn($l) => ($l['type'] ?? '') === 'paste_event')), + 'total_incidents' => count($logs), + ]; + } + + /** + * Format timeline string: "M d, H:i – H:i". + */ + public function getFormattedTimelineAttribute(): string + { + $start = $this->scheduled_at ?? $this->created_at; + return $start->format('M d, H:i') . ' – ' . $this->expires_at->format('H:i'); + } } diff --git a/resources/views/components/alert.blade.php b/resources/views/components/alert.blade.php new file mode 100644 index 0000000..8e13cf5 --- /dev/null +++ b/resources/views/components/alert.blade.php @@ -0,0 +1,32 @@ +@props([ + 'variant' => 'info', // success, danger, warning, info + 'icon' => null, +]) + +@php + $variants = [ + 'success' => 'bg-emerald-500/15 border-emerald-500/30 text-emerald-300', + 'danger' => 'bg-red-500/15 border-red-500/30 text-red-300', + 'warning' => 'bg-amber-500/15 border-amber-500/30 text-amber-300', + 'info' => 'bg-sky-500/15 border-sky-500/30 text-sky-300', + ]; + + $defaultIcons = [ + 'success' => 'fa-solid fa-circle-check', + 'danger' => 'fa-solid fa-triangle-exclamation', + 'warning' => 'fa-solid fa-circle-exclamation', + 'info' => 'fa-solid fa-circle-info', + ]; + + $selectedIcon = $icon ?? ($defaultIcons[$variant] ?? $defaultIcons['info']); + $variantClass = $variants[$variant] ?? $variants['info']; +@endphp + +
merge(['class' => "flex items-start gap-2.5 px-4 py-3 border rounded-xl text-xs font-medium {$variantClass}"]) }}> + @if($selectedIcon) + + @endif +
+ {{ $slot }} +
+
diff --git a/resources/views/components/input.blade.php b/resources/views/components/input.blade.php new file mode 100644 index 0000000..0a18193 --- /dev/null +++ b/resources/views/components/input.blade.php @@ -0,0 +1,29 @@ +@props([ + 'type' => 'text', + 'name' => null, + 'value' => null, + 'placeholder' => null, + 'required' => false, + 'disabled' => false, + 'size' => 'md', // sm, md, lg +]) + +@php + $sizeClasses = [ + 'sm' => 'px-2.5 py-1.5 text-xs', + 'md' => 'px-3 py-2 text-xs', + 'lg' => 'px-3.5 py-2.5 text-sm', + ]; + + $classes = 'w-full bg-white/5 border border-slate-700/60 rounded-lg text-white outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500/40 placeholder-slate-500 transition-colors disabled:opacity-50 disabled:cursor-not-allowed ' . ($sizeClasses[$size] ?? $sizeClasses['md']); +@endphp + +merge(['class' => $classes]) }} +/> diff --git a/resources/views/components/interview/admin-settings-card.blade.php b/resources/views/components/interview/admin-settings-card.blade.php new file mode 100644 index 0000000..a4eb9fd --- /dev/null +++ b/resources/views/components/interview/admin-settings-card.blade.php @@ -0,0 +1,71 @@ +
+
+
+

+ Global Admin Proctoring & System Settings +

+
Master control panel for candidate assessment rules, system screen capturing, and module toggles
+
+ + ADMIN CONTROL PANEL + +
+ +
+ +
+
+ @csrf +
+
+ Candidate System Screenshot Capture +
+
+ Captures candidate system desktop screen automatically on call start & tab switches. Admin can stop taking screenshots anytime across all candidates. +
+
+
+ + {{ \App\Models\Setting::get('enable_candidate_screenshots', '1') === '1' ? '🟢 ENABLED (Active)' : '🔴 STOPPED / DISABLED' }} + + @if(Auth::check() && Auth::user()->isAdmin()) + + @endif +
+
+
+ + +
+
+ @csrf +
+
+ Candidate Provisioning & Onboarding Module +
+
+ Master toggle to enable/disable automated candidate provisioning, onboarding checklists, and 1-click revocation. +
+
+
+ + {{ \App\Models\Setting::get('onboarding_enabled', '1') === '1' ? '🟢 ENABLED' : '🔴 DISABLED' }} + + @if(Auth::check() && Auth::user()->isAdmin()) + + @endif +
+
+
+
+
diff --git a/resources/views/components/interview/call-controls.blade.php b/resources/views/components/interview/call-controls.blade.php new file mode 100644 index 0000000..c331795 --- /dev/null +++ b/resources/views/components/interview/call-controls.blade.php @@ -0,0 +1,40 @@ +@props([ + 'interview', +]) + +
+ + + + + + + + @if($interview->call_status === 'ended') + + Call Ended + + @elseif($interview->call_status === 'active') + + Join Call + + @else + + Start Call + + @endif + + + + + + + + + + +
diff --git a/resources/views/components/interview/candidate-header.blade.php b/resources/views/components/interview/candidate-header.blade.php new file mode 100644 index 0000000..f1086d1 --- /dev/null +++ b/resources/views/components/interview/candidate-header.blade.php @@ -0,0 +1,75 @@ +@props([ + 'interview', +]) + +
+
+
+
+ {{ $interview->candidate_initials }} +
+
+
+ + + Not Joined + +
+
{{ $interview->candidate_email }} · {{ $interview->candidate_phone }}
+
+
+ +
+ @if($interview->isExpired()) + Expired + @elseif($interview->status === 'completed') + Completed + @elseif($interview->call_status === 'active') + Call in progress + @elseif($interview->isActiveTimeline()) + Timeline live + @else + Scheduled + @endif + +
+ +
+ + SOS auto-trigger +
+ +
+ + Password + PDF report + Block +
+
+ + +
+ + + Show submission details + +
+
+
Submission ID
+ +
+
+
Temp Pass
+
{{ $interview->temp_password }}
+
+
+
Language
+
{{ $interview->language }}
+
+
+
Timeline
+
{{ $interview->formatted_timeline }}
+
+
+
+
diff --git a/resources/views/components/interview/candidate/drawing-modal.blade.php b/resources/views/components/interview/candidate/drawing-modal.blade.php new file mode 100644 index 0000000..00620d0 --- /dev/null +++ b/resources/views/components/interview/candidate/drawing-modal.blade.php @@ -0,0 +1,19 @@ + diff --git a/resources/views/components/interview/candidate/ide-header.blade.php b/resources/views/components/interview/candidate/ide-header.blade.php new file mode 100644 index 0000000..acbfdc0 --- /dev/null +++ b/resources/views/components/interview/candidate/ide-header.blade.php @@ -0,0 +1,48 @@ +@props([ + 'interview', +]) + +
+
+
+ Candidate Assessment Room +
+ + ID: {{ $interview->submission_unique_id }} + +
+ +
+ + + + +
+ + +
+ + + + + + +
+
diff --git a/resources/views/components/interview/candidate/incoming-overlay.blade.php b/resources/views/components/interview/candidate/incoming-overlay.blade.php new file mode 100644 index 0000000..08adc90 --- /dev/null +++ b/resources/views/components/interview/candidate/incoming-overlay.blade.php @@ -0,0 +1,32 @@ +
+
+
+
+
+
+ +
+
+ +
+ ⚡ INCOMING INTERVIEW CALL +
+ +

+ Interviewer Panel Calling... +

+ +
+ The interviewer panel has initiated a live 2-way call. +
+ +
+ + +
+
+
diff --git a/resources/views/components/interview/candidate/notepad-modal.blade.php b/resources/views/components/interview/candidate/notepad-modal.blade.php new file mode 100644 index 0000000..446acf9 --- /dev/null +++ b/resources/views/components/interview/candidate/notepad-modal.blade.php @@ -0,0 +1,17 @@ +@props([ + 'notes' => '', +]) + + diff --git a/resources/views/components/interview/candidate/proctor-sidebar.blade.php b/resources/views/components/interview/candidate/proctor-sidebar.blade.php new file mode 100644 index 0000000..96c515a --- /dev/null +++ b/resources/views/components/interview/candidate/proctor-sidebar.blade.php @@ -0,0 +1,94 @@ +@props([ + 'interview', +]) + + diff --git a/resources/views/components/interview/candidate/terminal.blade.php b/resources/views/components/interview/candidate/terminal.blade.php new file mode 100644 index 0000000..b2fd9c8 --- /dev/null +++ b/resources/views/components/interview/candidate/terminal.blade.php @@ -0,0 +1,7 @@ +
+
+ EXECUTION OUTPUT TERMINAL (STDOUT / STDERR) + Ready +
+
// Press 'Run Code' to execute candidate solution live...
+
diff --git a/resources/views/components/interview/incoming-call-modal.blade.php b/resources/views/components/interview/incoming-call-modal.blade.php new file mode 100644 index 0000000..29a813d --- /dev/null +++ b/resources/views/components/interview/incoming-call-modal.blade.php @@ -0,0 +1,36 @@ + +
+
+
+
+
+ +
+
+ +
+ ⚡ Incoming Assessment Call +
+ +

+ Candidate Name +

+ +
+ Initiated by Panelist +
+ +
+ Another interviewer has started calling the candidate. Click Accept Call to join live, or Decline if busy. +
+ +
+ + Decline / Miss + + + Accept Call + +
+
+
diff --git a/resources/views/components/interview/navbar.blade.php b/resources/views/components/interview/navbar.blade.php new file mode 100644 index 0000000..cc5afc4 --- /dev/null +++ b/resources/views/components/interview/navbar.blade.php @@ -0,0 +1,35 @@ +@props([ + 'activeNav' => 'interview', +]) + +
+
+ + + +
+

Candidate Live Assessment Portal

+
Proctored IDE & Code Submissions
+
+
+ +
+ @if(Auth::check() && Auth::user()->isAdmin()) + + Control Panel + + @endif + + Onboarding Hub + + + User Portal + +
+ @csrf + + Logout + +
+
+
diff --git a/resources/views/components/interview/proctor-badges.blade.php b/resources/views/components/interview/proctor-badges.blade.php new file mode 100644 index 0000000..979fccf --- /dev/null +++ b/resources/views/components/interview/proctor-badges.blade.php @@ -0,0 +1,39 @@ +@props([ + 'metrics' => [], +]) + +@php + $tabSwitches = $metrics['tab_switches'] ?? 0; + $focusLost = $metrics['focus_lost'] ?? 0; + $gazeAlerts = $metrics['gaze_alerts'] ?? 0; + $lowerGaze = $metrics['lower_gaze'] ?? 0; + $questionRepeat = $metrics['question_repeat'] ?? 0; + $externalAi = $metrics['external_ai'] ?? 0; +@endphp + +
merge(['class' => 'flex flex-col gap-0.5 text-xs']) }}> + + Tab Switches: {{ $tabSwitches }} + + + Focus Loss / Overlay: {{ $focusLost }} + + + Eye Gaze Anomaly: {{ $gazeAlerts }} + + @if($lowerGaze > 0) + + Lower Gaze (>10s): {{ $lowerGaze }} + + @endif + @if($questionRepeat > 0) + + Question Repetition: {{ $questionRepeat }} + + @endif + @if($externalAi > 0) + + Parakeet / External AI: {{ $externalAi }} + + @endif +
diff --git a/resources/views/components/interview/report/artifacts-section.blade.php b/resources/views/components/interview/report/artifacts-section.blade.php new file mode 100644 index 0000000..c73a1d7 --- /dev/null +++ b/resources/views/components/interview/report/artifacts-section.blade.php @@ -0,0 +1,55 @@ +@props([ + 'interview', +]) + +@if(!empty($interview->candidate_notes) || !empty($interview->interviewer_notes) || !empty($interview->candidate_drawing) || (is_array($interview->formatted_recordings) && count($interview->formatted_recordings) > 0)) +
+ 📝 Workspace Artifacts, Evaluation Notes & Call Session Recordings +
+
+ @if(!empty($interview->candidate_notes)) +
+ CANDIDATE NOTEPAD NOTES (UNIQUE ID SYNCED): +
+
{{ $interview->candidate_notes }}
+ @endif + + @if(!empty($interview->interviewer_notes)) +
+ INTERVIEWER EVALUATION NOTES (STORED BY UNIQUE ID): +
+
{{ $interview->interviewer_notes }}
+ @endif + + @if(!empty($interview->candidate_drawing)) +
+ CANDIDATE DRAWING DIAGRAM: +
+ Candidate Drawing + @endif + + @if(is_array($interview->formatted_recordings) && count($interview->formatted_recordings) > 0) +
+ 📹 STORED CALL SESSION RECORDINGS ({{ count($interview->formatted_recordings) }} RECORDINGS): + 📜 Scroll to view all +
+
+ @foreach($interview->formatted_recordings as $displayIdx => $rec) +
+
+ Recording #{{ count($interview->formatted_recordings) - $displayIdx }} ({{ $rec['created_at'] }}) + + 📥 Download MP4 Video + +
+ +
+ @endforeach +
+ @endif +
+@endif diff --git a/resources/views/components/interview/report/audit-table.blade.php b/resources/views/components/interview/report/audit-table.blade.php new file mode 100644 index 0000000..0e48f26 --- /dev/null +++ b/resources/views/components/interview/report/audit-table.blade.php @@ -0,0 +1,37 @@ +@props([ + 'logs' => [], +]) + +@if(is_array($logs) && count($logs) > 0) +
+ + + + + + + + + + @foreach($logs as $log) + + + + + + @endforeach + +
TimestampViolation CategoryAudit Details
+ {{ isset($log['timestamp']) ? \Carbon\Carbon::parse($log['timestamp'])->format('H:i:s T') : '--:--:--' }} + + {{ str_replace('_', ' ', $log['type'] ?? 'Violation') }} + + {{ $log['details'] ?? 'Incident flagged by proctoring engine.' }} +
+
+@else +
+ + Zero proctoring violations or malpractice detected during the session. +
+@endif diff --git a/resources/views/components/interview/report/code-section.blade.php b/resources/views/components/interview/report/code-section.blade.php new file mode 100644 index 0000000..8cb4397 --- /dev/null +++ b/resources/views/components/interview/report/code-section.blade.php @@ -0,0 +1,21 @@ +@props([ + 'code' => null, + 'output' => null, + 'language' => 'code', +]) + + +
+ 💻 Submitted Code Solution ({{ strtoupper($language) }}) +
+
+{{ $code ?? '// No code solution submitted by candidate.' }} +
+ + +
+ 🖥️ Engine Execution Stdout Output +
+
+{{ $output ?? 'No execution output recorded.' }} +
diff --git a/resources/views/components/interview/report/header.blade.php b/resources/views/components/interview/report/header.blade.php new file mode 100644 index 0000000..29ed349 --- /dev/null +++ b/resources/views/components/interview/report/header.blade.php @@ -0,0 +1,39 @@ +@props([ + 'interview', +]) + + +
+
+ + Executive Assessment Performance Report +
+ +
+ + +
+
+
+ SingleLogin Enterprise Assessment +
+
+ Candidate Technical Competency & Behavioral Audit Report +
+
+ +
+ + Executive Summary + +
+ Report ID: RPT-{{ $interview->submission_unique_id }} +
+
+ Date: {{ now()->format('M d, Y - H:i:s T') }} +
+
+
diff --git a/resources/views/components/interview/report/incident-grid.blade.php b/resources/views/components/interview/report/incident-grid.blade.php new file mode 100644 index 0000000..23403f3 --- /dev/null +++ b/resources/views/components/interview/report/incident-grid.blade.php @@ -0,0 +1,43 @@ +@props([ + 'metrics' => [], +]) + +@php + $tabSwitches = $metrics['tab_switches'] ?? 0; + $focusLosses = $metrics['focus_lost'] ?? 0; + $gazeAnomalies = $metrics['gaze_alerts'] ?? 0; + $pasteEvents = $metrics['paste_events'] ?? 0; + $lowerGaze = $metrics['lower_gaze'] ?? 0; + $questionRepeat = $metrics['question_repeat'] ?? 0; +@endphp + +
+ 🔍 Behavioral Audit & Proctoring Incident Breakdown +
+ +
+
+
{{ $tabSwitches }}
+
Tab Switches
+
+
+
{{ $focusLosses }}
+
Focus Lost
+
+
+
{{ $gazeAnomalies }}
+
Gaze Anomalies
+
+
+
{{ $pasteEvents }}
+
Code Pastes
+
+
+
{{ $lowerGaze }}
+
📱 Lower Gaze
+
+
+
{{ $questionRepeat }}
+
🗣️ Question Repeat
+
+
diff --git a/resources/views/components/interview/report/meta-grid.blade.php b/resources/views/components/interview/report/meta-grid.blade.php new file mode 100644 index 0000000..ca125b3 --- /dev/null +++ b/resources/views/components/interview/report/meta-grid.blade.php @@ -0,0 +1,32 @@ +@props([ + 'interview', +]) + +@php + $statusColor = match($interview->status) { + 'completed' => 'text-emerald-600', + 'blocked' => 'text-red-600', + default => 'text-indigo-600', + }; +@endphp + +
+
+ + {{ $interview->candidate_name }} +
+
+ + {{ $interview->candidate_email }} +
+
+ + {{ $interview->language }} +
+
+ + + {{ $interview->status }} + +
+
diff --git a/resources/views/components/interview/report/score-card.blade.php b/resources/views/components/interview/report/score-card.blade.php new file mode 100644 index 0000000..31d152f --- /dev/null +++ b/resources/views/components/interview/report/score-card.blade.php @@ -0,0 +1,46 @@ +@props([ + 'integrityScore' => 100, + 'integrityLabel' => 'Optimal Candidate Trust', + 'integrityColor' => '#10b981', + 'incidentCount' => 0, + 'codeScore' => 0, + 'hasSubmittedCode' => false, +]) + +@php + $codeLabel = $codeScore >= 80 ? 'Strong Technical Match' : ($codeScore >= 50 ? 'Moderate Competency' : 'Needs Further Review'); +@endphp + +
+ +
+
+ 🛡️ Behavioral Integrity Rating +
+
+ {{ $integrityScore }}% +
+
+ {{ $integrityLabel }} +
+
+ Recorded Violations: {{ $incidentCount }} incident(s) +
+
+ + +
+
+ 💻 Technical Code Competency +
+
+ {{ $codeScore }} / 100 +
+
+ {{ $codeLabel }} +
+
+ Solution Code: {{ $hasSubmittedCode ? 'Submitted' : 'Pending' }} +
+
+
diff --git a/resources/views/components/interview/report/signoff.blade.php b/resources/views/components/interview/report/signoff.blade.php new file mode 100644 index 0000000..169092a --- /dev/null +++ b/resources/views/components/interview/report/signoff.blade.php @@ -0,0 +1,23 @@ +@props([ + 'recommended' => true, +]) + +
+
+
+ HR & Lead Panel Approval +
+
+ SingleLogin Enterprise HR Board +
+
+ +
+
+ Final Recommendation +
+
+ {{ $recommended ? 'RECOMMENDED FOR HIRE' : 'REQUIRES FURTHER REVIEW / FLAGGED' }} +
+
+
diff --git a/resources/views/components/interview/schedule-modal.blade.php b/resources/views/components/interview/schedule-modal.blade.php new file mode 100644 index 0000000..8c5af67 --- /dev/null +++ b/resources/views/components/interview/schedule-modal.blade.php @@ -0,0 +1,75 @@ +@props([ + 'interviewers' => [], +]) + + +
+ @csrf +
+
+ Candidate Name + +
+
+ Candidate Email + +
+
+ +
+
+ Phone Number + +
+
+ Start Time (Timeline) + +
+
+ Access Duration + + + + + + + +
+
+ +
+ Coding Language + + + + + + + + +
+ +
+
+ Assign Internal Interviewers / Panelists +
+
+ @foreach($interviewers as $usr) + + @endforeach +
+
+ +
+ + Cancel + + + Create Session & Password + +
+
+
diff --git a/resources/views/components/interview/session-row.blade.php b/resources/views/components/interview/session-row.blade.php new file mode 100644 index 0000000..34936e1 --- /dev/null +++ b/resources/views/components/interview/session-row.blade.php @@ -0,0 +1,89 @@ +@props([ + 'interview', +]) + +@php + $metrics = $interview->proctor_metrics; +@endphp + + + + +
+ {{ $interview->candidate_name }} +
{{ $interview->candidate_email }} • {{ $interview->candidate_phone }}
+
+
+ Temp Pass: {{ $interview->temp_password }} +
+ +
+
+ + + + + + {{ $interview->submission_unique_id }} + + + + + + @if($interview->isExpired()) + EXPIRED + @elseif($interview->status === 'completed') + COMPLETED + @elseif($interview->call_status === 'active') + CALL IN PROGRESS + @elseif($interview->isActiveTimeline()) + TIMELINE LIVE + @else + SCHEDULED + @endif +
+ Timeline: {{ $interview->formatted_timeline }} +
+ + + + + + {{ $interview->language }} + + + + + + + + + + +
+ + + + PDF Report + + + + + @if($interview->call_status === 'active') + + + Join Active Call + + + @else + + + Join Call + + + @endif +
+ + diff --git a/resources/views/components/interview/sos-modal.blade.php b/resources/views/components/interview/sos-modal.blade.php new file mode 100644 index 0000000..9388c32 --- /dev/null +++ b/resources/views/components/interview/sos-modal.blade.php @@ -0,0 +1,13 @@ + +
+ Violation details loading... +
+
+ + Acknowledge Alert + + + Acknowledge & Disable SOS + +
+
diff --git a/resources/views/components/interview/tabs/code-tab.blade.php b/resources/views/components/interview/tabs/code-tab.blade.php new file mode 100644 index 0000000..22a1001 --- /dev/null +++ b/resources/views/components/interview/tabs/code-tab.blade.php @@ -0,0 +1,7 @@ +
+
Current code solution — visible even if candidate does not share screen
+ + +
Execution stdout / stderr
+ +
diff --git a/resources/views/components/interview/tabs/drawing-tab.blade.php b/resources/views/components/interview/tabs/drawing-tab.blade.php new file mode 100644 index 0000000..3955662 --- /dev/null +++ b/resources/views/components/interview/tabs/drawing-tab.blade.php @@ -0,0 +1,7 @@ + diff --git a/resources/views/components/interview/tabs/notes-tab.blade.php b/resources/views/components/interview/tabs/notes-tab.blade.php new file mode 100644 index 0000000..069386c --- /dev/null +++ b/resources/views/components/interview/tabs/notes-tab.blade.php @@ -0,0 +1,4 @@ + diff --git a/resources/views/components/interview/tabs/recordings-tab.blade.php b/resources/views/components/interview/tabs/recordings-tab.blade.php new file mode 100644 index 0000000..a502d68 --- /dev/null +++ b/resources/views/components/interview/tabs/recordings-tab.blade.php @@ -0,0 +1,6 @@ + diff --git a/resources/views/components/interview/tabs/screenshots-tab.blade.php b/resources/views/components/interview/tabs/screenshots-tab.blade.php new file mode 100644 index 0000000..e54f06f --- /dev/null +++ b/resources/views/components/interview/tabs/screenshots-tab.blade.php @@ -0,0 +1,9 @@ + diff --git a/resources/views/components/label.blade.php b/resources/views/components/label.blade.php new file mode 100644 index 0000000..904db63 --- /dev/null +++ b/resources/views/components/label.blade.php @@ -0,0 +1,10 @@ +@props([ + 'required' => false, +]) + + diff --git a/resources/views/components/layouts/candidate.blade.php b/resources/views/components/layouts/candidate.blade.php new file mode 100644 index 0000000..cda65ec --- /dev/null +++ b/resources/views/components/layouts/candidate.blade.php @@ -0,0 +1,37 @@ +@props([ + 'title' => 'Live Assessment Room', +]) + + + + + + + + {{ $title }} | SingleLogin + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + + + + + + + + + + + + + + @stack('styles') + @stack('head-scripts') + +merge(['class' => "bg-[#080c14] text-white h-screen flex flex-col font-['Instrument_Sans',sans-serif] overflow-hidden antialiased select-none"]) }}> + + {{ $slot }} + + @stack('scripts') + + diff --git a/resources/views/components/layouts/guest.blade.php b/resources/views/components/layouts/guest.blade.php new file mode 100644 index 0000000..4210489 --- /dev/null +++ b/resources/views/components/layouts/guest.blade.php @@ -0,0 +1,32 @@ +@props([ + 'title' => 'Candidate Portal', +]) + + + + + + + + {{ $title }} | SingleLogin + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + + + + @stack('styles') + @stack('head-scripts') + +merge(['class' => "bg-[#0b0f19] text-white min-h-screen flex items-center justify-center p-4 relative overflow-hidden font-['Instrument_Sans',sans-serif] antialiased"]) }}> + + +
+ +
+ {{ $slot }} +
+ + @stack('scripts') + + diff --git a/resources/views/components/layouts/interview.blade.php b/resources/views/components/layouts/interview.blade.php new file mode 100644 index 0000000..655d366 --- /dev/null +++ b/resources/views/components/layouts/interview.blade.php @@ -0,0 +1,57 @@ +@props([ + 'title' => 'Candidate Live Assessment Portal', + 'activeNav' => 'interview', +]) + + + + + + + + {{ $title }} | SingleLogin + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + + + + + + @stack('styles') + @stack('head-scripts') + +merge(['class' => "bg-[#0a0e17] text-white min-h-screen flex flex-col font-['Instrument_Sans',sans-serif] antialiased"]) }}> + + + +
+ @if(session('success')) + + {{ session('success') }} + + @endif + + @if(session('error')) + + {{ session('error') }} + + @endif + + {{ $slot }} +
+ + + + + + + @stack('scripts') + + diff --git a/resources/views/components/layouts/report.blade.php b/resources/views/components/layouts/report.blade.php new file mode 100644 index 0000000..3ba7f0f --- /dev/null +++ b/resources/views/components/layouts/report.blade.php @@ -0,0 +1,26 @@ +@props([ + 'title' => 'Executive Evaluation Report', +]) + + + + + + + {{ $title }} | SingleLogin + @vite(['resources/css/app.css', 'resources/js/app.js']) + + + + + + @stack('styles') + @stack('head-scripts') + +merge(['class' => "bg-slate-100 text-slate-900 leading-normal p-5 md:p-10 font-['Instrument_Sans',sans-serif] antialiased print:bg-white print:p-0 print:text-black"]) }}> + + {{ $slot }} + + @stack('scripts') + + diff --git a/resources/views/components/select.blade.php b/resources/views/components/select.blade.php new file mode 100644 index 0000000..5be7854 --- /dev/null +++ b/resources/views/components/select.blade.php @@ -0,0 +1,25 @@ +@props([ + 'name' => null, + 'required' => false, + 'disabled' => false, + 'size' => 'md', +]) + +@php + $sizeClasses = [ + 'sm' => 'px-2.5 py-1.5 text-xs', + 'md' => 'px-3 py-2 text-xs', + 'lg' => 'px-3.5 py-2.5 text-sm', + ]; + + $classes = 'w-full bg-slate-900 border border-slate-700/60 rounded-lg text-white outline-none focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500/40 transition-colors disabled:opacity-50 disabled:cursor-not-allowed ' . ($sizeClasses[$size] ?? $sizeClasses['md']); +@endphp + + diff --git a/resources/views/interview/candidate_login.blade.php b/resources/views/interview/candidate_login.blade.php index a83ae78..d1f947b 100644 --- a/resources/views/interview/candidate_login.blade.php +++ b/resources/views/interview/candidate_login.blade.php @@ -1,103 +1,40 @@ - - - - - - Candidate Assessment Login | SingleLogin - @vite(['resources/css/app.css', 'resources/js/app.js']) - - - - - - -