chore: update dependencies and enhance vacation request component
- Updated convex-svelte to version 0.0.12 and convex to version 1.28.2 for improved functionality. - Refactored the vacation request component to enhance loading states and error handling. - Implemented derived states for better management of loading and error states. - Improved calendar initialization logic and cleanup processes for better performance and reliability.
This commit is contained in:
@@ -44,7 +44,7 @@
|
||||
"@types/papaparse": "^5.3.14",
|
||||
"better-auth": "catalog:",
|
||||
"convex": "catalog:",
|
||||
"convex-svelte": "^0.0.11",
|
||||
"convex-svelte": "^0.0.12",
|
||||
"date-fns": "^4.1.0",
|
||||
"emoji-picker-element": "^1.27.0",
|
||||
"is-network-error": "^1.3.0",
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
import { api } from '@sgse-app/backend/convex/_generated/api';
|
||||
import type { FunctionReturnType } from 'convex/server';
|
||||
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||
import '@fullcalendar/core/index.css';
|
||||
import '@fullcalendar/daygrid/index.css';
|
||||
type CalendarConstructor = typeof import('@fullcalendar/core').Calendar;
|
||||
type CalendarInstance = import('@fullcalendar/core').Calendar;
|
||||
type EventInput = import('@fullcalendar/core').EventInput;
|
||||
@@ -37,6 +35,46 @@
|
||||
// Buscar TODAS as solicitações de férias (Dashboard RH)
|
||||
const todasSolicitacoesQuery = useQuery(api.ferias.listarTodas, {});
|
||||
|
||||
// Estados de loading e error
|
||||
const isLoading = $derived(todasSolicitacoesQuery?.isLoading ?? true);
|
||||
|
||||
// Verificar erro de forma segura
|
||||
const queryResult = $derived(todasSolicitacoesQuery);
|
||||
const hasError = $derived(
|
||||
queryResult !== undefined &&
|
||||
queryResult !== null &&
|
||||
typeof queryResult === 'object' &&
|
||||
'error' in queryResult &&
|
||||
(queryResult as { error?: unknown }).error !== undefined
|
||||
);
|
||||
const errorMessage = $derived(() => {
|
||||
if (!hasError) return 'Erro desconhecido ao carregar dados';
|
||||
const queryWithError = queryResult as { error?: unknown } | undefined;
|
||||
if (!queryWithError?.error) return 'Erro desconhecido ao carregar dados';
|
||||
if (queryWithError.error instanceof Error) {
|
||||
return queryWithError.error.message;
|
||||
}
|
||||
if (typeof queryWithError.error === 'string') {
|
||||
return queryWithError.error;
|
||||
}
|
||||
return 'Erro desconhecido ao carregar dados';
|
||||
});
|
||||
|
||||
// Manter último valor válido para evitar dados desaparecendo
|
||||
let ultimasSolicitacoesValidas = $state<TodasSolicitacoes>([]);
|
||||
|
||||
// Atualizar apenas quando temos dados válidos
|
||||
$effect(() => {
|
||||
if (todasSolicitacoesQuery?.data && !hasError) {
|
||||
ultimasSolicitacoesValidas = todasSolicitacoesQuery.data;
|
||||
}
|
||||
});
|
||||
|
||||
// Usar último valor válido ou array vazio
|
||||
const solicitacoes = $derived<TodasSolicitacoes>(
|
||||
todasSolicitacoesQuery?.data ?? ultimasSolicitacoesValidas
|
||||
);
|
||||
|
||||
let filtroStatus = $state<string>('todos');
|
||||
let filtroNome = $state<string>('');
|
||||
let filtroMatricula = $state<string>('');
|
||||
@@ -46,7 +84,6 @@
|
||||
let filtroPeriodoFim = $state<string>('');
|
||||
let dataInicioRelatorio = $state<string>('');
|
||||
let dataFimRelatorio = $state<string>('');
|
||||
const solicitacoes = $derived<TodasSolicitacoes>(todasSolicitacoesQuery?.data ?? []);
|
||||
|
||||
// Filtrar solicitações
|
||||
const solicitacoesFiltradas = $derived(
|
||||
@@ -304,11 +341,26 @@
|
||||
let calendarioContainer: HTMLDivElement | null = null;
|
||||
let calendarioInstance: CalendarInstance | null = null;
|
||||
let CalendarClass: CalendarConstructor | null = null;
|
||||
let calendarioInicializado = $state(false);
|
||||
|
||||
onMount(() => {
|
||||
let destroyed = false;
|
||||
// Inicializar calendário quando o container estiver disponível
|
||||
$effect(() => {
|
||||
// Verificar se o container está disponível e o calendário ainda não foi inicializado
|
||||
const container = calendarioContainer;
|
||||
|
||||
const inicializarCalendario = async () => {
|
||||
if (!container || calendarioInicializado || calendarioInstance) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Usar setTimeout para garantir que o elemento está completamente no DOM
|
||||
let timeoutId: ReturnType<typeof setTimeout> | null = null;
|
||||
|
||||
timeoutId = setTimeout(async () => {
|
||||
if (!calendarioContainer || calendarioInstance || calendarioInicializado) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const [coreModule, dayGridModule, interactionModule, localeModule] = await Promise.all([
|
||||
import('@fullcalendar/core'),
|
||||
import('@fullcalendar/daygrid'),
|
||||
@@ -316,7 +368,8 @@
|
||||
import('@fullcalendar/core/locales/pt-br')
|
||||
]);
|
||||
|
||||
if (destroyed || !calendarioContainer) {
|
||||
// Verificar novamente após os imports
|
||||
if (!calendarioContainer || calendarioInstance || calendarioInicializado) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -347,26 +400,73 @@
|
||||
});
|
||||
|
||||
calendarioInstance.render();
|
||||
};
|
||||
|
||||
void inicializarCalendario();
|
||||
calendarioInicializado = true;
|
||||
} catch (error) {
|
||||
console.error('Erro ao inicializar calendário:', error);
|
||||
}
|
||||
}, 300);
|
||||
|
||||
// Cleanup
|
||||
return () => {
|
||||
destroyed = true;
|
||||
calendarioInstance?.destroy();
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
if (calendarioInstance && !calendarioContainer) {
|
||||
try {
|
||||
calendarioInstance.destroy();
|
||||
} catch (error) {
|
||||
console.error('Erro ao destruir calendário:', error);
|
||||
}
|
||||
calendarioInstance = null;
|
||||
calendarioInicializado = false;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// Cleanup ao desmontar o componente
|
||||
onMount(() => {
|
||||
return () => {
|
||||
if (calendarioInstance) {
|
||||
try {
|
||||
calendarioInstance.destroy();
|
||||
} catch (error) {
|
||||
console.error('Erro ao destruir calendário:', error);
|
||||
}
|
||||
calendarioInstance = null;
|
||||
calendarioInicializado = false;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// Sincronizar eventos do calendário quando mudarem
|
||||
$effect(() => {
|
||||
if (!calendarioInstance) {
|
||||
// Não atualizar se o calendário não estiver inicializado
|
||||
if (!calendarioInstance || !calendarioInicializado) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Remover todos os eventos existentes
|
||||
calendarioInstance.removeAllEvents();
|
||||
for (const evento of eventosFerias) {
|
||||
|
||||
// Adicionar novos eventos
|
||||
const eventosClonados = eventosFerias.map((evento) => ({
|
||||
...evento,
|
||||
extendedProps: { ...evento.extendedProps }
|
||||
}));
|
||||
|
||||
// Adicionar eventos em lote
|
||||
for (const evento of eventosClonados) {
|
||||
calendarioInstance.addEvent(evento);
|
||||
}
|
||||
} catch (error) {
|
||||
// Log do erro, mas não interromper o fluxo
|
||||
if (error instanceof Error) {
|
||||
console.error('Erro ao atualizar eventos do calendário:', error.message);
|
||||
} else {
|
||||
console.error('Erro ao atualizar eventos do calendário:', error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
@@ -844,8 +944,41 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mensagem de erro -->
|
||||
{#if hasError}
|
||||
<div class="alert alert-error mb-6 shadow-lg">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-6 w-6 shrink-0 stroke-current"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<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>
|
||||
<h3 class="font-bold">Erro ao carregar dados</h3>
|
||||
<div class="text-sm">{errorMessage}</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Estatísticas -->
|
||||
<div class="mb-6 grid grid-cols-1 gap-4 md:grid-cols-4">
|
||||
{#if isLoading && !hasError}
|
||||
{#each Array.from({ length: 4 }, (_, i) => i) as index (index)}
|
||||
<div class="stat bg-base-100 rounded-box border-base-300 border shadow-lg">
|
||||
<div class="skeleton mb-2 h-8 w-8 rounded-full"></div>
|
||||
<div class="skeleton mb-2 h-4 w-20"></div>
|
||||
<div class="skeleton mb-2 h-8 w-16"></div>
|
||||
<div class="skeleton h-4 w-24"></div>
|
||||
</div>
|
||||
{/each}
|
||||
{:else}
|
||||
<div class="stat bg-base-100 rounded-box border-base-300 border shadow-lg">
|
||||
<div class="stat-figure text-primary">
|
||||
@@ -933,9 +1066,24 @@
|
||||
<div class="stat-title">Reprovadas</div>
|
||||
<div class="stat-value text-error">{stats.reprovadas}</div>
|
||||
<div class="stat-desc">Indeferidas</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<!-- Filtros -->
|
||||
{#if isLoading && !hasError}
|
||||
<div class="card border-base-300/60 bg-base-100 mb-6 border shadow-xl">
|
||||
<div class="card-body space-y-6">
|
||||
<div class="skeleton h-6 w-32"></div>
|
||||
<div class="grid grid-cols-12 gap-5">
|
||||
{#each Array.from({ length: 6 }, (_, i) => i) as index (index)}
|
||||
<div class="col-span-12 md:col-span-6 xl:col-span-4">
|
||||
<div class="skeleton h-32 rounded-2xl"></div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="card border-base-300/60 bg-base-100 mb-6 border shadow-xl">
|
||||
<div class="card-body space-y-6">
|
||||
@@ -1166,8 +1314,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Impressão da Programação -->
|
||||
{#if !isLoading || !hasError}
|
||||
<div class="card border-accent/30 bg-base-100 mb-6 border shadow-xl">
|
||||
<div class="card-body space-y-4 p-6">
|
||||
@@ -1245,13 +1395,26 @@
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-base-content/60 text-xs">
|
||||
O relatório será aberto em uma nova aba com formatação própria para impressão. Verifique se
|
||||
<p class="text-base-content/60 text-xs">
|
||||
O relatório será aberto em uma nova aba com formatação própria para impressão. Verifique
|
||||
se o bloqueador de pop-ups está desabilitado para o domínio.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Lista de Solicitações -->
|
||||
{#if isLoading && !hasError}
|
||||
<div class="card bg-base-100 shadow-lg">
|
||||
<div class="card-body">
|
||||
<div class="skeleton mb-4 h-6 w-48"></div>
|
||||
<div class="space-y-4">
|
||||
{#each Array.from({ length: 5 }, (_, i) => i) as index (index)}
|
||||
<div class="skeleton h-16 w-full"></div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{:else}
|
||||
<div class="card bg-base-100 shadow-lg">
|
||||
<div class="card-body">
|
||||
@@ -1311,7 +1474,10 @@
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
{#if solicitacao.time}
|
||||
{#if solicitacao.time}
|
||||
<div
|
||||
class="badge badge-outline"
|
||||
style="border-color: {solicitacao.time.cor}"
|
||||
>
|
||||
{solicitacao.time.nome}
|
||||
</div>
|
||||
@@ -1337,7 +1503,21 @@
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<!-- Visualizações e Relatórios -->
|
||||
{#if isLoading && !hasError}
|
||||
<div class="mb-6 space-y-6" bind:this={chartContainer}>
|
||||
{#each Array.from({ length: 3 }, (_, i) => i) as index (index)}
|
||||
<div class="card bg-base-100 border-primary/20 border shadow-lg">
|
||||
<div class="card-body space-y-4 p-6">
|
||||
<div class="skeleton mb-4 h-6 w-64"></div>
|
||||
<div class="skeleton h-64 w-full"></div>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{:else}
|
||||
<div class="mb-6 space-y-6" bind:this={chartContainer}>
|
||||
<!-- Gráfico 1 -->
|
||||
@@ -1432,7 +1612,6 @@
|
||||
.map((item, index) => {
|
||||
const x = getX(index, periodosPorMesAtivos.length);
|
||||
const y = chartHeight - padding.bottom - scaleY(item.totalDias, maxDias);
|
||||
return `${x},${y}`;
|
||||
return `${x},${y}`;
|
||||
})
|
||||
.join(' ')}
|
||||
@@ -1716,15 +1895,159 @@
|
||||
Visualize os períodos aprovados diretamente no calendário interativo
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-base-200/40 w-full overflow-hidden rounded-xl p-4">
|
||||
</div>
|
||||
<div class="bg-base-200/40 relative w-full overflow-hidden rounded-xl p-4">
|
||||
<div
|
||||
class="calendario-ferias overflow-hidden rounded-xl shadow-2xl"
|
||||
bind:this={calendarioContainer}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</main>
|
||||
<footer
|
||||
class="border-base-300/60 bg-base-100 text-base-content/70 mt-8 border-t py-6 text-center text-sm"
|
||||
>
|
||||
SGSE - Sistema de Gerenciamento da Secretaria de Esportes.
|
||||
</footer>
|
||||
|
||||
<style>
|
||||
/* Calendário de Férias */
|
||||
.calendario-ferias {
|
||||
font-family:
|
||||
'Inter',
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
'Segoe UI',
|
||||
sans-serif;
|
||||
}
|
||||
|
||||
/* Toolbar moderna com cores azuis/primary */
|
||||
:global(.calendario-ferias .fc .fc-toolbar) {
|
||||
background: linear-gradient(135deg, #2563eb 0%, #1d4ed8 100%);
|
||||
padding: 1rem;
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
color: white !important;
|
||||
}
|
||||
|
||||
:global(.calendario-ferias .fc .fc-toolbar-title) {
|
||||
color: white !important;
|
||||
font-weight: 700;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
:global(.calendario-ferias .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(.calendario-ferias .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(.calendario-ferias .fc .fc-button-active) {
|
||||
background: rgba(255, 255, 255, 0.4) !important;
|
||||
}
|
||||
|
||||
/* Cabeçalho dos dias */
|
||||
:global(.calendario-ferias .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(.calendario-ferias .fc .fc-daygrid-day) {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
:global(.calendario-ferias .fc .fc-daygrid-day:hover) {
|
||||
background: rgba(37, 99, 235, 0.05);
|
||||
}
|
||||
|
||||
:global(.calendario-ferias .fc .fc-daygrid-day-number) {
|
||||
padding: 0.5rem;
|
||||
font-weight: 600;
|
||||
color: #495057;
|
||||
}
|
||||
|
||||
/* Fim de semana */
|
||||
:global(.calendario-ferias .fc .fc-day-weekend) {
|
||||
background: rgba(59, 130, 246, 0.05);
|
||||
}
|
||||
|
||||
/* Hoje */
|
||||
:global(.calendario-ferias .fc .fc-day-today) {
|
||||
border: 2px solid #2563eb !important;
|
||||
}
|
||||
|
||||
/* Eventos (férias) */
|
||||
:global(.calendario-ferias .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(.calendario-ferias .fc .fc-event:hover) {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
/* Seleção (arrastar) */
|
||||
:global(.calendario-ferias .fc .fc-highlight) {
|
||||
background: rgba(37, 99, 235, 0.3) !important;
|
||||
border: 2px dashed #2563eb;
|
||||
}
|
||||
|
||||
/* Datas desabilitadas (passado) */
|
||||
:global(.calendario-ferias .fc .fc-day-past .fc-daygrid-day-number) {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
/* Remover bordas padrão */
|
||||
:global(.calendario-ferias .fc .fc-scrollgrid) {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
:global(.calendario-ferias .fc .fc-scrollgrid-section > td) {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/* Grid moderno */
|
||||
:global(.calendario-ferias .fc .fc-daygrid-day-frame) {
|
||||
border: 1px solid #e9ecef;
|
||||
min-height: 80px;
|
||||
}
|
||||
|
||||
/* Responsivo */
|
||||
@media (max-width: 768px) {
|
||||
:global(.calendario-ferias .fc .fc-toolbar) {
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
:global(.calendario-ferias .fc .fc-toolbar-title) {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
:global(.calendario-ferias .fc .fc-button) {
|
||||
font-size: 0.75rem;
|
||||
padding: 0.25rem 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
13
bun.lock
13
bun.lock
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "sgse-app",
|
||||
@@ -42,7 +41,7 @@
|
||||
"@types/papaparse": "^5.3.14",
|
||||
"better-auth": "catalog:",
|
||||
"convex": "catalog:",
|
||||
"convex-svelte": "^0.0.11",
|
||||
"convex-svelte": "^0.0.12",
|
||||
"date-fns": "^4.1.0",
|
||||
"emoji-picker-element": "^1.27.0",
|
||||
"eslint": "catalog:",
|
||||
@@ -120,7 +119,7 @@
|
||||
"catalog": {
|
||||
"@eslint/js": "^9.39.1",
|
||||
"better-auth": "1.3.27",
|
||||
"convex": "^1.28.0",
|
||||
"convex": "^1.28.2",
|
||||
"eslint": "^9.39.1",
|
||||
"typescript": "^5.9.2",
|
||||
},
|
||||
@@ -717,11 +716,11 @@
|
||||
|
||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||
|
||||
"convex": ["convex@1.28.0", "", { "dependencies": { "esbuild": "0.25.4", "prettier": "^3.0.0" }, "peerDependencies": { "@auth0/auth0-react": "^2.0.1", "@clerk/clerk-react": "^4.12.8 || ^5.0.0", "react": "^18.0.0 || ^19.0.0-0 || ^19.0.0" }, "optionalPeers": ["@auth0/auth0-react", "@clerk/clerk-react", "react"], "bin": { "convex": "bin/main.js" } }, "sha512-40FgeJ/LxP9TxnkDDztU/A5gcGTdq1klcTT5mM0Ak+kSlQiDktMpjNX1TfkWLxXaE3lI4qvawKH95v2RiYgFxA=="],
|
||||
"convex": ["convex@1.29.0", "", { "dependencies": { "esbuild": "0.25.4", "prettier": "^3.0.0" }, "peerDependencies": { "@auth0/auth0-react": "^2.0.1", "@clerk/clerk-react": "^4.12.8 || ^5.0.0", "react": "^18.0.0 || ^19.0.0-0 || ^19.0.0" }, "optionalPeers": ["@auth0/auth0-react", "@clerk/clerk-react", "react"], "bin": { "convex": "bin/main.js" } }, "sha512-uoIPXRKIp2eLCkkR9WJ2vc9NtgQtx8Pml59WPUahwbrd5EuW2WLI/cf2E7XrUzOSifdQC3kJZepisk4wJNTJaA=="],
|
||||
|
||||
"convex-helpers": ["convex-helpers@0.1.104", "", { "peerDependencies": { "@standard-schema/spec": "^1.0.0", "convex": "^1.24.0", "hono": "^4.0.5", "react": "^17.0.2 || ^18.0.0 || ^19.0.0", "typescript": "^5.5", "zod": "^3.22.4 || ^4.0.15" }, "optionalPeers": ["@standard-schema/spec", "hono", "react", "typescript", "zod"], "bin": { "convex-helpers": "bin.cjs" } }, "sha512-7CYvx7T3K6n+McDTK4ZQaQNNGBzq5aWezpjzsKbOxPXx7oNcTP9wrpef3JxeXWFzkByJv5hRCjseh9B7eNJ7Ig=="],
|
||||
|
||||
"convex-svelte": ["convex-svelte@0.0.11", "", { "peerDependencies": { "convex": "^1.10.0", "svelte": "^5.0.0" } }, "sha512-N/29gg5Zqy72vKL4xHSLk3jGwXVKIWXPs6xzq6KxGL84y/D6hG85pG2CPOzn08EzMmByts5FTkJ5p3var6yDng=="],
|
||||
"convex-svelte": ["convex-svelte@0.0.12", "", { "dependencies": { "esm-env": "^1.2.2", "runed": "^0.31.1" }, "peerDependencies": { "convex": "^1.10.0", "svelte": "^5.0.0" } }, "sha512-sUZoYp4ZsokyvKlbbg1dWYB7MkAjZn4nNG9DnADEt9L6KTKuhhnEIt6fdLj+3GnVBUGDTssm17+7ppzFc4y7Gg=="],
|
||||
|
||||
"cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
|
||||
|
||||
@@ -1347,6 +1346,8 @@
|
||||
|
||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||
|
||||
"@mmailaender/convex-better-auth-svelte/convex-svelte": ["convex-svelte@0.0.11", "", { "peerDependencies": { "convex": "^1.10.0", "svelte": "^5.0.0" } }, "sha512-N/29gg5Zqy72vKL4xHSLk3jGwXVKIWXPs6xzq6KxGL84y/D6hG85pG2CPOzn08EzMmByts5FTkJ5p3var6yDng=="],
|
||||
|
||||
"@sveltejs/kit/@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="],
|
||||
|
||||
"@sveltejs/kit/cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="],
|
||||
@@ -1371,6 +1372,8 @@
|
||||
|
||||
"convex/esbuild": ["esbuild@0.25.4", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.4", "@esbuild/android-arm": "0.25.4", "@esbuild/android-arm64": "0.25.4", "@esbuild/android-x64": "0.25.4", "@esbuild/darwin-arm64": "0.25.4", "@esbuild/darwin-x64": "0.25.4", "@esbuild/freebsd-arm64": "0.25.4", "@esbuild/freebsd-x64": "0.25.4", "@esbuild/linux-arm": "0.25.4", "@esbuild/linux-arm64": "0.25.4", "@esbuild/linux-ia32": "0.25.4", "@esbuild/linux-loong64": "0.25.4", "@esbuild/linux-mips64el": "0.25.4", "@esbuild/linux-ppc64": "0.25.4", "@esbuild/linux-riscv64": "0.25.4", "@esbuild/linux-s390x": "0.25.4", "@esbuild/linux-x64": "0.25.4", "@esbuild/netbsd-arm64": "0.25.4", "@esbuild/netbsd-x64": "0.25.4", "@esbuild/openbsd-arm64": "0.25.4", "@esbuild/openbsd-x64": "0.25.4", "@esbuild/sunos-x64": "0.25.4", "@esbuild/win32-arm64": "0.25.4", "@esbuild/win32-ia32": "0.25.4", "@esbuild/win32-x64": "0.25.4" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q=="],
|
||||
|
||||
"convex-svelte/runed": ["runed@0.31.1", "", { "dependencies": { "esm-env": "^1.0.0" }, "peerDependencies": { "svelte": "^5.7.0" } }, "sha512-v3czcTnO+EJjiPvD4dwIqfTdHLZ8oH0zJheKqAHh9QMViY7Qb29UlAMRpX7ZtHh7AFqV60KmfxaJ9QMy+L1igQ=="],
|
||||
|
||||
"eslint-plugin-react/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
|
||||
|
||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"packages/*"
|
||||
],
|
||||
"catalog": {
|
||||
"convex": "^1.28.0",
|
||||
"convex": "^1.28.2",
|
||||
"typescript": "^5.9.2",
|
||||
"better-auth": "1.3.27",
|
||||
"eslint": "^9.39.1",
|
||||
|
||||
34
packages/backend/convex/_generated/api.d.ts
vendored
34
packages/backend/convex/_generated/api.d.ts
vendored
@@ -15,8 +15,8 @@ import type * as actions_smtp from "../actions/smtp.js";
|
||||
import type * as actions_utils_nodeCrypto from "../actions/utils/nodeCrypto.js";
|
||||
import type * as atestadosLicencas from "../atestadosLicencas.js";
|
||||
import type * as ausencias from "../ausencias.js";
|
||||
import type * as auth_utils from "../auth/utils.js";
|
||||
import type * as auth from "../auth.js";
|
||||
import type * as auth_utils from "../auth/utils.js";
|
||||
import type * as chat from "../chat.js";
|
||||
import type * as configuracaoEmail from "../configuracaoEmail.js";
|
||||
import type * as crons from "../crons.js";
|
||||
@@ -54,14 +54,6 @@ import type {
|
||||
FunctionReference,
|
||||
} from "convex/server";
|
||||
|
||||
/**
|
||||
* A utility for referencing Convex functions in your app's API.
|
||||
*
|
||||
* Usage:
|
||||
* ```js
|
||||
* const myFunctionReference = api.myModule.myFunction;
|
||||
* ```
|
||||
*/
|
||||
declare const fullApi: ApiFromModules<{
|
||||
"actions/email": typeof actions_email;
|
||||
"actions/linkPreview": typeof actions_linkPreview;
|
||||
@@ -70,8 +62,8 @@ declare const fullApi: ApiFromModules<{
|
||||
"actions/utils/nodeCrypto": typeof actions_utils_nodeCrypto;
|
||||
atestadosLicencas: typeof atestadosLicencas;
|
||||
ausencias: typeof ausencias;
|
||||
"auth/utils": typeof auth_utils;
|
||||
auth: typeof auth;
|
||||
"auth/utils": typeof auth_utils;
|
||||
chat: typeof chat;
|
||||
configuracaoEmail: typeof configuracaoEmail;
|
||||
crons: typeof crons;
|
||||
@@ -103,14 +95,30 @@ declare const fullApi: ApiFromModules<{
|
||||
"utils/getClientIP": typeof utils_getClientIP;
|
||||
verificarMatriculas: typeof verificarMatriculas;
|
||||
}>;
|
||||
declare const fullApiWithMounts: typeof fullApi;
|
||||
|
||||
/**
|
||||
* A utility for referencing Convex functions in your app's public API.
|
||||
*
|
||||
* Usage:
|
||||
* ```js
|
||||
* const myFunctionReference = api.myModule.myFunction;
|
||||
* ```
|
||||
*/
|
||||
export declare const api: FilterApi<
|
||||
typeof fullApiWithMounts,
|
||||
typeof fullApi,
|
||||
FunctionReference<any, "public">
|
||||
>;
|
||||
|
||||
/**
|
||||
* A utility for referencing Convex functions in your app's internal API.
|
||||
*
|
||||
* Usage:
|
||||
* ```js
|
||||
* const myFunctionReference = internal.myModule.myFunction;
|
||||
* ```
|
||||
*/
|
||||
export declare const internal: FilterApi<
|
||||
typeof fullApiWithMounts,
|
||||
typeof fullApi,
|
||||
FunctionReference<any, "internal">
|
||||
>;
|
||||
|
||||
|
||||
16
packages/backend/convex/_generated/server.d.ts
vendored
16
packages/backend/convex/_generated/server.d.ts
vendored
@@ -10,7 +10,6 @@
|
||||
|
||||
import {
|
||||
ActionBuilder,
|
||||
AnyComponents,
|
||||
HttpActionBuilder,
|
||||
MutationBuilder,
|
||||
QueryBuilder,
|
||||
@@ -19,15 +18,9 @@ import {
|
||||
GenericQueryCtx,
|
||||
GenericDatabaseReader,
|
||||
GenericDatabaseWriter,
|
||||
FunctionReference,
|
||||
} from "convex/server";
|
||||
import type { DataModel } from "./dataModel.js";
|
||||
|
||||
type GenericCtx =
|
||||
| GenericActionCtx<DataModel>
|
||||
| GenericMutationCtx<DataModel>
|
||||
| GenericQueryCtx<DataModel>;
|
||||
|
||||
/**
|
||||
* Define a query in this Convex app's public API.
|
||||
*
|
||||
@@ -92,11 +85,12 @@ export declare const internalAction: ActionBuilder<DataModel, "internal">;
|
||||
/**
|
||||
* Define an HTTP action.
|
||||
*
|
||||
* This function will be used to respond to HTTP requests received by a Convex
|
||||
* deployment if the requests matches the path and method where this action
|
||||
* is routed. Be sure to route your action in `convex/http.js`.
|
||||
* The wrapped function will be used to respond to HTTP requests received
|
||||
* by a Convex deployment if the requests matches the path and method where
|
||||
* this action is routed. Be sure to route your httpAction in `convex/http.js`.
|
||||
*
|
||||
* @param func - The function. It receives an {@link ActionCtx} as its first argument.
|
||||
* @param func - The function. It receives an {@link ActionCtx} as its first argument
|
||||
* and a Fetch API `Request` object as its second.
|
||||
* @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
|
||||
*/
|
||||
export declare const httpAction: HttpActionBuilder;
|
||||
|
||||
@@ -16,7 +16,6 @@ import {
|
||||
internalActionGeneric,
|
||||
internalMutationGeneric,
|
||||
internalQueryGeneric,
|
||||
componentsGeneric,
|
||||
} from "convex/server";
|
||||
|
||||
/**
|
||||
@@ -81,10 +80,14 @@ export const action = actionGeneric;
|
||||
export const internalAction = internalActionGeneric;
|
||||
|
||||
/**
|
||||
* Define a Convex HTTP action.
|
||||
* Define an HTTP action.
|
||||
*
|
||||
* @param func - The function. It receives an {@link ActionCtx} as its first argument, and a `Request` object
|
||||
* as its second.
|
||||
* @returns The wrapped endpoint function. Route a URL path to this function in `convex/http.js`.
|
||||
* The wrapped function will be used to respond to HTTP requests received
|
||||
* by a Convex deployment if the requests matches the path and method where
|
||||
* this action is routed. Be sure to route your httpAction in `convex/http.js`.
|
||||
*
|
||||
* @param func - The function. It receives an {@link ActionCtx} as its first argument
|
||||
* and a Fetch API `Request` object as its second.
|
||||
* @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
|
||||
*/
|
||||
export const httpAction = httpActionGeneric;
|
||||
|
||||
Reference in New Issue
Block a user