- integrate spatie/icalendar-generator for candidate & panelist .ics invitations (RSVP & 15m alerts)
- add StoreInterviewRequest, ScheduleInterviewDto, and invitation/reminder queued actions
- add migration for job_title, round, description, and reminder_sent_at on interviews table
- style datetime-local picker indicators to pure white on dark input backgrounds
- support button loading spinners with :showLoader="true" and loadingText
- auto-open schedule drawer on validation failure with inline @error alerts and old() bindings
179 lines
9.5 KiB
PHP
179 lines
9.5 KiB
PHP
@props([
|
|
'interviewers' => [],
|
|
])
|
|
|
|
@php
|
|
$errors = $errors ?? new \Illuminate\Support\ViewErrorBag;
|
|
$hasInterviewErrors = $errors->any() && (
|
|
$errors->has('candidate_name') ||
|
|
$errors->has('candidate_email') ||
|
|
$errors->has('candidate_phone') ||
|
|
$errors->has('job_title') ||
|
|
$errors->has('round') ||
|
|
$errors->has('scheduled_at') ||
|
|
$errors->has('valid_hours') ||
|
|
$errors->has('language') ||
|
|
$errors->has('assigned_interviewers') ||
|
|
$errors->has('assigned_interviewers.*') ||
|
|
$errors->has('description')
|
|
);
|
|
@endphp
|
|
|
|
<x-modal id="create-interview-modal" title="Schedule Candidate Assessment" maxWidth="lg" class="{{ $hasInterviewErrors ? 'active' : '' }}">
|
|
<form action="{{ route('interview.store') }}" method="POST">
|
|
@csrf
|
|
|
|
@if($hasInterviewErrors)
|
|
<div class="mb-4 bg-rose-500/10 border border-rose-500/30 rounded-xl p-3.5 text-xs text-rose-300 flex items-start gap-2.5">
|
|
<i class="fa-solid fa-triangle-exclamation text-rose-400 mt-0.5 shrink-0 text-sm"></i>
|
|
<div class="flex-1">
|
|
<strong class="block font-semibold text-rose-200">Please correct the following errors:</strong>
|
|
<ul class="list-disc list-inside mt-1 space-y-0.5 text-[11px] text-rose-300">
|
|
@foreach($errors->all() as $errorMsg)
|
|
<li>{{ $errorMsg }}</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
@endif
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-3.5 mb-3.5">
|
|
<div>
|
|
<x-label required>Candidate Name</x-label>
|
|
<x-input type="text" name="candidate_name" value="{{ old('candidate_name') }}" required placeholder="e.g. Soumyadeep Mondal" />
|
|
@error('candidate_name')
|
|
<p class="text-[11px] text-rose-400 mt-1 font-medium flex items-center gap-1">
|
|
<i class="fa-solid fa-circle-exclamation text-[10px]"></i> {{ $message }}
|
|
</p>
|
|
@enderror
|
|
</div>
|
|
<div>
|
|
<x-label required>Candidate Email</x-label>
|
|
<x-input type="email" name="candidate_email" value="{{ old('candidate_email') }}" required placeholder="candidate@example.com" />
|
|
@error('candidate_email')
|
|
<p class="text-[11px] text-rose-400 mt-1 font-medium flex items-center gap-1">
|
|
<i class="fa-solid fa-circle-exclamation text-[10px]"></i> {{ $message }}
|
|
</p>
|
|
@enderror
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-3.5 mb-3.5">
|
|
<div>
|
|
<x-label required>Position / Job Title</x-label>
|
|
<x-input type="text" name="job_title" value="{{ old('job_title') }}" required placeholder="e.g. AIML Engineer" />
|
|
@error('job_title')
|
|
<p class="text-[11px] text-rose-400 mt-1 font-medium flex items-center gap-1">
|
|
<i class="fa-solid fa-circle-exclamation text-[10px]"></i> {{ $message }}
|
|
</p>
|
|
@enderror
|
|
</div>
|
|
<div>
|
|
<x-label>Assessment Round</x-label>
|
|
<x-input type="text" name="round" value="{{ old('round', 'R1') }}" placeholder="e.g. R1, Technical" />
|
|
@error('round')
|
|
<p class="text-[11px] text-rose-400 mt-1 font-medium flex items-center gap-1">
|
|
<i class="fa-solid fa-circle-exclamation text-[10px]"></i> {{ $message }}
|
|
</p>
|
|
@enderror
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-3 mb-3.5">
|
|
<div>
|
|
<x-label required>Phone Number</x-label>
|
|
<x-input type="text" name="candidate_phone" value="{{ old('candidate_phone') }}" required placeholder="9876543210" />
|
|
@error('candidate_phone')
|
|
<p class="text-[11px] text-rose-400 mt-1 font-medium flex items-center gap-1">
|
|
<i class="fa-solid fa-circle-exclamation text-[10px]"></i> {{ $message }}
|
|
</p>
|
|
@enderror
|
|
</div>
|
|
<div>
|
|
<x-label>Start Time (Timeline)</x-label>
|
|
<x-input type="datetime-local" name="scheduled_at" value="{{ old('scheduled_at', now()->format('Y-m-d\TH:i')) }}" class="bg-slate-900" />
|
|
@error('scheduled_at')
|
|
<p class="text-[11px] text-rose-400 mt-1 font-medium flex items-center gap-1">
|
|
<i class="fa-solid fa-circle-exclamation text-[10px]"></i> {{ $message }}
|
|
</p>
|
|
@enderror
|
|
</div>
|
|
<div>
|
|
<x-label required>Access Duration</x-label>
|
|
<x-select name="valid_hours" required>
|
|
<option value="1" @selected(old('valid_hours') === '1')>1 Hour</option>
|
|
<option value="2" @selected(old('valid_hours', '2') === '2')>2 Hours</option>
|
|
<option value="4" @selected(old('valid_hours') === '4')>4 Hours</option>
|
|
<option value="12" @selected(old('valid_hours') === '12')>12 Hours</option>
|
|
<option value="24" @selected(old('valid_hours') === '24')>24 Hours</option>
|
|
</x-select>
|
|
@error('valid_hours')
|
|
<p class="text-[11px] text-rose-400 mt-1 font-medium flex items-center gap-1">
|
|
<i class="fa-solid fa-circle-exclamation text-[10px]"></i> {{ $message }}
|
|
</p>
|
|
@enderror
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3.5">
|
|
<x-label required>Coding Language</x-label>
|
|
<x-select name="language" required>
|
|
<option value="python" @selected(old('language', 'python') === 'python')>Python 3</option>
|
|
<option value="cpp" @selected(old('language') === 'cpp')>C++ (GCC)</option>
|
|
<option value="c" @selected(old('language') === 'c')>C (GCC)</option>
|
|
<option value="java" @selected(old('language') === 'java')>Java 15</option>
|
|
<option value="php" @selected(old('language') === 'php')>PHP 8.2 / Laravel</option>
|
|
<option value="javascript" @selected(old('language') === 'javascript')>JavaScript (Node.js)</option>
|
|
</x-select>
|
|
@error('language')
|
|
<p class="text-[11px] text-rose-400 mt-1 font-medium flex items-center gap-1">
|
|
<i class="fa-solid fa-circle-exclamation text-[10px]"></i> {{ $message }}
|
|
</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="mb-3.5">
|
|
<x-label>Instructions / Notes (Optional)</x-label>
|
|
<textarea name="description" rows="2" class="w-full bg-slate-900 border @error('description') border-rose-500/80 focus:border-rose-500 @else border-slate-700/60 focus:border-indigo-500 @enderror rounded-xl p-3 text-xs text-white placeholder-slate-500 focus:outline-none transition-colors" placeholder="Special requirements, interview topics, or instructions...">{{ old('description') }}</textarea>
|
|
@error('description')
|
|
<p class="text-[11px] text-rose-400 mt-1 font-medium flex items-center gap-1">
|
|
<i class="fa-solid fa-circle-exclamation text-[10px]"></i> {{ $message }}
|
|
</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="mb-4">
|
|
<div class="flex justify-between items-center mb-1.5">
|
|
<x-label>Assign Internal Interviewers / Panelists</x-label>
|
|
</div>
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2 max-h-[120px] overflow-y-auto bg-black/30 p-2.5 rounded-lg border @error('assigned_interviewers') border-rose-500/80 @else border-slate-700/60 @enderror">
|
|
@foreach($interviewers as $usr)
|
|
<label class="flex items-center gap-2 text-xs text-white cursor-pointer hover:text-indigo-300 transition-colors">
|
|
<input type="checkbox" name="assigned_interviewers[]" value="{{ $usr->id }}" @checked(in_array($usr->id, (array) old('assigned_interviewers', []))) class="accent-indigo-500 rounded">
|
|
{{ $usr->name }} ({{ $usr->email }})
|
|
</label>
|
|
@endforeach
|
|
</div>
|
|
@error('assigned_interviewers')
|
|
<p class="text-[11px] text-rose-400 mt-1 font-medium flex items-center gap-1">
|
|
<i class="fa-solid fa-circle-exclamation text-[10px]"></i> {{ $message }}
|
|
</p>
|
|
@enderror
|
|
@error('assigned_interviewers.*')
|
|
<p class="text-[11px] text-rose-400 mt-1 font-medium flex items-center gap-1">
|
|
<i class="fa-solid fa-circle-exclamation text-[10px]"></i> {{ $message }}
|
|
</p>
|
|
@enderror
|
|
</div>
|
|
|
|
<div class="flex justify-end gap-2.5 mt-5">
|
|
<x-button type="button" onclick="document.getElementById('create-interview-modal').classList.remove('active')" variant="secondary">
|
|
Cancel
|
|
</x-button>
|
|
<x-button type="submit" variant="primary" icon="fa-solid fa-paper-plane" :showLoader="true" loadingText="Scheduling...">
|
|
Schedule & Send Invites
|
|
</x-button>
|
|
</div>
|
|
</form>
|
|
</x-modal>
|