feat: UI Refactor, multi-people recording and noise cancellation #21

Merged
subhajit.pal merged 9 commits from feature/noise-cancellation into main 2026-08-21 11:33:03 +00:00
3 changed files with 78 additions and 74 deletions
Showing only changes of commit b787f04914 - Show all commits

View File

@ -303,7 +303,7 @@ public function updateOnboardingToggle(Request $request)
\App\Models\Setting::set('onboarding_enabled', $enabled); \App\Models\Setting::set('onboarding_enabled', $enabled);
$msg = $enabled === '1' ? 'Onboarding & Offboarding module enabled.' : 'Onboarding & Offboarding module disabled.'; $msg = $enabled === '1' ? 'Onboarding & Offboarding module enabled.' : 'Onboarding & Offboarding module disabled.';
return redirect()->route('admin.dashboard')->with('success', $msg); return redirect()->back(fallback: route('admin.dashboard'))->with('success', $msg);
} }
/** /**
@ -315,7 +315,7 @@ public function updateScreenshotToggle(Request $request)
\App\Models\Setting::set('enable_candidate_screenshots', $enabled); \App\Models\Setting::set('enable_candidate_screenshots', $enabled);
$msg = $enabled === '1' ? 'Candidate System Screenshot Capture ENABLED globally.' : 'Candidate System Screenshot Capture DISABLED globally by Admin.'; $msg = $enabled === '1' ? 'Candidate System Screenshot Capture ENABLED globally.' : 'Candidate System Screenshot Capture DISABLED globally by Admin.';
return redirect()->route('admin.dashboard')->with('success', $msg); return redirect()->back(fallback: route('admin.dashboard'))->with('success', $msg);
} }
/** /**

View File

@ -1,71 +1,75 @@
<section class="mb-6 p-5 bg-gradient-to-r from-slate-900/95 to-slate-800/95 border border-indigo-500/35 rounded-2xl shadow-xl"> @php
<div class="flex justify-between items-center pb-3 mb-4 border-b border-white/10"> $screenshotActive = \App\Models\Setting::get('enable_candidate_screenshots', '1') === '1';
<div> $onboardingActive = \App\Models\Setting::get('onboarding_enabled', '1') === '1';
<h3 class="font-outfit text-xl font-bold text-white m-0 flex items-center gap-2"> $isAdmin = Auth::check() && Auth::user()->isAdmin();
<i class="fa-solid fa-gear text-indigo-400"></i> Global Admin Proctoring & System Settings @endphp
</h3>
<div class="text-xs text-slate-400 mt-1">Master control panel for candidate assessment rules, system screen capturing, and module toggles</div>
</div>
<x-pill variant="primary" size="md" icon="fa-solid fa-shield-halved">
ADMIN CONTROL PANEL
</x-pill>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> <div class="mb-6 grid grid-cols-1 md:grid-cols-2 gap-3.5">
<!-- 1. Candidate System Screenshot Capture Master Toggle --> <!-- 1. Candidate System Screenshot Capture Option Card -->
<div class="p-4 bg-emerald-500/10 border border-emerald-500/30 rounded-xl"> <div class="bg-[#0e1422] border border-[#1b2233] rounded-xl p-4 flex flex-col justify-between hover:border-slate-700/60 transition-colors">
<form action="{{ route('admin.settings.screenshot-toggle') }}" method="POST"> <div class="flex items-start gap-3">
@csrf <div class="w-8 h-8 rounded-lg bg-emerald-500/10 border border-emerald-500/25 flex items-center justify-center text-emerald-400 shrink-0 mt-0.5">
<div class="mb-3"> <i class="fa-solid fa-camera text-sm"></i>
<div class="text-sm text-white font-bold flex items-center gap-2"> </div>
<i class="fa-solid fa-camera text-emerald-400"></i> Candidate System Screenshot Capture <div class="flex-1 min-w-0">
</div> <div class="flex items-center gap-2 flex-wrap mb-1">
<div class="text-xs text-slate-400 mt-1 leading-relaxed"> <h4 class="text-xs font-bold text-white m-0">Screenshot Capture</h4>
Captures candidate system desktop screen automatically on call start & tab switches. Admin can stop taking screenshots anytime across all candidates. @if($screenshotActive)
</div> <x-pill variant="success" size="sm" icon="fa-solid fa-circle-check">Active</x-pill>
</div> @else
<div class="flex justify-between items-center pt-2.5 border-t border-white/10"> <x-pill variant="danger" size="sm" icon="fa-solid fa-circle-xmark">Stopped</x-pill>
<span id="global-screenshot-status-text" class="text-xs font-bold {{ \App\Models\Setting::get('enable_candidate_screenshots', '1') === '1' ? 'text-emerald-400' : 'text-red-400' }}">
{{ \App\Models\Setting::get('enable_candidate_screenshots', '1') === '1' ? '🟢 ENABLED (Active)' : '🔴 STOPPED / DISABLED' }}
</span>
@if(Auth::check() && Auth::user()->isAdmin())
<label class="inline-flex items-center gap-2 cursor-pointer">
<input type="checkbox" name="enable_candidate_screenshots" value="1" onchange="this.form.submit()" {{ \App\Models\Setting::get('enable_candidate_screenshots', '1') === '1' ? 'checked' : '' }} class="accent-emerald-500 w-5 h-5 cursor-pointer">
<span class="text-xs font-bold text-white bg-white/10 px-3 py-1 rounded-md hover:bg-white/20 transition-colors">
{{ \App\Models\Setting::get('enable_candidate_screenshots', '1') === '1' ? 'Stop Screenshot Capture' : 'Enable Screenshot Capture' }}
</span>
</label>
@endif @endif
</div> </div>
</form> <p class="text-[11.5px] text-slate-400 m-0 leading-relaxed">
</div> Captures candidate's desktop automatically on call start & tab switches.
</p>
</div>
<!-- 2. Onboarding & Offboarding Module Master Toggle --> @if($isAdmin)
<div class="p-4 bg-indigo-500/10 border border-indigo-500/30 rounded-xl"> <div class="flex items-center justify-end pt-2 border-t border-white/5">
<form action="{{ route('admin.settings.onboarding-toggle') }}" method="POST"> <form action="{{ route('admin.settings.screenshot-toggle') }}" method="POST" class="flex items-center gap-2">
@csrf @csrf
<div class="mb-3"> <label class="relative inline-flex items-center cursor-pointer" title="{{ $screenshotActive ? 'Turn off screenshots' : 'Turn on screenshots' }}">
<div class="text-sm text-white font-bold flex items-center gap-2"> <input type="checkbox" name="enable_candidate_screenshots" value="1" onchange="this.form.submit()" {{ $screenshotActive ? 'checked' : '' }} class="sr-only peer">
<i class="fa-solid fa-rocket text-indigo-400"></i> Candidate Provisioning & Onboarding Module <div class="w-8 h-4.5 bg-slate-800 border border-slate-700 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-slate-300 after:border after:rounded-full after:h-3.5 after:w-3.5 after:transition-all peer-checked:bg-indigo-600 peer-checked:border-indigo-500"></div>
</div> </label>
<div class="text-xs text-slate-400 mt-1 leading-relaxed"> </form>
Master toggle to enable/disable automated candidate provisioning, onboarding checklists, and 1-click revocation. </div>
</div> @endif
</div>
<div class="flex justify-between items-center pt-2.5 border-t border-white/10">
<span class="text-xs font-bold {{ \App\Models\Setting::get('onboarding_enabled', '1') === '1' ? 'text-emerald-400' : 'text-red-400' }}">
{{ \App\Models\Setting::get('onboarding_enabled', '1') === '1' ? '🟢 ENABLED' : '🔴 DISABLED' }}
</span>
@if(Auth::check() && Auth::user()->isAdmin())
<label class="inline-flex items-center gap-2 cursor-pointer">
<input type="checkbox" name="onboarding_enabled" value="1" onchange="this.form.submit()" {{ \App\Models\Setting::get('onboarding_enabled', '1') === '1' ? 'checked' : '' }} class="accent-emerald-500 w-5 h-5 cursor-pointer">
<span class="text-xs font-bold text-white bg-white/10 px-3 py-1 rounded-md hover:bg-white/20 transition-colors">
{{ \App\Models\Setting::get('onboarding_enabled', '1') === '1' ? 'Disable Onboarding' : 'Enable Onboarding' }}
</span>
</label>
@endif
</div>
</form>
</div> </div>
</div> </div>
</section>
<!-- 2. Candidate Onboarding Option Card -->
<div class="bg-[#0e1422] border border-[#1b2233] rounded-xl p-3.5 flex flex-col justify-between gap-3 hover:border-slate-700/60 transition-colors">
<div class="flex items-start gap-3">
<div class="w-8 h-8 rounded-lg bg-indigo-500/10 border border-indigo-500/25 flex items-center justify-center text-indigo-400 shrink-0 mt-0.5">
<i class="fa-solid fa-user-check text-sm"></i>
</div>
<div class="flex-1 min-w-0">
<div class="flex items-center gap-2 flex-wrap mb-1">
<h4 class="text-xs font-bold text-white m-0">Candidate Onboarding</h4>
@if($onboardingActive)
<x-pill variant="success" size="sm" icon="fa-solid fa-circle-check">Active</x-pill>
@else
<x-pill variant="danger" size="sm" icon="fa-solid fa-circle-xmark">Disabled</x-pill>
@endif
</div>
<p class="text-[11.5px] text-slate-400 m-0 leading-relaxed">
Automatic provisioning checklist and one-click revocation.
</p>
</div>
@if($isAdmin)
<div class="flex items-center justify-end pt-2 border-t border-white/5">
<form action="{{ route('admin.settings.onboarding-toggle') }}" method="POST" class="flex items-center gap-2">
@csrf
<label class="relative inline-flex items-center cursor-pointer" title="{{ $onboardingActive ? 'Turn off onboarding' : 'Turn on onboarding' }}">
<input type="checkbox" name="onboarding_enabled" value="1" onchange="this.form.submit()" {{ $onboardingActive ? 'checked' : '' }} class="sr-only peer">
<div class="w-8 h-4.5 bg-slate-800 border border-slate-700 peer-focus:outline-none rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-slate-300 after:border after:rounded-full after:h-3.5 after:w-3.5 after:transition-all peer-checked:bg-indigo-600 peer-checked:border-indigo-500"></div>
</label>
</form>
</div>
@endif
</div>
</div>
</div>

View File

@ -15,17 +15,17 @@
</div> </div>
<!-- Assessment Table Card --> <!-- Assessment Table Card -->
<x-card class="p-6"> <x-card class="pt-4">
<div class="overflow-x-auto w-full"> <div class="overflow-x-auto w-full">
<table class="w-full text-left text-xs border-collapse"> <table class="w-full text-left text-xs border-collapse">
<thead> <thead>
<tr class="border-b border-slate-700/60 text-slate-400 uppercase text-[0.7rem] tracking-wider"> <tr class="border-b border-slate-700/60 text-slate-400 uppercase text-[0.7rem] tracking-wider">
<th class="py-3 px-4">Candidate & Temp Pass</th> <th class="pb-4 px-4">Candidate & Temp Pass</th>
<th class="py-3 px-4">Unique Submission ID</th> <th class="pb-4 px-4">Unique Submission ID</th>
<th class="py-3 px-4">Status & Validity</th> <th class="pb-4 px-4">Status & Validity</th>
<th class="py-3 px-4">Language</th> <th class="pb-4 px-4">Language</th>
<th class="py-3 px-4">Proctoring Alerts</th> <th class="pb-4 px-4">Proctoring Alerts</th>
<th class="py-3 px-4 text-right">Review & Actions</th> <th class="pb-4 px-4 text-right">Review & Actions</th>
</tr> </tr>
</thead> </thead>
<tbody class="divide-y divide-white/5"> <tbody class="divide-y divide-white/5">