refactor: enhance employee management with regime de trabalho integration
- Added regime de trabalho selection to employee forms for better categorization. - Updated backend validation to include regime de trabalho options for employees. - Enhanced employee data handling by integrating regime de trabalho into various components. - Removed the print modal for financial data to streamline the employee profile interface. - Improved overall code clarity and maintainability across multiple files.
This commit is contained in:
@@ -1,393 +1,399 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { Calendar } from "@fullcalendar/core";
|
||||
import dayGridPlugin from "@fullcalendar/daygrid";
|
||||
import interactionPlugin from "@fullcalendar/interaction";
|
||||
import multiMonthPlugin from "@fullcalendar/multimonth";
|
||||
import ptBrLocale from "@fullcalendar/core/locales/pt-br";
|
||||
import { onMount } from 'svelte';
|
||||
import { Calendar } from '@fullcalendar/core';
|
||||
import dayGridPlugin from '@fullcalendar/daygrid';
|
||||
import interactionPlugin from '@fullcalendar/interaction';
|
||||
import multiMonthPlugin from '@fullcalendar/multimonth';
|
||||
import ptBrLocale from '@fullcalendar/core/locales/pt-br';
|
||||
import { SvelteDate } from 'svelte/reactivity';
|
||||
|
||||
interface Props {
|
||||
periodosExistentes?: Array<{ dataInicio: string; dataFim: string; dias: number }>;
|
||||
onPeriodoAdicionado?: (periodo: { dataInicio: string; dataFim: string; dias: number }) => void;
|
||||
onPeriodoRemovido?: (index: number) => void;
|
||||
maxPeriodos?: number;
|
||||
minDiasPorPeriodo?: number;
|
||||
modoVisualizacao?: "month" | "multiMonth";
|
||||
readonly?: boolean;
|
||||
}
|
||||
interface Props {
|
||||
periodosExistentes?: Array<{ dataInicio: string; dataFim: string; dias: number }>;
|
||||
onPeriodoAdicionado?: (periodo: { dataInicio: string; dataFim: string; dias: number }) => void;
|
||||
onPeriodoRemovido?: (index: number) => void;
|
||||
maxPeriodos?: number;
|
||||
minDiasPorPeriodo?: number;
|
||||
modoVisualizacao?: 'month' | 'multiMonth';
|
||||
readonly?: boolean;
|
||||
}
|
||||
|
||||
let {
|
||||
periodosExistentes = [],
|
||||
onPeriodoAdicionado,
|
||||
onPeriodoRemovido,
|
||||
maxPeriodos = 3,
|
||||
minDiasPorPeriodo = 5,
|
||||
modoVisualizacao = "month",
|
||||
readonly = false,
|
||||
}: Props = $props();
|
||||
let {
|
||||
periodosExistentes = [],
|
||||
onPeriodoAdicionado,
|
||||
onPeriodoRemovido,
|
||||
maxPeriodos = 3,
|
||||
minDiasPorPeriodo = 5,
|
||||
modoVisualizacao = 'month',
|
||||
readonly = false
|
||||
}: Props = $props();
|
||||
|
||||
let calendarEl: HTMLDivElement;
|
||||
let calendar: Calendar | null = null;
|
||||
let selecaoInicio: Date | null = null;
|
||||
let eventos: any[] = $state([]);
|
||||
let calendarEl: HTMLDivElement;
|
||||
let calendar: Calendar | null = null;
|
||||
|
||||
// Cores dos períodos
|
||||
const coresPeriodos = [
|
||||
{ bg: "#667eea", border: "#5568d3", text: "#ffffff" }, // Roxo
|
||||
{ bg: "#f093fb", border: "#c75ce6", text: "#ffffff" }, // Rosa
|
||||
{ bg: "#4facfe", border: "#00c6ff", text: "#ffffff" }, // Azul
|
||||
];
|
||||
// Cores dos períodos
|
||||
const coresPeriodos = [
|
||||
{ bg: '#667eea', border: '#5568d3', text: '#ffffff' }, // Roxo
|
||||
{ bg: '#f093fb', border: '#c75ce6', text: '#ffffff' }, // Rosa
|
||||
{ bg: '#4facfe', border: '#00c6ff', text: '#ffffff' } // Azul
|
||||
];
|
||||
|
||||
// Converter períodos existentes em eventos
|
||||
function atualizarEventos() {
|
||||
eventos = periodosExistentes.map((periodo, index) => ({
|
||||
id: `periodo-${index}`,
|
||||
title: `Período ${index + 1} (${periodo.dias} dias)`,
|
||||
start: periodo.dataInicio,
|
||||
end: calcularDataFim(periodo.dataFim),
|
||||
backgroundColor: coresPeriodos[index % coresPeriodos.length].bg,
|
||||
borderColor: coresPeriodos[index % coresPeriodos.length].border,
|
||||
textColor: coresPeriodos[index % coresPeriodos.length].text,
|
||||
display: "block",
|
||||
extendedProps: {
|
||||
index,
|
||||
dias: periodo.dias,
|
||||
},
|
||||
}));
|
||||
}
|
||||
const eventos = $derived.by(() =>
|
||||
periodosExistentes.map((periodo, index) => ({
|
||||
id: `periodo-${index}`,
|
||||
title: `Período ${index + 1} (${periodo.dias} dias)`,
|
||||
start: periodo.dataInicio,
|
||||
end: calcularDataFim(periodo.dataFim),
|
||||
backgroundColor: coresPeriodos[index % coresPeriodos.length].bg,
|
||||
borderColor: coresPeriodos[index % coresPeriodos.length].border,
|
||||
textColor: coresPeriodos[index % coresPeriodos.length].text,
|
||||
display: 'block',
|
||||
extendedProps: {
|
||||
index,
|
||||
dias: periodo.dias
|
||||
}
|
||||
}))
|
||||
);
|
||||
|
||||
// Helper: Adicionar 1 dia à data fim (FullCalendar usa exclusive end)
|
||||
function calcularDataFim(dataFim: string): string {
|
||||
const data = new Date(dataFim);
|
||||
data.setDate(data.getDate() + 1);
|
||||
return data.toISOString().split("T")[0];
|
||||
}
|
||||
// Helper: Adicionar 1 dia à data fim (FullCalendar usa exclusive end)
|
||||
function calcularDataFim(dataFim: string): string {
|
||||
const data = new SvelteDate(dataFim);
|
||||
data.setDate(data.getDate() + 1);
|
||||
return data.toISOString().split('T')[0];
|
||||
}
|
||||
|
||||
// Helper: Calcular dias entre datas (inclusivo)
|
||||
function calcularDias(inicio: Date, fim: Date): number {
|
||||
const diffTime = Math.abs(fim.getTime() - inicio.getTime());
|
||||
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;
|
||||
return diffDays;
|
||||
}
|
||||
// Helper: Calcular dias entre datas (inclusivo)
|
||||
function calcularDias(inicio: Date, fim: Date): number {
|
||||
const diffTime = Math.abs(fim.getTime() - inicio.getTime());
|
||||
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;
|
||||
return diffDays;
|
||||
}
|
||||
|
||||
// Atualizar eventos quando períodos mudam
|
||||
$effect(() => {
|
||||
atualizarEventos();
|
||||
if (calendar) {
|
||||
calendar.removeAllEvents();
|
||||
calendar.addEventSource(eventos);
|
||||
}
|
||||
});
|
||||
// Atualizar eventos quando períodos mudam
|
||||
$effect(() => {
|
||||
if (!calendar) return;
|
||||
|
||||
onMount(() => {
|
||||
if (!calendarEl) return;
|
||||
calendar.removeAllEvents();
|
||||
if (eventos.length === 0) return;
|
||||
|
||||
atualizarEventos();
|
||||
// FullCalendar muta os objetos de evento internamente, então fornecemos cópias
|
||||
const eventosClonados = eventos.map((evento) => ({
|
||||
...evento,
|
||||
extendedProps: { ...evento.extendedProps }
|
||||
}));
|
||||
calendar.addEventSource(eventosClonados);
|
||||
});
|
||||
|
||||
calendar = new Calendar(calendarEl, {
|
||||
plugins: [dayGridPlugin, interactionPlugin, multiMonthPlugin],
|
||||
initialView: modoVisualizacao === "multiMonth" ? "multiMonthYear" : "dayGridMonth",
|
||||
locale: ptBrLocale,
|
||||
headerToolbar: {
|
||||
left: "prev,next today",
|
||||
center: "title",
|
||||
right: modoVisualizacao === "multiMonth" ? "multiMonthYear" : "dayGridMonth",
|
||||
},
|
||||
height: "auto",
|
||||
selectable: !readonly,
|
||||
selectMirror: true,
|
||||
unselectAuto: false,
|
||||
events: eventos,
|
||||
|
||||
// Estilo customizado
|
||||
buttonText: {
|
||||
today: "Hoje",
|
||||
month: "Mês",
|
||||
multiMonthYear: "Ano",
|
||||
},
|
||||
|
||||
// Seleção de período
|
||||
select: (info) => {
|
||||
if (readonly) return;
|
||||
onMount(() => {
|
||||
if (!calendarEl) return;
|
||||
|
||||
const inicio = new Date(info.startStr);
|
||||
const fim = new Date(info.endStr);
|
||||
fim.setDate(fim.getDate() - 1); // FullCalendar usa exclusive end
|
||||
calendar = new Calendar(calendarEl, {
|
||||
plugins: [dayGridPlugin, interactionPlugin, multiMonthPlugin],
|
||||
initialView: modoVisualizacao === 'multiMonth' ? 'multiMonthYear' : 'dayGridMonth',
|
||||
locale: ptBrLocale,
|
||||
headerToolbar: {
|
||||
left: 'prev,next today',
|
||||
center: 'title',
|
||||
right: modoVisualizacao === 'multiMonth' ? 'multiMonthYear' : 'dayGridMonth'
|
||||
},
|
||||
height: 'auto',
|
||||
selectable: !readonly,
|
||||
selectMirror: true,
|
||||
unselectAuto: false,
|
||||
events: eventos.map((evento) => ({ ...evento, extendedProps: { ...evento.extendedProps } })),
|
||||
|
||||
const dias = calcularDias(inicio, fim);
|
||||
// Estilo customizado
|
||||
buttonText: {
|
||||
today: 'Hoje',
|
||||
month: 'Mês',
|
||||
multiMonthYear: 'Ano'
|
||||
},
|
||||
|
||||
// Validar número de períodos
|
||||
if (periodosExistentes.length >= maxPeriodos) {
|
||||
alert(`Máximo de ${maxPeriodos} períodos permitidos`);
|
||||
calendar?.unselect();
|
||||
return;
|
||||
}
|
||||
// Seleção de período
|
||||
select: (info) => {
|
||||
if (readonly) return;
|
||||
|
||||
// Validar mínimo de dias
|
||||
if (dias < minDiasPorPeriodo) {
|
||||
alert(`Período deve ter no mínimo ${minDiasPorPeriodo} dias`);
|
||||
calendar?.unselect();
|
||||
return;
|
||||
}
|
||||
const inicio = new Date(info.startStr);
|
||||
const fim = new SvelteDate(info.endStr);
|
||||
fim.setDate(fim.getDate() - 1); // FullCalendar usa exclusive end
|
||||
|
||||
// Adicionar período
|
||||
const novoPeriodo = {
|
||||
dataInicio: info.startStr,
|
||||
dataFim: fim.toISOString().split("T")[0],
|
||||
dias,
|
||||
};
|
||||
const dias = calcularDias(inicio, fim);
|
||||
|
||||
if (onPeriodoAdicionado) {
|
||||
onPeriodoAdicionado(novoPeriodo);
|
||||
}
|
||||
// Validar número de períodos
|
||||
if (periodosExistentes.length >= maxPeriodos) {
|
||||
alert(`Máximo de ${maxPeriodos} períodos permitidos`);
|
||||
calendar?.unselect();
|
||||
return;
|
||||
}
|
||||
|
||||
calendar?.unselect();
|
||||
},
|
||||
// Validar mínimo de dias
|
||||
if (dias < minDiasPorPeriodo) {
|
||||
alert(`Período deve ter no mínimo ${minDiasPorPeriodo} dias`);
|
||||
calendar?.unselect();
|
||||
return;
|
||||
}
|
||||
|
||||
// Click em evento para remover
|
||||
eventClick: (info) => {
|
||||
if (readonly) return;
|
||||
// Adicionar período
|
||||
const novoPeriodo = {
|
||||
dataInicio: info.startStr,
|
||||
dataFim: fim.toISOString().split('T')[0],
|
||||
dias
|
||||
};
|
||||
|
||||
const index = info.event.extendedProps.index;
|
||||
if (
|
||||
confirm(
|
||||
`Deseja remover o Período ${index + 1} (${info.event.extendedProps.dias} dias)?`
|
||||
)
|
||||
) {
|
||||
if (onPeriodoRemovido) {
|
||||
onPeriodoRemovido(index);
|
||||
}
|
||||
}
|
||||
},
|
||||
if (onPeriodoAdicionado) {
|
||||
onPeriodoAdicionado(novoPeriodo);
|
||||
}
|
||||
|
||||
// Tooltip ao passar mouse
|
||||
eventDidMount: (info) => {
|
||||
info.el.title = `Click para remover\n${info.event.title}`;
|
||||
info.el.style.cursor = readonly ? "default" : "pointer";
|
||||
},
|
||||
calendar?.unselect();
|
||||
},
|
||||
|
||||
// Desabilitar datas passadas
|
||||
selectAllow: (selectInfo) => {
|
||||
const hoje = new Date();
|
||||
hoje.setHours(0, 0, 0, 0);
|
||||
return new Date(selectInfo.start) >= hoje;
|
||||
},
|
||||
// Click em evento para remover
|
||||
eventClick: (info) => {
|
||||
if (readonly) return;
|
||||
|
||||
// Highlight de fim de semana
|
||||
dayCellClassNames: (arg) => {
|
||||
if (arg.date.getDay() === 0 || arg.date.getDay() === 6) {
|
||||
return ["fc-day-weekend-custom"];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
});
|
||||
const index = info.event.extendedProps.index;
|
||||
if (
|
||||
confirm(`Deseja remover o Período ${index + 1} (${info.event.extendedProps.dias} dias)?`)
|
||||
) {
|
||||
if (onPeriodoRemovido) {
|
||||
onPeriodoRemovido(index);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
calendar.render();
|
||||
// Tooltip ao passar mouse
|
||||
eventDidMount: (info) => {
|
||||
info.el.title = `Click para remover\n${info.event.title}`;
|
||||
info.el.style.cursor = readonly ? 'default' : 'pointer';
|
||||
},
|
||||
|
||||
return () => {
|
||||
calendar?.destroy();
|
||||
};
|
||||
});
|
||||
// Desabilitar datas passadas
|
||||
selectAllow: (selectInfo) => {
|
||||
const hoje = new SvelteDate();
|
||||
hoje.setHours(0, 0, 0, 0);
|
||||
return new Date(selectInfo.start) >= hoje;
|
||||
},
|
||||
|
||||
// Highlight de fim de semana
|
||||
dayCellClassNames: (arg) => {
|
||||
if (arg.date.getDay() === 0 || arg.date.getDay() === 6) {
|
||||
return ['fc-day-weekend-custom'];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
calendar.render();
|
||||
|
||||
return () => {
|
||||
calendar?.destroy();
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="calendario-ferias-wrapper">
|
||||
<!-- Header com instruções -->
|
||||
{#if !readonly}
|
||||
<div class="alert alert-info mb-4 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 um período de férias</li>
|
||||
<li>Clique em um período colorido para removê-lo</li>
|
||||
<li>
|
||||
Você pode adicionar até {maxPeriodos} períodos (mínimo {minDiasPorPeriodo} dias cada)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<!-- Header com instruções -->
|
||||
{#if !readonly}
|
||||
<div class="alert alert-info mb-4 shadow-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
class="h-6 w-6 shrink-0 stroke-current"
|
||||
>
|
||||
<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="mt-1 list-inside list-disc">
|
||||
<li>Clique e arraste no calendário para selecionar um período de férias</li>
|
||||
<li>Clique em um período colorido para removê-lo</li>
|
||||
<li>
|
||||
Você pode adicionar até {maxPeriodos} períodos (mínimo {minDiasPorPeriodo} dias cada)
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Calendário -->
|
||||
<div
|
||||
bind:this={calendarEl}
|
||||
class="calendario-ferias shadow-2xl rounded-2xl overflow-hidden border-2 border-primary/10"
|
||||
></div>
|
||||
<!-- Calendário -->
|
||||
<div
|
||||
bind:this={calendarEl}
|
||||
class="calendario-ferias border-primary/10 overflow-hidden rounded-2xl border-2 shadow-2xl"
|
||||
></div>
|
||||
|
||||
<!-- Legenda de períodos -->
|
||||
{#if periodosExistentes.length > 0}
|
||||
<div class="mt-6 grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
{#each periodosExistentes as periodo, index}
|
||||
<div
|
||||
class="stat bg-base-100 shadow-lg rounded-xl border-2 transition-all hover:scale-105"
|
||||
style="border-color: {coresPeriodos[index % coresPeriodos.length].border}"
|
||||
>
|
||||
<div
|
||||
class="stat-figure text-white w-12 h-12 rounded-full flex items-center justify-center text-xl font-bold"
|
||||
style="background: {coresPeriodos[index % coresPeriodos.length].bg}"
|
||||
>
|
||||
{index + 1}
|
||||
</div>
|
||||
<div class="stat-title">Período {index + 1}</div>
|
||||
<div class="stat-value text-2xl" style="color: {coresPeriodos[index % coresPeriodos.length].bg}">
|
||||
{periodo.dias} dias
|
||||
</div>
|
||||
<div class="stat-desc">
|
||||
{new Date(periodo.dataInicio).toLocaleDateString("pt-BR")} até
|
||||
{new Date(periodo.dataFim).toLocaleDateString("pt-BR")}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
<!-- Legenda de períodos -->
|
||||
{#if periodosExistentes.length > 0}
|
||||
<div class="mt-6 grid grid-cols-1 gap-4 md:grid-cols-3">
|
||||
{#each periodosExistentes as periodo, index (index)}
|
||||
<div
|
||||
class="stat bg-base-100 rounded-xl border-2 shadow-lg transition-all hover:scale-105"
|
||||
style="border-color: {coresPeriodos[index % coresPeriodos.length].border}"
|
||||
>
|
||||
<div
|
||||
class="stat-figure flex h-12 w-12 items-center justify-center rounded-full text-xl font-bold text-white"
|
||||
style="background: {coresPeriodos[index % coresPeriodos.length].bg}"
|
||||
>
|
||||
{index + 1}
|
||||
</div>
|
||||
<div class="stat-title">Período {index + 1}</div>
|
||||
<div
|
||||
class="stat-value text-2xl"
|
||||
style="color: {coresPeriodos[index % coresPeriodos.length].bg}"
|
||||
>
|
||||
{periodo.dias} dias
|
||||
</div>
|
||||
<div class="stat-desc">
|
||||
{new Date(periodo.dataInicio).toLocaleDateString('pt-BR')} até
|
||||
{new Date(periodo.dataFim).toLocaleDateString('pt-BR')}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
/* Calendário Premium */
|
||||
.calendario-ferias {
|
||||
font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
}
|
||||
/* Calendário Premium */
|
||||
.calendario-ferias {
|
||||
font-family:
|
||||
'Inter',
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
'Segoe UI',
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
/* Toolbar moderna */
|
||||
:global(.fc .fc-toolbar) {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
padding: 1rem;
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
color: white !important;
|
||||
}
|
||||
/* Toolbar moderna */
|
||||
:global(.fc .fc-toolbar) {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
padding: 1rem;
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
:global(.fc .fc-toolbar-title) {
|
||||
color: white !important;
|
||||
font-weight: 700;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
:global(.fc .fc-toolbar-title) {
|
||||
color: white !important;
|
||||
font-weight: 700;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
:global(.fc .fc-button) {
|
||||
background: rgba(255, 255, 255, 0.2) !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3) !important;
|
||||
color: white !important;
|
||||
font-weight: 600;
|
||||
text-transform: capitalize;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
:global(.fc .fc-button) {
|
||||
background: rgba(255, 255, 255, 0.2) !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.3) !important;
|
||||
color: white !important;
|
||||
font-weight: 600;
|
||||
text-transform: capitalize;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
:global(.fc .fc-button:hover) {
|
||||
background: rgba(255, 255, 255, 0.3) !important;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
:global(.fc .fc-button:hover) {
|
||||
background: rgba(255, 255, 255, 0.3) !important;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
:global(.fc .fc-button-active) {
|
||||
background: rgba(255, 255, 255, 0.4) !important;
|
||||
}
|
||||
:global(.fc .fc-button-active) {
|
||||
background: rgba(255, 255, 255, 0.4) !important;
|
||||
}
|
||||
|
||||
/* Cabeçalho dos dias */
|
||||
:global(.fc .fc-col-header-cell) {
|
||||
background: linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%);
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.05em;
|
||||
padding: 0.75rem 0.5rem;
|
||||
color: #495057;
|
||||
}
|
||||
/* Cabeçalho dos dias */
|
||||
:global(.fc .fc-col-header-cell) {
|
||||
background: linear-gradient(180deg, #f8f9fa 0%, #e9ecef 100%);
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.75rem;
|
||||
letter-spacing: 0.05em;
|
||||
padding: 0.75rem 0.5rem;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
/* Células dos dias */
|
||||
:global(.fc .fc-daygrid-day) {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
/* Células dos dias */
|
||||
:global(.fc .fc-daygrid-day) {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
:global(.fc .fc-daygrid-day:hover) {
|
||||
background: rgba(102, 126, 234, 0.05);
|
||||
}
|
||||
:global(.fc .fc-daygrid-day:hover) {
|
||||
background: rgba(102, 126, 234, 0.05);
|
||||
}
|
||||
|
||||
:global(.fc .fc-daygrid-day-number) {
|
||||
padding: 0.5rem;
|
||||
font-weight: 600;
|
||||
color: #495057;
|
||||
}
|
||||
:global(.fc .fc-daygrid-day-number) {
|
||||
padding: 0.5rem;
|
||||
font-weight: 600;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
/* Fim de semana */
|
||||
:global(.fc .fc-day-weekend-custom) {
|
||||
background: rgba(255, 193, 7, 0.05);
|
||||
}
|
||||
/* Fim de semana */
|
||||
:global(.fc .fc-day-weekend-custom) {
|
||||
background: rgba(255, 193, 7, 0.05);
|
||||
}
|
||||
|
||||
/* Hoje */
|
||||
:global(.fc .fc-day-today) {
|
||||
background: rgba(102, 126, 234, 0.1) !important;
|
||||
border: 2px solid #667eea !important;
|
||||
}
|
||||
/* Hoje */
|
||||
:global(.fc .fc-day-today) {
|
||||
background: rgba(102, 126, 234, 0.1) !important;
|
||||
border: 2px solid #667eea !important;
|
||||
}
|
||||
|
||||
/* Eventos (períodos selecionados) */
|
||||
:global(.fc .fc-event) {
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
/* Eventos (períodos selecionados) */
|
||||
:global(.fc .fc-event) {
|
||||
border-radius: 0.5rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
font-weight: 600;
|
||||
font-size: 0.875rem;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
transition: all 0.3s ease;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
:global(.fc .fc-event:hover) {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
:global(.fc .fc-event:hover) {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
/* Seleção (arrastar) */
|
||||
:global(.fc .fc-highlight) {
|
||||
background: rgba(102, 126, 234, 0.3) !important;
|
||||
border: 2px dashed #667eea;
|
||||
}
|
||||
/* Seleção (arrastar) */
|
||||
:global(.fc .fc-highlight) {
|
||||
background: rgba(102, 126, 234, 0.3) !important;
|
||||
border: 2px dashed #667eea;
|
||||
}
|
||||
|
||||
/* Datas desabilitadas (passado) */
|
||||
:global(.fc .fc-day-past .fc-daygrid-day-number) {
|
||||
opacity: 0.4;
|
||||
}
|
||||
/* Datas desabilitadas (passado) */
|
||||
:global(.fc .fc-day-past .fc-daygrid-day-number) {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
/* Remover bordas padrão */
|
||||
:global(.fc .fc-scrollgrid) {
|
||||
border: none !important;
|
||||
}
|
||||
/* Remover bordas padrão */
|
||||
:global(.fc .fc-scrollgrid) {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
:global(.fc .fc-scrollgrid-section > td) {
|
||||
border: none !important;
|
||||
}
|
||||
:global(.fc .fc-scrollgrid-section > td) {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/* Grid moderno */
|
||||
:global(.fc .fc-daygrid-day-frame) {
|
||||
border: 1px solid #e9ecef;
|
||||
min-height: 80px;
|
||||
}
|
||||
/* Grid moderno */
|
||||
:global(.fc .fc-daygrid-day-frame) {
|
||||
border: 1px solid #e9ecef;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
/* Responsivo */
|
||||
@media (max-width: 768px) {
|
||||
:global(.fc .fc-toolbar) {
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
/* Responsivo */
|
||||
@media (max-width: 768px) {
|
||||
:global(.fc .fc-toolbar) {
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
:global(.fc .fc-toolbar-title) {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
:global(.fc .fc-toolbar-title) {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
:global(.fc .fc-button) {
|
||||
font-size: 0.75rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
}
|
||||
:global(.fc .fc-button) {
|
||||
font-size: 0.75rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user