feat: enhance vacation approval process by adding notification system for employees, including email alerts and in-app notifications; improve error handling and user feedback during vacation management

This commit is contained in:
2025-12-10 06:27:25 -03:00
parent 73da995109
commit d27c0b6f91
22 changed files with 1572 additions and 215 deletions

View File

@@ -0,0 +1,135 @@
<script lang="ts">
import { AlertTriangle, X } from 'lucide-svelte';
interface Props {
open: boolean;
title?: string;
message: string;
confirmText?: string;
cancelText?: string;
onConfirm: () => void;
onCancel: () => void;
}
let {
open = $bindable(false),
title = 'Confirmar ação',
message,
confirmText = 'Confirmar',
cancelText = 'Cancelar',
onConfirm,
onCancel
}: Props = $props();
function handleConfirm() {
open = false;
onConfirm();
}
function handleCancel() {
open = false;
onCancel();
}
</script>
{#if open}
<div
class="pointer-events-none fixed inset-0 z-50"
style="animation: fadeIn 0.2s ease-out;"
role="dialog"
aria-modal="true"
aria-labelledby="modal-confirm-title"
>
<!-- Backdrop -->
<div
class="pointer-events-auto absolute inset-0 bg-black/40 backdrop-blur-sm transition-opacity duration-200"
onclick={handleCancel}
></div>
<!-- Modal Box -->
<div
class="bg-base-100 pointer-events-auto absolute left-1/2 top-1/2 z-10 flex max-h-[90vh] w-full max-w-md transform -translate-x-1/2 -translate-y-1/2 flex-col overflow-hidden rounded-2xl shadow-2xl transition-all duration-300"
style="animation: slideUp 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);"
onclick={(e) => e.stopPropagation()}
>
<!-- Header -->
<div
class="border-base-300 from-warning/10 to-warning/5 flex flex-shrink-0 items-center justify-between border-b bg-linear-to-r px-6 py-4"
>
<h2 id="modal-confirm-title" class="text-warning flex items-center gap-2 text-xl font-bold">
<AlertTriangle class="h-6 w-6" strokeWidth={2.5} />
{title}
</h2>
<button
type="button"
class="btn btn-sm btn-circle btn-ghost hover:bg-base-300"
onclick={handleCancel}
aria-label="Fechar"
>
<X class="h-5 w-5" />
</button>
</div>
<!-- Content -->
<div class="modal-scroll flex-1 overflow-y-auto px-6 py-6">
<p class="text-base-content text-base leading-relaxed">{message}</p>
</div>
<!-- Footer -->
<div class="border-base-300 flex flex-shrink-0 justify-end gap-3 border-t px-6 py-4">
<button class="btn btn-ghost" onclick={handleCancel}>{cancelText}</button>
<button class="btn btn-warning" onclick={handleConfirm}>{confirmText}</button>
</div>
</div>
</div>
{/if}
<style>
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideUp {
from {
opacity: 0;
transform: translate(-50%, -40%) scale(0.95);
}
to {
opacity: 1;
transform: translate(-50%, -50%) scale(1);
}
}
/* Scrollbar customizada */
:global(.modal-scroll) {
scrollbar-width: thin;
scrollbar-color: hsl(var(--bc) / 0.3) transparent;
scroll-behavior: smooth;
-webkit-overflow-scrolling: touch;
}
:global(.modal-scroll::-webkit-scrollbar) {
width: 8px;
}
:global(.modal-scroll::-webkit-scrollbar-track) {
background: transparent;
border-radius: 4px;
}
:global(.modal-scroll::-webkit-scrollbar-thumb) {
background-color: hsl(var(--bc) / 0.3);
border-radius: 4px;
transition: background-color 0.2s ease;
}
:global(.modal-scroll::-webkit-scrollbar-thumb:hover) {
background-color: hsl(var(--bc) / 0.5);
}
</style>