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",
|
"@types/papaparse": "^5.3.14",
|
||||||
"better-auth": "catalog:",
|
"better-auth": "catalog:",
|
||||||
"convex": "catalog:",
|
"convex": "catalog:",
|
||||||
"convex-svelte": "^0.0.11",
|
"convex-svelte": "^0.0.12",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"emoji-picker-element": "^1.27.0",
|
"emoji-picker-element": "^1.27.0",
|
||||||
"is-network-error": "^1.3.0",
|
"is-network-error": "^1.3.0",
|
||||||
|
|||||||
@@ -7,8 +7,6 @@
|
|||||||
import { api } from '@sgse-app/backend/convex/_generated/api';
|
import { api } from '@sgse-app/backend/convex/_generated/api';
|
||||||
import type { FunctionReturnType } from 'convex/server';
|
import type { FunctionReturnType } from 'convex/server';
|
||||||
import type { Id } from '@sgse-app/backend/convex/_generated/dataModel';
|
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 CalendarConstructor = typeof import('@fullcalendar/core').Calendar;
|
||||||
type CalendarInstance = import('@fullcalendar/core').Calendar;
|
type CalendarInstance = import('@fullcalendar/core').Calendar;
|
||||||
type EventInput = import('@fullcalendar/core').EventInput;
|
type EventInput = import('@fullcalendar/core').EventInput;
|
||||||
@@ -37,6 +35,46 @@
|
|||||||
// Buscar TODAS as solicitações de férias (Dashboard RH)
|
// Buscar TODAS as solicitações de férias (Dashboard RH)
|
||||||
const todasSolicitacoesQuery = useQuery(api.ferias.listarTodas, {});
|
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 filtroStatus = $state<string>('todos');
|
||||||
let filtroNome = $state<string>('');
|
let filtroNome = $state<string>('');
|
||||||
let filtroMatricula = $state<string>('');
|
let filtroMatricula = $state<string>('');
|
||||||
@@ -46,7 +84,6 @@
|
|||||||
let filtroPeriodoFim = $state<string>('');
|
let filtroPeriodoFim = $state<string>('');
|
||||||
let dataInicioRelatorio = $state<string>('');
|
let dataInicioRelatorio = $state<string>('');
|
||||||
let dataFimRelatorio = $state<string>('');
|
let dataFimRelatorio = $state<string>('');
|
||||||
const solicitacoes = $derived<TodasSolicitacoes>(todasSolicitacoesQuery?.data ?? []);
|
|
||||||
|
|
||||||
// Filtrar solicitações
|
// Filtrar solicitações
|
||||||
const solicitacoesFiltradas = $derived(
|
const solicitacoesFiltradas = $derived(
|
||||||
@@ -304,11 +341,26 @@
|
|||||||
let calendarioContainer: HTMLDivElement | null = null;
|
let calendarioContainer: HTMLDivElement | null = null;
|
||||||
let calendarioInstance: CalendarInstance | null = null;
|
let calendarioInstance: CalendarInstance | null = null;
|
||||||
let CalendarClass: CalendarConstructor | null = null;
|
let CalendarClass: CalendarConstructor | null = null;
|
||||||
|
let calendarioInicializado = $state(false);
|
||||||
|
|
||||||
onMount(() => {
|
// Inicializar calendário quando o container estiver disponível
|
||||||
let destroyed = false;
|
$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([
|
const [coreModule, dayGridModule, interactionModule, localeModule] = await Promise.all([
|
||||||
import('@fullcalendar/core'),
|
import('@fullcalendar/core'),
|
||||||
import('@fullcalendar/daygrid'),
|
import('@fullcalendar/daygrid'),
|
||||||
@@ -316,7 +368,8 @@
|
|||||||
import('@fullcalendar/core/locales/pt-br')
|
import('@fullcalendar/core/locales/pt-br')
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (destroyed || !calendarioContainer) {
|
// Verificar novamente após os imports
|
||||||
|
if (!calendarioContainer || calendarioInstance || calendarioInicializado) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,26 +400,73 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
calendarioInstance.render();
|
calendarioInstance.render();
|
||||||
};
|
calendarioInicializado = true;
|
||||||
|
} catch (error) {
|
||||||
void inicializarCalendario();
|
console.error('Erro ao inicializar calendário:', error);
|
||||||
|
}
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
return () => {
|
return () => {
|
||||||
destroyed = true;
|
if (timeoutId) {
|
||||||
calendarioInstance?.destroy();
|
clearTimeout(timeoutId);
|
||||||
|
}
|
||||||
|
if (calendarioInstance && !calendarioContainer) {
|
||||||
|
try {
|
||||||
|
calendarioInstance.destroy();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erro ao destruir calendário:', error);
|
||||||
|
}
|
||||||
calendarioInstance = null;
|
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(() => {
|
$effect(() => {
|
||||||
if (!calendarioInstance) {
|
// Não atualizar se o calendário não estiver inicializado
|
||||||
|
if (!calendarioInstance || !calendarioInicializado) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Remover todos os eventos existentes
|
||||||
calendarioInstance.removeAllEvents();
|
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);
|
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') {
|
if (typeof window !== 'undefined') {
|
||||||
@@ -844,8 +944,41 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</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 -->
|
<!-- 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}
|
{:else}
|
||||||
<div class="stat bg-base-100 rounded-box border-base-300 border shadow-lg">
|
<div class="stat bg-base-100 rounded-box border-base-300 border shadow-lg">
|
||||||
<div class="stat-figure text-primary">
|
<div class="stat-figure text-primary">
|
||||||
@@ -933,9 +1066,24 @@
|
|||||||
<div class="stat-title">Reprovadas</div>
|
<div class="stat-title">Reprovadas</div>
|
||||||
<div class="stat-value text-error">{stats.reprovadas}</div>
|
<div class="stat-value text-error">{stats.reprovadas}</div>
|
||||||
<div class="stat-desc">Indeferidas</div>
|
<div class="stat-desc">Indeferidas</div>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</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}
|
{:else}
|
||||||
<div class="card border-base-300/60 bg-base-100 mb-6 border shadow-xl">
|
<div class="card border-base-300/60 bg-base-100 mb-6 border shadow-xl">
|
||||||
<div class="card-body space-y-6">
|
<div class="card-body space-y-6">
|
||||||
@@ -1166,8 +1314,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
<!-- Impressão da Programação -->
|
||||||
{#if !isLoading || !hasError}
|
{#if !isLoading || !hasError}
|
||||||
<div class="card border-accent/30 bg-base-100 mb-6 border shadow-xl">
|
<div class="card border-accent/30 bg-base-100 mb-6 border shadow-xl">
|
||||||
<div class="card-body space-y-4 p-6">
|
<div class="card-body space-y-4 p-6">
|
||||||
@@ -1245,13 +1395,26 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-base-content/60 text-xs">
|
<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 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.
|
se o bloqueador de pop-ups está desabilitado para o domínio.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{/if}
|
{/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}
|
{:else}
|
||||||
<div class="card bg-base-100 shadow-lg">
|
<div class="card bg-base-100 shadow-lg">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
@@ -1311,7 +1474,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
{#if solicitacao.time}
|
{#if solicitacao.time}
|
||||||
|
<div
|
||||||
|
class="badge badge-outline"
|
||||||
|
style="border-color: {solicitacao.time.cor}"
|
||||||
>
|
>
|
||||||
{solicitacao.time.nome}
|
{solicitacao.time.nome}
|
||||||
</div>
|
</div>
|
||||||
@@ -1337,7 +1503,21 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</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}
|
{:else}
|
||||||
<div class="mb-6 space-y-6" bind:this={chartContainer}>
|
<div class="mb-6 space-y-6" bind:this={chartContainer}>
|
||||||
<!-- Gráfico 1 -->
|
<!-- Gráfico 1 -->
|
||||||
@@ -1432,7 +1612,6 @@
|
|||||||
.map((item, index) => {
|
.map((item, index) => {
|
||||||
const x = getX(index, periodosPorMesAtivos.length);
|
const x = getX(index, periodosPorMesAtivos.length);
|
||||||
const y = chartHeight - padding.bottom - scaleY(item.totalDias, maxDias);
|
const y = chartHeight - padding.bottom - scaleY(item.totalDias, maxDias);
|
||||||
return `${x},${y}`;
|
|
||||||
return `${x},${y}`;
|
return `${x},${y}`;
|
||||||
})
|
})
|
||||||
.join(' ')}
|
.join(' ')}
|
||||||
@@ -1716,15 +1895,159 @@
|
|||||||
Visualize os períodos aprovados diretamente no calendário interativo
|
Visualize os períodos aprovados diretamente no calendário interativo
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-base-200/40 w-full overflow-hidden rounded-xl p-4">
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</main>
|
</main>
|
||||||
<footer
|
<footer
|
||||||
class="border-base-300/60 bg-base-100 text-base-content/70 mt-8 border-t py-6 text-center text-sm"
|
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.
|
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,
|
"lockfileVersion": 1,
|
||||||
"configVersion": 0,
|
|
||||||
"workspaces": {
|
"workspaces": {
|
||||||
"": {
|
"": {
|
||||||
"name": "sgse-app",
|
"name": "sgse-app",
|
||||||
@@ -42,7 +41,7 @@
|
|||||||
"@types/papaparse": "^5.3.14",
|
"@types/papaparse": "^5.3.14",
|
||||||
"better-auth": "catalog:",
|
"better-auth": "catalog:",
|
||||||
"convex": "catalog:",
|
"convex": "catalog:",
|
||||||
"convex-svelte": "^0.0.11",
|
"convex-svelte": "^0.0.12",
|
||||||
"date-fns": "^4.1.0",
|
"date-fns": "^4.1.0",
|
||||||
"emoji-picker-element": "^1.27.0",
|
"emoji-picker-element": "^1.27.0",
|
||||||
"eslint": "catalog:",
|
"eslint": "catalog:",
|
||||||
@@ -120,7 +119,7 @@
|
|||||||
"catalog": {
|
"catalog": {
|
||||||
"@eslint/js": "^9.39.1",
|
"@eslint/js": "^9.39.1",
|
||||||
"better-auth": "1.3.27",
|
"better-auth": "1.3.27",
|
||||||
"convex": "^1.28.0",
|
"convex": "^1.28.2",
|
||||||
"eslint": "^9.39.1",
|
"eslint": "^9.39.1",
|
||||||
"typescript": "^5.9.2",
|
"typescript": "^5.9.2",
|
||||||
},
|
},
|
||||||
@@ -717,11 +716,11 @@
|
|||||||
|
|
||||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
"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-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=="],
|
"cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="],
|
||||||
|
|
||||||
@@ -1347,6 +1346,8 @@
|
|||||||
|
|
||||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
"@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/@types/cookie": ["@types/cookie@0.6.0", "", {}, "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="],
|
||||||
|
|
||||||
"@sveltejs/kit/cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="],
|
"@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/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=="],
|
"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=="],
|
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
"catalog": {
|
"catalog": {
|
||||||
"convex": "^1.28.0",
|
"convex": "^1.28.2",
|
||||||
"typescript": "^5.9.2",
|
"typescript": "^5.9.2",
|
||||||
"better-auth": "1.3.27",
|
"better-auth": "1.3.27",
|
||||||
"eslint": "^9.39.1",
|
"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 actions_utils_nodeCrypto from "../actions/utils/nodeCrypto.js";
|
||||||
import type * as atestadosLicencas from "../atestadosLicencas.js";
|
import type * as atestadosLicencas from "../atestadosLicencas.js";
|
||||||
import type * as ausencias from "../ausencias.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 from "../auth.js";
|
||||||
|
import type * as auth_utils from "../auth/utils.js";
|
||||||
import type * as chat from "../chat.js";
|
import type * as chat from "../chat.js";
|
||||||
import type * as configuracaoEmail from "../configuracaoEmail.js";
|
import type * as configuracaoEmail from "../configuracaoEmail.js";
|
||||||
import type * as crons from "../crons.js";
|
import type * as crons from "../crons.js";
|
||||||
@@ -54,14 +54,6 @@ import type {
|
|||||||
FunctionReference,
|
FunctionReference,
|
||||||
} from "convex/server";
|
} 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<{
|
declare const fullApi: ApiFromModules<{
|
||||||
"actions/email": typeof actions_email;
|
"actions/email": typeof actions_email;
|
||||||
"actions/linkPreview": typeof actions_linkPreview;
|
"actions/linkPreview": typeof actions_linkPreview;
|
||||||
@@ -70,8 +62,8 @@ declare const fullApi: ApiFromModules<{
|
|||||||
"actions/utils/nodeCrypto": typeof actions_utils_nodeCrypto;
|
"actions/utils/nodeCrypto": typeof actions_utils_nodeCrypto;
|
||||||
atestadosLicencas: typeof atestadosLicencas;
|
atestadosLicencas: typeof atestadosLicencas;
|
||||||
ausencias: typeof ausencias;
|
ausencias: typeof ausencias;
|
||||||
"auth/utils": typeof auth_utils;
|
|
||||||
auth: typeof auth;
|
auth: typeof auth;
|
||||||
|
"auth/utils": typeof auth_utils;
|
||||||
chat: typeof chat;
|
chat: typeof chat;
|
||||||
configuracaoEmail: typeof configuracaoEmail;
|
configuracaoEmail: typeof configuracaoEmail;
|
||||||
crons: typeof crons;
|
crons: typeof crons;
|
||||||
@@ -103,14 +95,30 @@ declare const fullApi: ApiFromModules<{
|
|||||||
"utils/getClientIP": typeof utils_getClientIP;
|
"utils/getClientIP": typeof utils_getClientIP;
|
||||||
verificarMatriculas: typeof verificarMatriculas;
|
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<
|
export declare const api: FilterApi<
|
||||||
typeof fullApiWithMounts,
|
typeof fullApi,
|
||||||
FunctionReference<any, "public">
|
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<
|
export declare const internal: FilterApi<
|
||||||
typeof fullApiWithMounts,
|
typeof fullApi,
|
||||||
FunctionReference<any, "internal">
|
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 {
|
import {
|
||||||
ActionBuilder,
|
ActionBuilder,
|
||||||
AnyComponents,
|
|
||||||
HttpActionBuilder,
|
HttpActionBuilder,
|
||||||
MutationBuilder,
|
MutationBuilder,
|
||||||
QueryBuilder,
|
QueryBuilder,
|
||||||
@@ -19,15 +18,9 @@ import {
|
|||||||
GenericQueryCtx,
|
GenericQueryCtx,
|
||||||
GenericDatabaseReader,
|
GenericDatabaseReader,
|
||||||
GenericDatabaseWriter,
|
GenericDatabaseWriter,
|
||||||
FunctionReference,
|
|
||||||
} from "convex/server";
|
} from "convex/server";
|
||||||
import type { DataModel } from "./dataModel.js";
|
import type { DataModel } from "./dataModel.js";
|
||||||
|
|
||||||
type GenericCtx =
|
|
||||||
| GenericActionCtx<DataModel>
|
|
||||||
| GenericMutationCtx<DataModel>
|
|
||||||
| GenericQueryCtx<DataModel>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a query in this Convex app's public API.
|
* 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.
|
* Define an HTTP action.
|
||||||
*
|
*
|
||||||
* This function will be used to respond to HTTP requests received by a Convex
|
* The wrapped function will be used to respond to HTTP requests received
|
||||||
* deployment if the requests matches the path and method where this action
|
* by a Convex deployment if the requests matches the path and method where
|
||||||
* is routed. Be sure to route your action in `convex/http.js`.
|
* 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.
|
* @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up.
|
||||||
*/
|
*/
|
||||||
export declare const httpAction: HttpActionBuilder;
|
export declare const httpAction: HttpActionBuilder;
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import {
|
|||||||
internalActionGeneric,
|
internalActionGeneric,
|
||||||
internalMutationGeneric,
|
internalMutationGeneric,
|
||||||
internalQueryGeneric,
|
internalQueryGeneric,
|
||||||
componentsGeneric,
|
|
||||||
} from "convex/server";
|
} from "convex/server";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -81,10 +80,14 @@ export const action = actionGeneric;
|
|||||||
export const internalAction = internalActionGeneric;
|
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
|
* The wrapped function will be used to respond to HTTP requests received
|
||||||
* as its second.
|
* by a Convex deployment if the requests matches the path and method where
|
||||||
* @returns The wrapped endpoint function. Route a URL path to this function in `convex/http.js`.
|
* 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;
|
export const httpAction = httpActionGeneric;
|
||||||
|
|||||||
Reference in New Issue
Block a user