sls/app/DTOs/Interview/ScheduleInterviewDto.php
kushal.saha 1541c8193e feat(interview): add candidate resume upload, lightbox viewer, and panelist email attachments
- Add resume file upload to schedule drawer with instant preview and validation
- Create resume lightbox modal viewer with background scroll lock and CV SVG icon
- Integrate CV tab into inspector panel with enlarge action and state 
- Attach candidate resume to panelist notification emails when 
- Fix Outlook RFC 5546 iTIP element mismatch and add table credentials copy button
2026-08-27 11:37:01 +00:00

93 lines
3.6 KiB
PHP

<?php
namespace App\DTOs\Interview;
use App\Http\Requests\Interview\StoreInterviewRequest;
use Carbon\Carbon;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Http\UploadedFile;
use JsonSerializable;
class ScheduleInterviewDto implements Arrayable, JsonSerializable
{
/**
* @param array<int> $assignedInterviewers
*/
public function __construct(
public readonly string $candidateName,
public readonly string $candidateEmail,
public readonly string $candidatePhone,
public readonly string $jobTitle,
public readonly string $round,
public readonly ?Carbon $scheduledAt,
public readonly int $validHours,
public readonly string $language,
public readonly array $assignedInterviewers = [],
public readonly ?string $description = null,
public readonly ?UploadedFile $resume = null,
public readonly ?string $resumePath = null,
) {}
public static function fromRequest(StoreInterviewRequest $request): self
{
$scheduledAt = $request->filled('scheduled_at')
? Carbon::parse($request->input('scheduled_at'))
: now();
return new self(
candidateName: trim($request->input('candidate_name')),
candidateEmail: strtolower(trim($request->input('candidate_email'))),
candidatePhone: trim($request->input('candidate_phone')),
jobTitle: trim($request->input('job_title', 'Software Engineer')),
round: trim($request->input('round', 'R1')) ?: 'R1',
scheduledAt: $scheduledAt,
validHours: (int) $request->input('valid_hours', 2),
language: $request->input('language', 'python'),
assignedInterviewers: array_map('intval', (array) $request->input('assigned_interviewers', [])),
description: $request->filled('description') ? trim($request->input('description')) : null,
resume: $request->file('resume'),
);
}
public static function fromArray(array $data): self
{
$scheduledAt = isset($data['scheduled_at'])
? ($data['scheduled_at'] instanceof Carbon ? $data['scheduled_at'] : Carbon::parse($data['scheduled_at']))
: now();
return new self(
candidateName: trim($data['candidate_name'] ?? ''),
candidateEmail: strtolower(trim($data['candidate_email'] ?? '')),
candidatePhone: trim($data['candidate_phone'] ?? ''),
jobTitle: trim($data['job_title'] ?? 'Software Engineer'),
round: trim($data['round'] ?? 'R1') ?: 'R1',
scheduledAt: $scheduledAt,
validHours: (int) ($data['valid_hours'] ?? 2),
language: $data['language'] ?? 'python',
assignedInterviewers: array_map('intval', (array) ($data['assigned_interviewers'] ?? [])),
description: isset($data['description']) && filled($data['description']) ? trim($data['description']) : null,
);
}
public function toArray(): array
{
return [
'candidate_name' => $this->candidateName,
'candidate_email' => $this->candidateEmail,
'candidate_phone' => $this->candidatePhone,
'job_title' => $this->jobTitle,
'round' => $this->round,
'scheduled_at' => $this->scheduledAt?->toDateTimeString(),
'valid_hours' => $this->validHours,
'language' => $this->language,
'assigned_interviewers' => $this->assignedInterviewers,
'description' => $this->description,
];
}
public function jsonSerialize(): array
{
return $this->toArray();
}
}