- 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
57 lines
2.2 KiB
PHP
57 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Interview;
|
|
|
|
use App\Mail\CandidateInterviewInvitationMail;
|
|
use App\Mail\InterviewerAssessmentNotificationMail;
|
|
use App\Models\Interview;
|
|
use App\Services\Interview\InterviewCalendarService;
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Mail;
|
|
|
|
class SendInterviewInvitationsAction
|
|
{
|
|
public function __construct(
|
|
protected InterviewCalendarService $calendarService
|
|
) {}
|
|
|
|
/**
|
|
* Generate calendar invitation (.ics) and dispatch queued invitation emails to candidate and panelists.
|
|
*/
|
|
public function execute(Interview $interview): void
|
|
{
|
|
$icsContent = $this->calendarService->generateIcs($interview);
|
|
$icsFilename = $this->calendarService->generateFilename($interview);
|
|
|
|
// 1. Send candidate invitation with RSVP required & 15m alert
|
|
if (! empty($interview->candidate_email)) {
|
|
try {
|
|
Mail::to($interview->candidate_email)
|
|
->queue(new CandidateInterviewInvitationMail($interview, $icsContent, $icsFilename));
|
|
} catch (\Throwable $e) {
|
|
Log::error('Failed to queue interview invitation email for candidate: '.$e->getMessage(), [
|
|
'interview_id' => $interview->id,
|
|
'candidate_email' => $interview->candidate_email,
|
|
]);
|
|
}
|
|
}
|
|
|
|
// 2. Send interviewer assignment notification to all assigned panelists
|
|
$assignedUsers = $interview->assignedUsers();
|
|
foreach ($assignedUsers as $interviewer) {
|
|
if (! empty($interviewer->email)) {
|
|
try {
|
|
Mail::to($interviewer->email)
|
|
->queue(new InterviewerAssessmentNotificationMail($interview, $interviewer, $icsContent, $icsFilename));
|
|
} catch (\Throwable $e) {
|
|
Log::error('Failed to queue interview notification for panelist: '.$e->getMessage(), [
|
|
'interview_id' => $interview->id,
|
|
'interviewer_id' => $interviewer->id,
|
|
'interviewer_email' => $interviewer->email,
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|