sls/app/Actions/Interview/SendInterviewInvitationsAction.php
kushal.saha e4fabef1d3 feat(interview): add icalendar invites, white date pickers, and drawer validation feedback
- 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
2026-08-27 10:16:46 +00:00

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,
]);
}
}
}
}
}