refactor: clean up Svelte components and improve code readability
- Refactored multiple Svelte components to enhance code clarity and maintainability. - Standardized formatting and indentation across various files for consistency. - Improved error handling messages in the AprovarAusencias component for better user feedback. - Updated class names in the UI components to align with the new design system. - Removed unnecessary whitespace and comments to streamline the codebase.
This commit is contained in:
@@ -14,7 +14,10 @@
|
||||
dataFim: string;
|
||||
status: "aguardando_aprovacao" | "aprovado" | "reprovado";
|
||||
}>;
|
||||
onPeriodoSelecionado?: (periodo: { dataInicio: string; dataFim: string }) => void;
|
||||
onPeriodoSelecionado?: (periodo: {
|
||||
dataInicio: string;
|
||||
dataFim: string;
|
||||
}) => void;
|
||||
modoVisualizacao?: "month" | "multiMonth";
|
||||
readonly?: boolean;
|
||||
}
|
||||
@@ -45,7 +48,10 @@
|
||||
}> = $state([]);
|
||||
|
||||
// Cores por status
|
||||
const coresStatus: Record<string, { bg: string; border: string; text: string }> = {
|
||||
const coresStatus: Record<
|
||||
string,
|
||||
{ bg: string; border: string; text: string }
|
||||
> = {
|
||||
aguardando_aprovacao: { bg: "#f59e0b", border: "#d97706", text: "#ffffff" }, // Laranja
|
||||
aprovado: { bg: "#10b981", border: "#059669", text: "#ffffff" }, // Verde
|
||||
reprovado: { bg: "#ef4444", border: "#dc2626", text: "#ffffff" }, // Vermelho
|
||||
@@ -65,7 +71,8 @@
|
||||
status: string;
|
||||
};
|
||||
}> = ausenciasExistentes.map((ausencia, index) => {
|
||||
const cor = coresStatus[ausencia.status] || coresStatus.aguardando_aprovacao;
|
||||
const cor =
|
||||
coresStatus[ausencia.status] || coresStatus.aguardando_aprovacao;
|
||||
return {
|
||||
id: `ausencia-${index}`,
|
||||
title: `${getStatusTexto(ausencia.status)} - ${calcularDias(ausencia.dataInicio, ausencia.dataFim)} dias`,
|
||||
@@ -95,7 +102,7 @@
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
eventos = novosEventos;
|
||||
}
|
||||
|
||||
@@ -129,11 +136,11 @@
|
||||
inicio1: Date,
|
||||
fim1: Date,
|
||||
inicio2: string,
|
||||
fim2: string
|
||||
fim2: string,
|
||||
): boolean {
|
||||
const d2Inicio = new Date(inicio2);
|
||||
const d2Fim = new Date(fim2);
|
||||
|
||||
|
||||
// Verificar sobreposição: início1 <= fim2 && início2 <= fim1
|
||||
return inicio1 <= d2Fim && d2Inicio <= fim1;
|
||||
}
|
||||
@@ -141,14 +148,14 @@
|
||||
// Helper: Verificar se período selecionado sobrepõe com ausências existentes
|
||||
function verificarSobreposicaoComAusencias(inicio: Date, fim: Date): boolean {
|
||||
if (!ausenciasExistentes || ausenciasExistentes.length === 0) return false;
|
||||
|
||||
|
||||
// Verificar apenas ausências aprovadas ou aguardando aprovação
|
||||
const ausenciasBloqueantes = ausenciasExistentes.filter(
|
||||
(a) => a.status === "aprovado" || a.status === "aguardando_aprovacao"
|
||||
(a) => a.status === "aprovado" || a.status === "aguardando_aprovacao",
|
||||
);
|
||||
|
||||
|
||||
return ausenciasBloqueantes.some((ausencia) =>
|
||||
verificarSobreposicao(inicio, fim, ausencia.dataInicio, ausencia.dataFim)
|
||||
verificarSobreposicao(inicio, fim, ausencia.dataInicio, ausencia.dataFim),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -158,11 +165,11 @@
|
||||
const cellDate = new Date(info.date);
|
||||
const inicio = new Date(dataInicio);
|
||||
const fim = new Date(dataFim);
|
||||
|
||||
|
||||
cellDate.setHours(0, 0, 0, 0);
|
||||
inicio.setHours(0, 0, 0, 0);
|
||||
fim.setHours(0, 0, 0, 0);
|
||||
|
||||
|
||||
if (cellDate >= inicio && cellDate <= fim) {
|
||||
info.el.classList.add("fc-day-selected");
|
||||
} else {
|
||||
@@ -185,7 +192,9 @@
|
||||
|
||||
// Verificar se a data está dentro de alguma ausência aprovada ou aguardando aprovação
|
||||
const estaBloqueado = ausenciasExistentes
|
||||
.filter((a) => a.status === "aprovado" || a.status === "aguardando_aprovacao")
|
||||
.filter(
|
||||
(a) => a.status === "aprovado" || a.status === "aguardando_aprovacao",
|
||||
)
|
||||
.some((ausencia) => {
|
||||
const inicio = new Date(ausencia.dataInicio);
|
||||
const fim = new Date(ausencia.dataFim);
|
||||
@@ -204,23 +213,23 @@
|
||||
// Helper: Atualizar todos os dias selecionados no calendário
|
||||
function atualizarDiasSelecionados() {
|
||||
if (!calendar || !calendarEl || !dataInicio || !dataFim || readonly) return;
|
||||
|
||||
|
||||
// Usar a API do FullCalendar para iterar sobre todas as células visíveis
|
||||
const view = calendar.view;
|
||||
if (!view) return;
|
||||
|
||||
|
||||
const inicio = new Date(dataInicio);
|
||||
const fim = new Date(dataFim);
|
||||
inicio.setHours(0, 0, 0, 0);
|
||||
fim.setHours(0, 0, 0, 0);
|
||||
|
||||
|
||||
// O FullCalendar renderiza as células, então podemos usar dayCellDidMount
|
||||
// Mas também precisamos atualizar células existentes
|
||||
const cells = calendarEl.querySelectorAll(".fc-daygrid-day");
|
||||
cells.forEach((cell) => {
|
||||
// Remover classe primeiro
|
||||
cell.classList.remove("fc-day-selected");
|
||||
|
||||
|
||||
// Tentar obter a data do aria-label ou do elemento
|
||||
const ariaLabel = cell.getAttribute("aria-label");
|
||||
if (ariaLabel) {
|
||||
@@ -242,7 +251,13 @@
|
||||
|
||||
// Helper: Atualizar todos os dias bloqueados no calendário
|
||||
function atualizarDiasBloqueados() {
|
||||
if (!calendar || !calendarEl || readonly || !ausenciasExistentes || ausenciasExistentes.length === 0) {
|
||||
if (
|
||||
!calendar ||
|
||||
!calendarEl ||
|
||||
readonly ||
|
||||
!ausenciasExistentes ||
|
||||
ausenciasExistentes.length === 0
|
||||
) {
|
||||
// Remover classes de bloqueio se não houver ausências
|
||||
if (calendarEl) {
|
||||
const cells = calendarEl.querySelectorAll(".fc-daygrid-day");
|
||||
@@ -250,23 +265,23 @@
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
const cells = calendarEl.querySelectorAll(".fc-daygrid-day");
|
||||
const ausenciasBloqueantes = ausenciasExistentes.filter(
|
||||
(a) => a.status === "aprovado" || a.status === "aguardando_aprovacao"
|
||||
(a) => a.status === "aprovado" || a.status === "aguardando_aprovacao",
|
||||
);
|
||||
|
||||
|
||||
if (ausenciasBloqueantes.length === 0) {
|
||||
cells.forEach((cell) => cell.classList.remove("fc-day-blocked"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
cells.forEach((cell) => {
|
||||
cell.classList.remove("fc-day-blocked");
|
||||
|
||||
|
||||
// Tentar obter a data de diferentes formas
|
||||
let cellDate: Date | null = null;
|
||||
|
||||
|
||||
// Método 1: aria-label
|
||||
const ariaLabel = cell.getAttribute("aria-label");
|
||||
if (ariaLabel) {
|
||||
@@ -279,7 +294,7 @@
|
||||
// Ignorar
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Método 2: data-date attribute
|
||||
if (!cellDate) {
|
||||
const dataDate = cell.getAttribute("data-date");
|
||||
@@ -294,7 +309,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Método 3: Tentar obter do número do dia e contexto do calendário
|
||||
if (!cellDate && calendar.view) {
|
||||
const dayNumberEl = cell.querySelector(".fc-daygrid-day-number");
|
||||
@@ -315,10 +330,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (cellDate) {
|
||||
cellDate.setHours(0, 0, 0, 0);
|
||||
|
||||
|
||||
const estaBloqueado = ausenciasBloqueantes.some((ausencia) => {
|
||||
const inicio = new Date(ausencia.dataInicio);
|
||||
const fim = new Date(ausencia.dataFim);
|
||||
@@ -326,7 +341,7 @@
|
||||
fim.setHours(0, 0, 0, 0);
|
||||
return cellDate >= inicio && cellDate <= fim;
|
||||
});
|
||||
|
||||
|
||||
if (estaBloqueado) {
|
||||
cell.classList.add("fc-day-blocked");
|
||||
}
|
||||
@@ -337,18 +352,18 @@
|
||||
// Atualizar eventos quando mudanças ocorrem (evitar loop infinito)
|
||||
$effect(() => {
|
||||
if (!calendar || selecionando) return; // Não atualizar durante seleção
|
||||
|
||||
|
||||
// Garantir que temos as ausências antes de atualizar
|
||||
const ausencias = ausenciasExistentes;
|
||||
|
||||
|
||||
atualizarEventos();
|
||||
|
||||
|
||||
// Usar requestAnimationFrame para evitar múltiplas atualizações durante seleção
|
||||
requestAnimationFrame(() => {
|
||||
if (calendar && !selecionando) {
|
||||
calendar.removeAllEvents();
|
||||
calendar.addEventSource(eventos);
|
||||
|
||||
|
||||
// Atualizar classes de seleção e bloqueio quando as datas mudarem
|
||||
setTimeout(() => {
|
||||
atualizarDiasSelecionados();
|
||||
@@ -357,16 +372,17 @@
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Efeito separado para atualizar quando ausências mudarem
|
||||
$effect(() => {
|
||||
if (!calendar || readonly) return;
|
||||
|
||||
|
||||
const ausencias = ausenciasExistentes;
|
||||
const ausenciasBloqueantes = ausencias?.filter(
|
||||
(a) => a.status === "aprovado" || a.status === "aguardando_aprovacao"
|
||||
) || [];
|
||||
|
||||
const ausenciasBloqueantes =
|
||||
ausencias?.filter(
|
||||
(a) => a.status === "aprovado" || a.status === "aguardando_aprovacao",
|
||||
) || [];
|
||||
|
||||
// Se houver ausências bloqueantes, forçar atualização
|
||||
if (ausenciasBloqueantes.length > 0) {
|
||||
setTimeout(() => {
|
||||
@@ -386,12 +402,14 @@
|
||||
|
||||
calendar = new Calendar(calendarEl, {
|
||||
plugins: [dayGridPlugin, interactionPlugin, multiMonthPlugin],
|
||||
initialView: modoVisualizacao === "multiMonth" ? "multiMonthYear" : "dayGridMonth",
|
||||
initialView:
|
||||
modoVisualizacao === "multiMonth" ? "multiMonthYear" : "dayGridMonth",
|
||||
locale: ptBrLocale,
|
||||
headerToolbar: {
|
||||
left: "prev,next today",
|
||||
center: "title",
|
||||
right: modoVisualizacao === "multiMonth" ? "multiMonthYear" : "dayGridMonth",
|
||||
right:
|
||||
modoVisualizacao === "multiMonth" ? "multiMonthYear" : "dayGridMonth",
|
||||
},
|
||||
height: "auto",
|
||||
selectable: !readonly,
|
||||
@@ -443,7 +461,9 @@
|
||||
|
||||
// Validar sobreposição com ausências existentes
|
||||
if (verificarSobreposicaoComAusencias(inicio, fim)) {
|
||||
alert("Este período sobrepõe com uma ausência já aprovada ou aguardando aprovação. Por favor, escolha outro período.");
|
||||
alert(
|
||||
"Este período sobrepõe com uma ausência já aprovada ou aguardando aprovação. Por favor, escolha outro período.",
|
||||
);
|
||||
calendar?.unselect();
|
||||
selecionando = false;
|
||||
return;
|
||||
@@ -459,7 +479,7 @@
|
||||
|
||||
// Não remover seleção imediatamente para manter visualização
|
||||
// calendar?.unselect();
|
||||
|
||||
|
||||
// Liberar flag após um pequeno delay para garantir que o estado foi atualizado
|
||||
setTimeout(() => {
|
||||
selecionando = false;
|
||||
@@ -472,7 +492,9 @@
|
||||
if (readonly) {
|
||||
const status = info.event.extendedProps.status;
|
||||
const texto = getStatusTexto(status);
|
||||
alert(`Ausência ${texto}\nPeríodo: ${new Date(info.event.startStr).toLocaleDateString("pt-BR")} até ${new Date(calcularDataFim(info.event.endStr)).toLocaleDateString("pt-BR")}`);
|
||||
alert(
|
||||
`Ausência ${texto}\nPeríodo: ${new Date(info.event.startStr).toLocaleDateString("pt-BR")} até ${new Date(calcularDataFim(info.event.endStr)).toLocaleDateString("pt-BR")}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -491,35 +513,39 @@
|
||||
selectAllow: (selectInfo) => {
|
||||
const hoje = new Date();
|
||||
hoje.setHours(0, 0, 0, 0);
|
||||
|
||||
|
||||
// Bloquear datas passadas
|
||||
if (new Date(selectInfo.start) < hoje) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Verificar sobreposição com ausências existentes
|
||||
if (!readonly && ausenciasExistentes && ausenciasExistentes.length > 0) {
|
||||
if (
|
||||
!readonly &&
|
||||
ausenciasExistentes &&
|
||||
ausenciasExistentes.length > 0
|
||||
) {
|
||||
const inicioSelecao = new Date(selectInfo.start);
|
||||
const fimSelecao = new Date(selectInfo.end);
|
||||
fimSelecao.setDate(fimSelecao.getDate() - 1); // FullCalendar usa exclusive end
|
||||
|
||||
|
||||
inicioSelecao.setHours(0, 0, 0, 0);
|
||||
fimSelecao.setHours(0, 0, 0, 0);
|
||||
|
||||
|
||||
if (verificarSobreposicaoComAusencias(inicioSelecao, fimSelecao)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
// Adicionar classe CSS aos dias selecionados e bloqueados
|
||||
dayCellDidMount: (info) => {
|
||||
atualizarClasseSelecionado(info);
|
||||
atualizarClasseBloqueado(info);
|
||||
},
|
||||
|
||||
|
||||
// Atualizar quando as datas mudarem (navegação do calendário)
|
||||
datesSet: () => {
|
||||
setTimeout(() => {
|
||||
@@ -527,7 +553,7 @@
|
||||
atualizarDiasBloqueados();
|
||||
}, 100);
|
||||
},
|
||||
|
||||
|
||||
// Garantir que as classes sejam aplicadas após renderização inicial
|
||||
viewDidMount: () => {
|
||||
setTimeout(() => {
|
||||
@@ -541,20 +567,25 @@
|
||||
// Highlight de fim de semana e aplicar classe de bloqueio
|
||||
dayCellClassNames: (arg) => {
|
||||
const classes: string[] = [];
|
||||
|
||||
|
||||
if (arg.date.getDay() === 0 || arg.date.getDay() === 6) {
|
||||
classes.push("fc-day-weekend-custom");
|
||||
}
|
||||
|
||||
|
||||
// Verificar se o dia está bloqueado
|
||||
if (!readonly && ausenciasExistentes && ausenciasExistentes.length > 0) {
|
||||
if (
|
||||
!readonly &&
|
||||
ausenciasExistentes &&
|
||||
ausenciasExistentes.length > 0
|
||||
) {
|
||||
const cellDate = new Date(arg.date);
|
||||
cellDate.setHours(0, 0, 0, 0);
|
||||
|
||||
|
||||
const ausenciasBloqueantes = ausenciasExistentes.filter(
|
||||
(a) => a.status === "aprovado" || a.status === "aguardando_aprovacao"
|
||||
(a) =>
|
||||
a.status === "aprovado" || a.status === "aguardando_aprovacao",
|
||||
);
|
||||
|
||||
|
||||
const estaBloqueado = ausenciasBloqueantes.some((ausencia) => {
|
||||
const inicio = new Date(ausencia.dataInicio);
|
||||
const fim = new Date(ausencia.dataFim);
|
||||
@@ -562,12 +593,12 @@
|
||||
fim.setHours(0, 0, 0, 0);
|
||||
return cellDate >= inicio && cellDate <= fim;
|
||||
});
|
||||
|
||||
|
||||
if (estaBloqueado) {
|
||||
classes.push("fc-day-blocked");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return classes;
|
||||
},
|
||||
});
|
||||
@@ -585,32 +616,39 @@
|
||||
{#if !readonly}
|
||||
<div class="space-y-4 mb-4">
|
||||
<div class="alert alert-info shadow-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
class="stroke-current shrink-0 w-6 h-6"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
></path>
|
||||
</svg>
|
||||
<div class="text-sm">
|
||||
<p class="font-bold">Como usar:</p>
|
||||
<ul class="list-disc list-inside mt-1">
|
||||
<li>Clique e arraste no calendário para selecionar o período de ausência</li>
|
||||
<li>Você pode visualizar suas ausências já solicitadas no calendário</li>
|
||||
<li>A data de início não pode ser no passado</li>
|
||||
</ul>
|
||||
</div>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
class="stroke-current shrink-0 w-6 h-6"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
></path>
|
||||
</svg>
|
||||
<div class="text-sm">
|
||||
<p class="font-bold">Como usar:</p>
|
||||
<ul class="list-disc list-inside mt-1">
|
||||
<li>
|
||||
Clique e arraste no calendário para selecionar o período de
|
||||
ausência
|
||||
</li>
|
||||
<li>
|
||||
Você pode visualizar suas ausências já solicitadas no calendário
|
||||
</li>
|
||||
<li>A data de início não pode ser no passado</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Alerta sobre dias bloqueados -->
|
||||
{#if ausenciasExistentes && ausenciasExistentes.filter(a => a.status === "aprovado" || a.status === "aguardando_aprovacao").length > 0}
|
||||
{@const ausenciasBloqueantes = ausenciasExistentes.filter(a => a.status === "aprovado" || a.status === "aguardando_aprovacao")}
|
||||
{#if ausenciasExistentes && ausenciasExistentes.filter((a) => a.status === "aprovado" || a.status === "aguardando_aprovacao").length > 0}
|
||||
{@const ausenciasBloqueantes = ausenciasExistentes.filter(
|
||||
(a) => a.status === "aprovado" || a.status === "aguardando_aprovacao",
|
||||
)}
|
||||
<div class="alert alert-warning shadow-lg border-2 border-warning/50">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -628,8 +666,18 @@
|
||||
<div class="flex-1">
|
||||
<h3 class="font-bold">Atenção: Períodos Indisponíveis</h3>
|
||||
<div class="text-sm mt-1">
|
||||
<p>Os dias marcados em <span class="font-bold text-error">vermelho</span> estão bloqueados porque você já possui solicitações <strong>aprovadas</strong> ou <strong>aguardando aprovação</strong> para esses períodos.</p>
|
||||
<p class="mt-2">Você não pode criar novas solicitações que sobreponham esses períodos. Escolha um período diferente.</p>
|
||||
<p>
|
||||
Os dias marcados em <span class="font-bold text-error"
|
||||
>vermelho</span
|
||||
>
|
||||
estão bloqueados porque você já possui solicitações
|
||||
<strong>aprovadas</strong>
|
||||
ou <strong>aguardando aprovação</strong> para esses períodos.
|
||||
</p>
|
||||
<p class="mt-2">
|
||||
Você não pode criar novas solicitações que sobreponham esses
|
||||
períodos. Escolha um período diferente.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -647,30 +695,46 @@
|
||||
{#if ausenciasExistentes.length > 0 || readonly}
|
||||
<div class="mt-6 space-y-4">
|
||||
<div class="flex flex-wrap gap-4 justify-center">
|
||||
<div class="badge badge-lg gap-2" style="background-color: #f59e0b; border-color: #d97706; color: white;">
|
||||
<div class="w-3 h-3 rounded-full bg-white"></div>
|
||||
Aguardando Aprovação
|
||||
</div>
|
||||
<div class="badge badge-lg gap-2" style="background-color: #10b981; border-color: #059669; color: white;">
|
||||
<div class="w-3 h-3 rounded-full bg-white"></div>
|
||||
Aprovado
|
||||
</div>
|
||||
<div class="badge badge-lg gap-2" style="background-color: #ef4444; border-color: #dc2626; color: white;">
|
||||
<div class="w-3 h-3 rounded-full bg-white"></div>
|
||||
Reprovado
|
||||
</div>
|
||||
{#if !readonly && ausenciasExistentes && ausenciasExistentes.filter(a => a.status === "aprovado" || a.status === "aguardando_aprovacao").length > 0}
|
||||
<div class="badge badge-lg gap-2" style="background-color: rgba(239, 68, 68, 0.2); border-color: #ef4444; color: #dc2626;">
|
||||
<div class="w-3 h-3 rounded-full" style="background-color: #ef4444;"></div>
|
||||
<div
|
||||
class="badge badge-lg gap-2"
|
||||
style="background-color: #f59e0b; border-color: #d97706; color: white;"
|
||||
>
|
||||
<div class="w-3 h-3 rounded-full bg-white"></div>
|
||||
Aguardando Aprovação
|
||||
</div>
|
||||
<div
|
||||
class="badge badge-lg gap-2"
|
||||
style="background-color: #10b981; border-color: #059669; color: white;"
|
||||
>
|
||||
<div class="w-3 h-3 rounded-full bg-white"></div>
|
||||
Aprovado
|
||||
</div>
|
||||
<div
|
||||
class="badge badge-lg gap-2"
|
||||
style="background-color: #ef4444; border-color: #dc2626; color: white;"
|
||||
>
|
||||
<div class="w-3 h-3 rounded-full bg-white"></div>
|
||||
Reprovado
|
||||
</div>
|
||||
{#if !readonly && ausenciasExistentes && ausenciasExistentes.filter((a) => a.status === "aprovado" || a.status === "aguardando_aprovacao").length > 0}
|
||||
<div
|
||||
class="badge badge-lg gap-2"
|
||||
style="background-color: rgba(239, 68, 68, 0.2); border-color: #ef4444; color: #dc2626;"
|
||||
>
|
||||
<div
|
||||
class="w-3 h-3 rounded-full"
|
||||
style="background-color: #ef4444;"
|
||||
></div>
|
||||
Dias Bloqueados (Indisponíveis)
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
{#if !readonly && ausenciasExistentes && ausenciasExistentes.filter(a => a.status === "aprovado" || a.status === "aguardando_aprovacao").length > 0}
|
||||
|
||||
{#if !readonly && ausenciasExistentes && ausenciasExistentes.filter((a) => a.status === "aprovado" || a.status === "aguardando_aprovacao").length > 0}
|
||||
<div class="text-center">
|
||||
<p class="text-sm text-base-content/70">
|
||||
<span class="font-semibold text-error">Dias bloqueados</span> não podem ser selecionados para novas solicitações
|
||||
<span class="font-semibold text-error">Dias bloqueados</span> não podem
|
||||
ser selecionados para novas solicitações
|
||||
</p>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -679,7 +743,9 @@
|
||||
|
||||
<!-- Informação do período selecionado -->
|
||||
{#if dataInicio && dataFim && !readonly}
|
||||
<div class="mt-6 card bg-gradient-to-br from-orange-50 to-amber-50 dark:from-orange-950 dark:to-amber-950 shadow-lg border-2 border-orange-500/30">
|
||||
<div
|
||||
class="mt-6 card bg-linear-to-br from-orange-50 to-amber-50 dark:from-orange-950 dark:to-amber-950 shadow-lg border-2 border-orange-500/30"
|
||||
>
|
||||
<div class="card-body">
|
||||
<h3 class="card-title text-orange-700 dark:text-orange-400">
|
||||
<svg
|
||||
@@ -701,15 +767,21 @@
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4 mt-2">
|
||||
<div>
|
||||
<p class="text-sm text-base-content/70">Data Início</p>
|
||||
<p class="font-bold text-lg">{new Date(dataInicio).toLocaleDateString("pt-BR")}</p>
|
||||
<p class="font-bold text-lg">
|
||||
{new Date(dataInicio).toLocaleDateString("pt-BR")}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm text-base-content/70">Data Fim</p>
|
||||
<p class="font-bold text-lg">{new Date(dataFim).toLocaleDateString("pt-BR")}</p>
|
||||
<p class="font-bold text-lg">
|
||||
{new Date(dataFim).toLocaleDateString("pt-BR")}
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-sm text-base-content/70">Total de Dias</p>
|
||||
<p class="font-bold text-2xl text-orange-600 dark:text-orange-400">{calcularDias(dataInicio, dataFim)} dias</p>
|
||||
<p class="font-bold text-2xl text-orange-600 dark:text-orange-400">
|
||||
{calcularDias(dataInicio, dataFim)} dias
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -720,7 +792,12 @@
|
||||
<style>
|
||||
/* Calendário Premium */
|
||||
.calendario-ausencias {
|
||||
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
font-family:
|
||||
"Inter",
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
/* Toolbar moderna com cores laranja/amarelo */
|
||||
@@ -847,12 +924,18 @@
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
:global(.calendario-ausencias .fc-daygrid-day.fc-day-blocked .fc-daygrid-day-frame) {
|
||||
:global(
|
||||
.calendario-ausencias .fc-daygrid-day.fc-day-blocked .fc-daygrid-day-frame
|
||||
) {
|
||||
background-color: rgba(239, 68, 68, 0.2) !important;
|
||||
border-color: rgba(239, 68, 68, 0.4) !important;
|
||||
}
|
||||
|
||||
:global(.calendario-ausencias .fc-daygrid-day.fc-day-blocked .fc-daygrid-day-number) {
|
||||
:global(
|
||||
.calendario-ausencias
|
||||
.fc-daygrid-day.fc-day-blocked
|
||||
.fc-daygrid-day-number
|
||||
) {
|
||||
color: #dc2626 !important;
|
||||
font-weight: 700 !important;
|
||||
text-decoration: line-through !important;
|
||||
@@ -917,4 +1000,3 @@
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user