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:
2025-11-08 10:11:40 -03:00
parent 28107b4050
commit 01138b3e1c
24 changed files with 4655 additions and 1927 deletions

View File

@@ -12,17 +12,29 @@
// Queries
const saldosQuery = useQuery(api.saldoFerias.listarSaldos, { funcionarioId });
const solicitacoesQuery = useQuery(api.ferias.listarMinhasSolicitacoes, { funcionarioId });
const solicitacoesQuery = useQuery(api.ferias.listarMinhasSolicitacoes, {
funcionarioId,
});
const saldos = $derived(saldosQuery.data || []);
const solicitacoes = $derived(solicitacoesQuery.data || []);
// Estatísticas derivadas
const saldoAtual = $derived(saldos.find((s) => s.anoReferencia === new Date().getFullYear()));
const saldoAtual = $derived(
saldos.find((s) => s.anoReferencia === new Date().getFullYear()),
);
const totalSolicitacoes = $derived(solicitacoes.length);
const aprovadas = $derived(solicitacoes.filter((s) => s.status === "aprovado" || s.status === "data_ajustada_aprovada").length);
const pendentes = $derived(solicitacoes.filter((s) => s.status === "aguardando_aprovacao").length);
const reprovadas = $derived(solicitacoes.filter((s) => s.status === "reprovado").length);
const aprovadas = $derived(
solicitacoes.filter(
(s) => s.status === "aprovado" || s.status === "data_ajustada_aprovada",
).length,
);
const pendentes = $derived(
solicitacoes.filter((s) => s.status === "aguardando_aprovacao").length,
);
const reprovadas = $derived(
solicitacoes.filter((s) => s.status === "reprovado").length,
);
// Canvas para gráfico de pizza
let canvasSaldo = $state<HTMLCanvasElement>();
@@ -31,7 +43,7 @@
// Função para desenhar gráfico de pizza moderno
function desenharGraficoPizza(
canvas: HTMLCanvasElement,
dados: { label: string; valor: number; cor: string }[]
dados: { label: string; valor: number; cor: string }[],
) {
const ctx = canvas.getContext("2d");
if (!ctx) return;
@@ -90,7 +102,11 @@
desenharGraficoPizza(canvasSaldo, [
{ label: "Usado", valor: saldoAtual.diasUsados, cor: "#ff6b6b" },
{ label: "Pendente", valor: saldoAtual.diasPendentes, cor: "#ffa94d" },
{ label: "Disponível", valor: saldoAtual.diasDisponiveis, cor: "#51cf66" },
{
label: "Disponível",
valor: saldoAtual.diasDisponiveis,
cor: "#51cf66",
},
]);
}
@@ -107,10 +123,14 @@
<div class="dashboard-ferias">
<!-- Header -->
<div class="mb-8">
<h1 class="text-4xl font-bold bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
<h1
class="text-4xl font-bold bg-linear-to-r from-primary to-secondary bg-clip-text text-transparent"
>
📊 Dashboard de Férias
</h1>
<p class="text-base-content/70 mt-2">Visualize seus saldos e histórico de solicitações</p>
<p class="text-base-content/70 mt-2">
Visualize seus saldos e histórico de solicitações
</p>
</div>
{#if saldosQuery.isLoading || solicitacoesQuery.isLoading}
@@ -125,7 +145,7 @@
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<!-- Card 1: Saldo Disponível -->
<div
class="stat bg-gradient-to-br from-success/20 to-success/5 border-2 border-success/30 shadow-2xl rounded-2xl hover:scale-105 transition-all duration-300"
class="stat bg-linear-to-br from-success/20 to-success/5 border-2 border-success/30 shadow-2xl rounded-2xl hover:scale-105 transition-all duration-300"
>
<div class="stat-figure text-success">
<svg
@@ -143,13 +163,15 @@
</svg>
</div>
<div class="stat-title text-success font-semibold">Disponível</div>
<div class="stat-value text-success text-4xl">{saldoAtual?.diasDisponiveis || 0}</div>
<div class="stat-value text-success text-4xl">
{saldoAtual?.diasDisponiveis || 0}
</div>
<div class="stat-desc text-success/70">dias para usar</div>
</div>
<!-- Card 2: Dias Usados -->
<div
class="stat bg-gradient-to-br from-error/20 to-error/5 border-2 border-error/30 shadow-2xl rounded-2xl hover:scale-105 transition-all duration-300"
class="stat bg-linear-to-br from-error/20 to-error/5 border-2 border-error/30 shadow-2xl rounded-2xl hover:scale-105 transition-all duration-300"
>
<div class="stat-figure text-error">
<svg
@@ -167,13 +189,15 @@
</svg>
</div>
<div class="stat-title text-error font-semibold">Usado</div>
<div class="stat-value text-error text-4xl">{saldoAtual?.diasUsados || 0}</div>
<div class="stat-value text-error text-4xl">
{saldoAtual?.diasUsados || 0}
</div>
<div class="stat-desc text-error/70">dias já gozados</div>
</div>
<!-- Card 3: Pendentes -->
<div
class="stat bg-gradient-to-br from-warning/20 to-warning/5 border-2 border-warning/30 shadow-2xl rounded-2xl hover:scale-105 transition-all duration-300"
class="stat bg-linear-to-br from-warning/20 to-warning/5 border-2 border-warning/30 shadow-2xl rounded-2xl hover:scale-105 transition-all duration-300"
>
<div class="stat-figure text-warning">
<svg
@@ -191,13 +215,15 @@
</svg>
</div>
<div class="stat-title text-warning font-semibold">Pendentes</div>
<div class="stat-value text-warning text-4xl">{saldoAtual?.diasPendentes || 0}</div>
<div class="stat-value text-warning text-4xl">
{saldoAtual?.diasPendentes || 0}
</div>
<div class="stat-desc text-warning/70">aguardando aprovação</div>
</div>
<!-- Card 4: Total de Direito -->
<div
class="stat bg-gradient-to-br from-primary/20 to-primary/5 border-2 border-primary/30 shadow-2xl rounded-2xl hover:scale-105 transition-all duration-300"
class="stat bg-linear-to-br from-primary/20 to-primary/5 border-2 border-primary/30 shadow-2xl rounded-2xl hover:scale-105 transition-all duration-300"
>
<div class="stat-figure text-primary">
<svg
@@ -215,7 +241,9 @@
</svg>
</div>
<div class="stat-title text-primary font-semibold">Total Direito</div>
<div class="stat-value text-primary text-4xl">{saldoAtual?.diasDireito || 0}</div>
<div class="stat-value text-primary text-4xl">
{saldoAtual?.diasDireito || 0}
</div>
<div class="stat-desc text-primary/70">dias no ano</div>
</div>
</div>
@@ -246,15 +274,21 @@
<div class="flex justify-center gap-4 mt-4 flex-wrap">
<div class="flex items-center gap-2">
<div class="w-4 h-4 rounded-full bg-[#51cf66]"></div>
<span class="text-sm font-semibold">Disponível: {saldoAtual.diasDisponiveis} dias</span>
<span class="text-sm font-semibold"
>Disponível: {saldoAtual.diasDisponiveis} dias</span
>
</div>
<div class="flex items-center gap-2">
<div class="w-4 h-4 rounded-full bg-[#ffa94d]"></div>
<span class="text-sm font-semibold">Pendente: {saldoAtual.diasPendentes} dias</span>
<span class="text-sm font-semibold"
>Pendente: {saldoAtual.diasPendentes} dias</span
>
</div>
<div class="flex items-center gap-2">
<div class="w-4 h-4 rounded-full bg-[#ff6b6b]"></div>
<span class="text-sm font-semibold">Usado: {saldoAtual.diasUsados} dias</span>
<span class="text-sm font-semibold"
>Usado: {saldoAtual.diasUsados} dias</span
>
</div>
</div>
{:else}
@@ -283,7 +317,9 @@
<div class="card-body">
<h2 class="card-title text-2xl mb-4">
📋 Status de Solicitações
<div class="badge badge-secondary badge-lg">Total: {totalSolicitacoes}</div>
<div class="badge badge-secondary badge-lg">
Total: {totalSolicitacoes}
</div>
</h2>
{#if totalSolicitacoes > 0}
@@ -300,15 +336,19 @@
<div class="flex justify-center gap-4 mt-4 flex-wrap">
<div class="flex items-center gap-2">
<div class="w-4 h-4 rounded-full bg-[#51cf66]"></div>
<span class="text-sm font-semibold">Aprovadas: {aprovadas}</span>
<span class="text-sm font-semibold">Aprovadas: {aprovadas}</span
>
</div>
<div class="flex items-center gap-2">
<div class="w-4 h-4 rounded-full bg-[#ffa94d]"></div>
<span class="text-sm font-semibold">Pendentes: {pendentes}</span>
<span class="text-sm font-semibold">Pendentes: {pendentes}</span
>
</div>
<div class="flex items-center gap-2">
<div class="w-4 h-4 rounded-full bg-[#ff6b6b]"></div>
<span class="text-sm font-semibold">Reprovadas: {reprovadas}</span>
<span class="text-sm font-semibold"
>Reprovadas: {reprovadas}</span
>
</div>
</div>
{:else}
@@ -356,9 +396,20 @@
<tr>
<td class="font-bold">{saldo.anoReferencia}</td>
<td>{saldo.diasDireito} dias</td>
<td><span class="badge badge-error">{saldo.diasUsados}</span></td>
<td><span class="badge badge-warning">{saldo.diasPendentes}</span></td>
<td><span class="badge badge-success">{saldo.diasDisponiveis}</span></td>
<td
><span class="badge badge-error">{saldo.diasUsados}</span
></td
>
<td
><span class="badge badge-warning"
>{saldo.diasPendentes}</span
></td
>
<td
><span class="badge badge-success"
>{saldo.diasDisponiveis}</span
></td
>
<td>
{#if saldo.status === "ativo"}
<span class="badge badge-success">Ativo</span>
@@ -390,5 +441,3 @@
image-rendering: crisp-edges;
}
</style>

View File

@@ -22,7 +22,11 @@
// Dados da solicitação
let anoSelecionado = $state(new Date().getFullYear());
let periodosFerias: Array<{ dataInicio: string; dataFim: string; dias: number }> = $state([]);
let periodosFerias: Array<{
dataInicio: string;
dataFim: string;
dias: number;
}> = $state([]);
let observacao = $state("");
let processando = $state(false);
@@ -31,7 +35,7 @@
useQuery(api.saldoFerias.obterSaldo, {
funcionarioId,
anoReferencia: anoSelecionado,
})
}),
);
const validacaoQuery = $derived(
@@ -44,14 +48,14 @@
dataFim: p.dataFim,
})),
})
: { data: null }
: { data: null },
);
// Derivados
const saldo = $derived(saldoQuery.data);
const validacao = $derived(validacaoQuery.data);
const totalDiasSelecionados = $derived(
periodosFerias.reduce((acc, p) => acc + p.dias, 0)
periodosFerias.reduce((acc, p) => acc + p.dias, 0),
);
// Anos disponíveis (últimos 3 anos + próximo ano)
@@ -61,9 +65,11 @@
});
// Configurações do calendário (baseado no saldo/regime)
const maxPeriodos = $derived(saldo?.regimeTrabalho?.includes("Servidor") ? 2 : 3);
const maxPeriodos = $derived(
saldo?.regimeTrabalho?.includes("Servidor") ? 2 : 3,
);
const minDiasPorPeriodo = $derived(
saldo?.regimeTrabalho?.includes("Servidor") ? 10 : 5
saldo?.regimeTrabalho?.includes("Servidor") ? 10 : 5,
);
// Funções
@@ -154,7 +160,9 @@
class:border-primary={passoAtual === i + 1}
class:bg-base-200={passoAtual < i + 1}
class:text-base-content={passoAtual < i + 1}
style:box-shadow={passoAtual === i + 1 ? "0 0 20px rgba(102, 126, 234, 0.5)" : "none"}
style:box-shadow={passoAtual === i + 1
? "0 0 20px rgba(102, 126, 234, 0.5)"
: "none"}
>
{#if passoAtual > i + 1}
<svg
@@ -191,13 +199,19 @@
<!-- Labels dos passos -->
<div class="flex justify-between mt-4 px-1">
<div class="text-center flex-1">
<p class="text-sm font-semibold" class:text-primary={passoAtual === 1}>Ano & Saldo</p>
<p class="text-sm font-semibold" class:text-primary={passoAtual === 1}>
Ano & Saldo
</p>
</div>
<div class="text-center flex-1">
<p class="text-sm font-semibold" class:text-primary={passoAtual === 2}>Períodos</p>
<p class="text-sm font-semibold" class:text-primary={passoAtual === 2}>
Períodos
</p>
</div>
<div class="text-center flex-1">
<p class="text-sm font-semibold" class:text-primary={passoAtual === 3}>Confirmação</p>
<p class="text-sm font-semibold" class:text-primary={passoAtual === 3}>
Confirmação
</p>
</div>
</div>
</div>
@@ -207,7 +221,9 @@
<!-- PASSO 1: Ano & Saldo -->
{#if passoAtual === 1}
<div class="passo-content animate-fadeIn">
<h2 class="text-3xl font-bold mb-6 text-center bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
<h2
class="text-3xl font-bold mb-6 text-center bg-linear-to-r from-primary to-secondary bg-clip-text text-transparent"
>
Escolha o Ano de Referência
</h2>
@@ -231,14 +247,16 @@
<div class="skeleton h-64 w-full rounded-2xl"></div>
{:else if saldo}
<div
class="card bg-gradient-to-br from-primary/10 to-secondary/10 shadow-2xl border-2 border-primary/20"
class="card bg-linear-to-br from-primary/10 to-secondary/10 shadow-2xl border-2 border-primary/20"
>
<div class="card-body">
<h3 class="card-title text-2xl mb-4">
📊 Saldo de Férias {anoSelecionado}
</h3>
<div class="stats stats-vertical lg:stats-horizontal shadow-lg w-full">
<div
class="stats stats-vertical lg:stats-horizontal shadow-lg w-full"
>
<div class="stat">
<div class="stat-figure text-primary">
<svg
@@ -277,7 +295,9 @@
</svg>
</div>
<div class="stat-title">Disponível</div>
<div class="stat-value text-success">{saldo.diasDisponiveis}</div>
<div class="stat-value text-success">
{saldo.diasDisponiveis}
</div>
<div class="stat-desc">para usar</div>
</div>
@@ -321,7 +341,9 @@
<div>
<h4 class="font-bold">{saldo.regimeTrabalho}</h4>
<p class="text-sm">
Período aquisitivo: {new Date(saldo.dataInicio).toLocaleDateString("pt-BR")}
Período aquisitivo: {new Date(
saldo.dataInicio,
).toLocaleDateString("pt-BR")}
a {new Date(saldo.dataFim).toLocaleDateString("pt-BR")}
</p>
</div>
@@ -371,7 +393,9 @@
<!-- PASSO 2: Seleção de Períodos -->
{#if passoAtual === 2}
<div class="passo-content animate-fadeIn">
<h2 class="text-3xl font-bold mb-6 text-center bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
<h2
class="text-3xl font-bold mb-6 text-center bg-linear-to-r from-primary to-secondary bg-clip-text text-transparent"
>
Selecione os Períodos de Férias
</h2>
@@ -393,7 +417,8 @@
<div>
<p>
<strong>Saldo disponível:</strong>
{saldo?.diasDisponiveis || 0} dias | <strong>Selecionados:</strong>
{saldo?.diasDisponiveis || 0} dias |
<strong>Selecionados:</strong>
{totalDiasSelecionados} dias | <strong>Restante:</strong>
{(saldo?.diasDisponiveis || 0) - totalDiasSelecionados} dias
</p>
@@ -405,10 +430,10 @@
periodosExistentes={periodosFerias}
onPeriodoAdicionado={handlePeriodoAdicionado}
onPeriodoRemovido={handlePeriodoRemovido}
maxPeriodos={maxPeriodos}
minDiasPorPeriodo={minDiasPorPeriodo}
modoVisualizacao="month">
</CalendarioFerias>
{maxPeriodos}
{minDiasPorPeriodo}
modoVisualizacao="month"
></CalendarioFerias>
<!-- Validações -->
{#if validacao && periodosFerias.length > 0}
@@ -428,7 +453,9 @@
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
<span>✅ Períodos válidos! Total: {validacao.totalDias} dias</span>
<span
>✅ Períodos válidos! Total: {validacao.totalDias} dias</span
>
</div>
{:else}
<div class="alert alert-error">
@@ -489,7 +516,9 @@
<!-- PASSO 3: Confirmação -->
{#if passoAtual === 3}
<div class="passo-content animate-fadeIn">
<h2 class="text-3xl font-bold mb-6 text-center bg-gradient-to-r from-primary to-secondary bg-clip-text text-transparent">
<h2
class="text-3xl font-bold mb-6 text-center bg-linear-to-r from-primary to-secondary bg-clip-text text-transparent"
>
Confirme sua Solicitação
</h2>
@@ -506,7 +535,9 @@
<div class="stat bg-base-200 rounded-lg">
<div class="stat-title">Total de Dias</div>
<div class="stat-value text-success">{totalDiasSelecionados}</div>
<div class="stat-value text-success">
{totalDiasSelecionados}
</div>
</div>
</div>
@@ -521,11 +552,14 @@
</div>
<div class="flex-1">
<p class="font-semibold">
{new Date(periodo.dataInicio).toLocaleDateString("pt-BR", {
day: "2-digit",
month: "long",
year: "numeric",
})}
{new Date(periodo.dataInicio).toLocaleDateString(
"pt-BR",
{
day: "2-digit",
month: "long",
year: "numeric",
},
)}
até
{new Date(periodo.dataFim).toLocaleDateString("pt-BR", {
day: "2-digit",
@@ -533,7 +567,9 @@
year: "numeric",
})}
</p>
<p class="text-sm text-base-content/70">{periodo.dias} dias corridos</p>
<p class="text-sm text-base-content/70">
{periodo.dias} dias corridos
</p>
</div>
</div>
{/each}
@@ -542,7 +578,9 @@
<!-- Campo de Observação -->
<div class="form-control mt-6">
<label for="observacao" class="label">
<span class="label-text font-semibold">Observações (opcional)</span>
<span class="label-text font-semibold"
>Observações (opcional)</span
>
</label>
<textarea
id="observacao"
@@ -561,7 +599,11 @@
<div class="flex justify-between mt-8">
<div>
{#if passoAtual > 1}
<button type="button" class="btn btn-outline btn-lg gap-2" onclick={passoAnterior}>
<button
type="button"
class="btn btn-outline btn-lg gap-2"
onclick={passoAnterior}
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="h-5 w-5"
@@ -685,4 +727,3 @@
}
}
</style>