refactor: streamline Svelte components and enhance user feedback
- Refactored multiple Svelte components, including AprovarAusencias, AprovarFerias, and ErrorModal, to improve code clarity and maintainability. - Updated modal interactions and error handling messages for better user feedback. - Cleaned up component structures and standardized formatting for consistency across the codebase. - Enhanced styling and layout adjustments to align with the new design system.
This commit is contained in:
@@ -1,226 +1,313 @@
|
||||
<script lang="ts">
|
||||
import { goto } from "$app/navigation";
|
||||
import { useQuery } from "convex-svelte";
|
||||
import { api } from "@sgse-app/backend/convex/_generated/api";
|
||||
|
||||
// Buscar TODAS as solicitações de férias (Dashboard RH)
|
||||
const todasSolicitacoesQuery = useQuery(api.ferias.listarTodas, {});
|
||||
|
||||
let filtroStatus = $state<string>("todos");
|
||||
|
||||
const solicitacoes = $derived(todasSolicitacoesQuery?.data || []);
|
||||
|
||||
// Filtrar solicitações
|
||||
const solicitacoesFiltradas = $derived(
|
||||
solicitacoes.filter((s: any) => {
|
||||
// Filtro de status
|
||||
if (filtroStatus !== "todos" && s.status !== filtroStatus) return false;
|
||||
return true;
|
||||
})
|
||||
);
|
||||
|
||||
// Estatísticas gerais
|
||||
const stats = $derived({
|
||||
total: solicitacoes.length,
|
||||
aguardando: solicitacoes.filter((s: any) => s.status === "aguardando_aprovacao").length,
|
||||
aprovadas: solicitacoes.filter((s: any) => s.status === "aprovado" || s.status === "data_ajustada_aprovada").length,
|
||||
reprovadas: solicitacoes.filter((s: any) => s.status === "reprovado").length,
|
||||
});
|
||||
|
||||
function getStatusBadge(status: string) {
|
||||
const badges: Record<string, string> = {
|
||||
aguardando_aprovacao: "badge-warning",
|
||||
aprovado: "badge-success",
|
||||
reprovado: "badge-error",
|
||||
data_ajustada_aprovada: "badge-info",
|
||||
};
|
||||
return badges[status] || "badge-neutral";
|
||||
}
|
||||
|
||||
function getStatusTexto(status: string) {
|
||||
const textos: Record<string, string> = {
|
||||
aguardando_aprovacao: "Aguardando",
|
||||
aprovado: "Aprovado",
|
||||
reprovado: "Reprovado",
|
||||
data_ajustada_aprovada: "Ajustado",
|
||||
};
|
||||
return textos[status] || status;
|
||||
}
|
||||
|
||||
function formatarData(dataISO: string) {
|
||||
return new Date(dataISO).toLocaleDateString("pt-BR");
|
||||
}
|
||||
import { goto } from '$app/navigation';
|
||||
import { useQuery } from 'convex-svelte';
|
||||
import { api } from '@sgse-app/backend/convex/_generated/api';
|
||||
|
||||
// Buscar TODAS as solicitações de férias (Dashboard RH)
|
||||
const todasSolicitacoesQuery = useQuery(api.ferias.listarTodas, {});
|
||||
|
||||
let filtroStatus = $state<string>('todos');
|
||||
|
||||
const solicitacoes = $derived(todasSolicitacoesQuery?.data || []);
|
||||
|
||||
// Filtrar solicitações
|
||||
const solicitacoesFiltradas = $derived(
|
||||
solicitacoes.filter((s: any) => {
|
||||
// Filtro de status
|
||||
if (filtroStatus !== 'todos' && s.status !== filtroStatus) return false;
|
||||
return true;
|
||||
})
|
||||
);
|
||||
|
||||
// Estatísticas gerais
|
||||
const stats = $derived({
|
||||
total: solicitacoes.length,
|
||||
aguardando: solicitacoes.filter((s: any) => s.status === 'aguardando_aprovacao').length,
|
||||
aprovadas: solicitacoes.filter(
|
||||
(s: any) => s.status === 'aprovado' || s.status === 'data_ajustada_aprovada'
|
||||
).length,
|
||||
reprovadas: solicitacoes.filter((s: any) => s.status === 'reprovado').length
|
||||
});
|
||||
|
||||
function getStatusBadge(status: string) {
|
||||
const badges: Record<string, string> = {
|
||||
aguardando_aprovacao: 'badge-warning',
|
||||
aprovado: 'badge-success',
|
||||
reprovado: 'badge-error',
|
||||
data_ajustada_aprovada: 'badge-info'
|
||||
};
|
||||
return badges[status] || 'badge-neutral';
|
||||
}
|
||||
|
||||
function getStatusTexto(status: string) {
|
||||
const textos: Record<string, string> = {
|
||||
aguardando_aprovacao: 'Aguardando',
|
||||
aprovado: 'Aprovado',
|
||||
reprovado: 'Reprovado',
|
||||
data_ajustada_aprovada: 'Ajustado'
|
||||
};
|
||||
return textos[status] || status;
|
||||
}
|
||||
|
||||
function formatarData(dataISO: string) {
|
||||
return new Date(dataISO).toLocaleDateString('pt-BR');
|
||||
}
|
||||
</script>
|
||||
|
||||
<main class="container mx-auto px-4 py-6 max-w-7xl">
|
||||
<!-- Breadcrumb -->
|
||||
<div class="text-sm breadcrumbs mb-4">
|
||||
<ul>
|
||||
<li><a href="/recursos-humanos" class="text-primary hover:underline">Recursos Humanos</a></li>
|
||||
<li>Gestão de Férias</li>
|
||||
</ul>
|
||||
</div>
|
||||
<main class="container mx-auto max-w-7xl px-4 py-6">
|
||||
<!-- Breadcrumb -->
|
||||
<div class="breadcrumbs mb-4 text-sm">
|
||||
<ul>
|
||||
<li><a href="/recursos-humanos" class="text-primary hover:underline">Recursos Humanos</a></li>
|
||||
<li>Gestão de Férias</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Header -->
|
||||
<div class="mb-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="p-3 bg-purple-500/20 rounded-xl">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8 text-purple-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold text-primary">Dashboard de Férias</h1>
|
||||
<p class="text-base-content/70">Visão geral de todas as solicitações e funcionários</p>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-ghost gap-2" onclick={() => goto("/recursos-humanos")}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
|
||||
</svg>
|
||||
Voltar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Header -->
|
||||
<div class="mb-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-4">
|
||||
<div class="rounded-xl bg-purple-500/20 p-3">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8 text-purple-600"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-primary text-3xl font-bold">Dashboard de Férias</h1>
|
||||
<p class="text-base-content/70">Visão geral de todas as solicitações e funcionários</p>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn gap-2" onclick={() => goto('/recursos-humanos')}>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 19l-7-7m0 0l7-7m-7 7h18"
|
||||
/>
|
||||
</svg>
|
||||
Voltar
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Estatísticas -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
|
||||
<div class="stat bg-base-100 shadow-lg rounded-box border border-base-300">
|
||||
<div class="stat-figure text-primary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Total</div>
|
||||
<div class="stat-value text-primary">{stats.total}</div>
|
||||
<div class="stat-desc">Solicitações</div>
|
||||
</div>
|
||||
<!-- Estatísticas -->
|
||||
<div class="mb-6 grid grid-cols-1 gap-4 md:grid-cols-4">
|
||||
<div class="stat bg-base-100 rounded-box border-base-300 border shadow-lg">
|
||||
<div class="stat-figure text-primary">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Total</div>
|
||||
<div class="stat-value text-primary">{stats.total}</div>
|
||||
<div class="stat-desc">Solicitações</div>
|
||||
</div>
|
||||
|
||||
<div class="stat bg-base-100 shadow-lg rounded-box border border-warning/30">
|
||||
<div class="stat-figure text-warning">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Aguardando</div>
|
||||
<div class="stat-value text-warning">{stats.aguardando}</div>
|
||||
<div class="stat-desc">Pendentes</div>
|
||||
</div>
|
||||
<div class="stat bg-base-100 rounded-box border-warning/30 border shadow-lg">
|
||||
<div class="stat-figure text-warning">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Aguardando</div>
|
||||
<div class="stat-value text-warning">{stats.aguardando}</div>
|
||||
<div class="stat-desc">Pendentes</div>
|
||||
</div>
|
||||
|
||||
<div class="stat bg-base-100 shadow-lg rounded-box border border-success/30">
|
||||
<div class="stat-figure text-success">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Aprovadas</div>
|
||||
<div class="stat-value text-success">{stats.aprovadas}</div>
|
||||
<div class="stat-desc">Deferidas</div>
|
||||
</div>
|
||||
<div class="stat bg-base-100 rounded-box border-success/30 border shadow-lg">
|
||||
<div class="stat-figure text-success">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Aprovadas</div>
|
||||
<div class="stat-value text-success">{stats.aprovadas}</div>
|
||||
<div class="stat-desc">Deferidas</div>
|
||||
</div>
|
||||
|
||||
<div class="stat bg-base-100 shadow-lg rounded-box border border-error/30">
|
||||
<div class="stat-figure text-error">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Reprovadas</div>
|
||||
<div class="stat-value text-error">{stats.reprovadas}</div>
|
||||
<div class="stat-desc">Indeferidas</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stat bg-base-100 rounded-box border-error/30 border shadow-lg">
|
||||
<div class="stat-figure text-error">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-8 w-8"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="stat-title">Reprovadas</div>
|
||||
<div class="stat-value text-error">{stats.reprovadas}</div>
|
||||
<div class="stat-desc">Indeferidas</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Filtros -->
|
||||
<div class="card bg-base-100 shadow-lg mb-6">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-lg mb-4">Filtros</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-1 gap-4">
|
||||
<!-- Filtro Status -->
|
||||
<div class="form-control">
|
||||
<label class="label" for="status">
|
||||
<span class="label-text">Status</span>
|
||||
</label>
|
||||
<select id="status" class="select select-bordered" bind:value={filtroStatus}>
|
||||
<option value="todos">Todos</option>
|
||||
<option value="aguardando_aprovacao">Aguardando Aprovação</option>
|
||||
<option value="aprovado">Aprovado</option>
|
||||
<option value="reprovado">Reprovado</option>
|
||||
<option value="data_ajustada_aprovada">Data Ajustada</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Filtros -->
|
||||
<div class="card bg-base-100 mb-6 shadow-lg">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title mb-4 text-lg">Filtros</h2>
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-1">
|
||||
<!-- Filtro Status -->
|
||||
<div class="form-control">
|
||||
<label class="label" for="status">
|
||||
<span class="label-text">Status</span>
|
||||
</label>
|
||||
<select id="status" class="select select-bordered" bind:value={filtroStatus}>
|
||||
<option value="todos">Todos</option>
|
||||
<option value="aguardando_aprovacao">Aguardando Aprovação</option>
|
||||
<option value="aprovado">Aprovado</option>
|
||||
<option value="reprovado">Reprovado</option>
|
||||
<option value="data_ajustada_aprovada">Data Ajustada</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Lista de Solicitações -->
|
||||
<div class="card bg-base-100 shadow-lg">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-lg mb-4">
|
||||
Solicitações ({solicitacoesFiltradas.length})
|
||||
</h2>
|
||||
<!-- Lista de Solicitações -->
|
||||
<div class="card bg-base-100 shadow-lg">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title mb-4 text-lg">
|
||||
Solicitações ({solicitacoesFiltradas.length})
|
||||
</h2>
|
||||
|
||||
{#if solicitacoesFiltradas.length === 0}
|
||||
<div class="alert">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-info 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>
|
||||
<span>Nenhuma solicitação encontrada com os filtros aplicados.</span>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table table-zebra">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Funcionário</th>
|
||||
<th>Time</th>
|
||||
<th>Ano</th>
|
||||
<th>Períodos</th>
|
||||
<th>Total Dias</th>
|
||||
<th>Status</th>
|
||||
<th>Solicitado em</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each solicitacoesFiltradas as solicitacao}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="avatar placeholder">
|
||||
<div class="bg-primary text-primary-content rounded-full w-10">
|
||||
<span class="text-xs">{solicitacao.funcionario?.nome.substring(0, 2).toUpperCase()}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-bold">{solicitacao.funcionario?.nome}</div>
|
||||
<div class="text-xs opacity-50">{solicitacao.funcionario?.matricula || "S/N"}</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{#if solicitacao.time}
|
||||
<div class="badge badge-outline" style="border-color: {solicitacao.time.cor}">
|
||||
{solicitacao.time.nome}
|
||||
</div>
|
||||
{:else}
|
||||
<span class="text-base-content/50 text-xs">Sem time</span>
|
||||
{/if}
|
||||
</td>
|
||||
<td>{solicitacao.anoReferencia}</td>
|
||||
<td>{solicitacao.periodos.length} período(s)</td>
|
||||
<td class="font-bold">{solicitacao.periodos.reduce((acc: number, p: any) => acc + p.diasCorridos, 0)} dias</td>
|
||||
<td>
|
||||
<div class={`badge ${getStatusBadge(solicitacao.status)}`}>
|
||||
{getStatusTexto(solicitacao.status)}
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-xs">{new Date(solicitacao._creationTime).toLocaleDateString("pt-BR")}</td>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{#if solicitacoesFiltradas.length === 0}
|
||||
<div class="alert">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
class="stroke-info h-6 w-6 shrink-0"
|
||||
>
|
||||
<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>
|
||||
<span>Nenhuma solicitação encontrada com os filtros aplicados.</span>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table-zebra table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Funcionário</th>
|
||||
<th>Time</th>
|
||||
<th>Ano</th>
|
||||
<th>Períodos</th>
|
||||
<th>Total Dias</th>
|
||||
<th>Status</th>
|
||||
<th>Solicitado em</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{#each solicitacoesFiltradas as solicitacao}
|
||||
<tr>
|
||||
<td>
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="avatar placeholder">
|
||||
<div class="bg-primary text-primary-content w-10 rounded-full">
|
||||
<span class="text-xs"
|
||||
>{solicitacao.funcionario?.nome.substring(0, 2).toUpperCase()}</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-bold">{solicitacao.funcionario?.nome}</div>
|
||||
<div class="text-xs opacity-50">
|
||||
{solicitacao.funcionario?.matricula || 'S/N'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{#if solicitacao.time}
|
||||
<div class="badge badge-outline" style="border-color: {solicitacao.time.cor}">
|
||||
{solicitacao.time.nome}
|
||||
</div>
|
||||
{:else}
|
||||
<span class="text-base-content/50 text-xs">Sem time</span>
|
||||
{/if}
|
||||
</td>
|
||||
<td>{solicitacao.anoReferencia}</td>
|
||||
<td>{solicitacao.periodos.length} período(s)</td>
|
||||
<td class="font-bold"
|
||||
>{solicitacao.periodos.reduce((acc: number, p: any) => acc + p.diasCorridos, 0)}
|
||||
dias</td
|
||||
>
|
||||
<td>
|
||||
<div class={`badge ${getStatusBadge(solicitacao.status)}`}>
|
||||
{getStatusTexto(solicitacao.status)}
|
||||
</div>
|
||||
</td>
|
||||
<td class="text-xs"
|
||||
>{new Date(solicitacao._creationTime).toLocaleDateString('pt-BR')}</td
|
||||
>
|
||||
</tr>
|
||||
{/each}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user