- Mobile responsive CSS (touch targets 44px, iOS anti-zoom, reduced motion) - Vitest setup s 39 testy (formatters, attendanceHelpers, useTableSort) - Klavesove zkratky (Shift+? napoveda, Ctrl+S ulozit, navigace) - Drag & drop pro polozky nabidek (@dnd-kit, SortableRow, useSortableList) - Univerzalizace: odstraneni BOHA brandingu z UI, emailu, PDF - Smazany nepotrebne soubory (deploy.sh, AUTH_SYSTEM.md, example_design, .htaccess) - CORS konfigurovatelny pres env promennou Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
91 lines
3.7 KiB
PHP
91 lines
3.7 KiB
PHP
<?php
|
||
|
||
/**
|
||
* Leave Request Email Notifications
|
||
*
|
||
* Sends email notifications when leave requests are created.
|
||
*/
|
||
|
||
declare(strict_types=1);
|
||
|
||
class LeaveNotification
|
||
{
|
||
/** @var array<string, string> */
|
||
private static array $leaveTypeLabels = [
|
||
'vacation' => 'Dovolená',
|
||
'sick' => 'Nemocenská',
|
||
'unpaid' => 'Neplacené volno',
|
||
];
|
||
|
||
/**
|
||
* Send notification about a new leave request
|
||
*
|
||
* @param array<string, mixed> $request
|
||
*/
|
||
public static function notifyNewRequest(array $request, string $employeeName): void
|
||
{
|
||
$notifyEmail = env('LEAVE_NOTIFY_EMAIL', '');
|
||
if (!$notifyEmail) {
|
||
return;
|
||
}
|
||
|
||
$leaveType = self::$leaveTypeLabels[$request['leave_type']] ?? $request['leave_type'];
|
||
$dateFrom = date('d.m.Y', strtotime($request['date_from']));
|
||
$dateTo = date('d.m.Y', strtotime($request['date_to']));
|
||
$notes = $request['notes'] ?? '';
|
||
|
||
$subject = "Nová žádost o nepřítomnost - $employeeName ($leaveType)";
|
||
|
||
$html = "
|
||
<html>
|
||
<body style='font-family: Arial, sans-serif; line-height: 1.6; color: #333;'>
|
||
<h2 style='color: #de3a3a;'>Nová žádost o nepřítomnost</h2>
|
||
<table style='width: 100%; border-collapse: collapse; margin: 20px 0;'>
|
||
<tr>
|
||
<td style='padding: 10px; background: #f5f5f5; font-weight: bold; width: 180px;'>
|
||
Zaměstnanec:</td>
|
||
<td style='padding: 10px; border-bottom: 1px solid #ddd;'>"
|
||
. htmlspecialchars($employeeName) . "</td>
|
||
</tr>
|
||
<tr>
|
||
<td style='padding: 10px; background: #f5f5f5; font-weight: bold;'>Typ:</td>
|
||
<td style='padding: 10px; border-bottom: 1px solid #ddd;'>" . htmlspecialchars($leaveType) . "</td>
|
||
</tr>
|
||
<tr>
|
||
<td style='padding: 10px; background: #f5f5f5; font-weight: bold;'>Období:</td>
|
||
<td style='padding: 10px; border-bottom: 1px solid #ddd;'>$dateFrom – $dateTo</td>
|
||
</tr>
|
||
<tr>
|
||
<td style='padding: 10px; background: #f5f5f5; font-weight: bold;'>Pracovní dny:</td>
|
||
<td style='padding: 10px; border-bottom: 1px solid #ddd;'>"
|
||
. "{$request['total_days']} dní ({$request['total_hours']} hodin)</td>
|
||
</tr>"
|
||
. ($notes ? "
|
||
<tr>
|
||
<td style='padding: 10px; background: #f5f5f5; font-weight: bold;'>Poznámka:</td>
|
||
<td style='padding: 10px; border-bottom: 1px solid #ddd;'>" . htmlspecialchars($notes) . '</td>
|
||
</tr>' : '') . "
|
||
</table>
|
||
" . (env('APP_URL', '') ? "
|
||
<p style='margin-top: 20px;'>
|
||
<a href='" . htmlspecialchars(env('APP_URL', '')) . "/leave-approval'
|
||
style='background: #de3a3a; color: #fff; padding: 10px 20px;
|
||
text-decoration: none; border-radius: 5px;'>
|
||
Přejít ke schvalování
|
||
</a>
|
||
</p>" : "") . "
|
||
<hr style='margin: 30px 0; border: none; border-top: 1px solid #ddd;'>
|
||
<p style='font-size: 12px; color: #999;'>
|
||
Tato zpráva byla automaticky vygenerována systémem.<br>
|
||
Datum: " . date('d.m.Y H:i:s') . '
|
||
</p>
|
||
</body>
|
||
</html>';
|
||
|
||
$sent = Mailer::send($notifyEmail, $subject, $html);
|
||
if (!$sent) {
|
||
error_log("LeaveNotification: Failed to send new request notification to $notifyEmail");
|
||
}
|
||
}
|
||
}
|