diff --git a/apps/web/package.json b/apps/web/package.json index fb6349c..61cc60c 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -28,6 +28,7 @@ "vite": "^7.1.2" }, "dependencies": { + "eslint": "catalog:", "@convex-dev/better-auth": "^0.9.7", "@dicebear/collection": "^9.2.4", "@dicebear/core": "^9.2.4", @@ -43,10 +44,9 @@ "@types/papaparse": "^5.3.14", "better-auth": "catalog:", "convex": "catalog:", - "convex-svelte": "^0.0.12", + "convex-svelte": "^0.0.11", "date-fns": "^4.1.0", "emoji-picker-element": "^1.27.0", - "eslint": "catalog:", "is-network-error": "^1.3.0", "jspdf": "^3.0.3", "jspdf-autotable": "^5.0.2", diff --git a/apps/web/src/lib/components/AprovarAusencias.svelte b/apps/web/src/lib/components/AprovarAusencias.svelte index 7dc5b55..49b6072 100644 --- a/apps/web/src/lib/components/AprovarAusencias.svelte +++ b/apps/web/src/lib/components/AprovarAusencias.svelte @@ -1,414 +1,426 @@
- -
-

Aprovar/Reprovar Ausência

-

Analise a solicitação e tome uma decisão

-
+ +
+

+ Aprovar/Reprovar Ausência +

+

Analise a solicitação e tome uma decisão

+
- -
-
- -
-

- - - - Funcionário -

-
-
-

Nome

-

- {solicitacao.funcionario?.nome || 'N/A'} -

-
- {#if solicitacao.time} -
-

Time

-
- {solicitacao.time.nome} -
-
- {/if} -
-
+ +
+
+ +
+

+ + + + Funcionário +

+
+
+

Nome

+

+ {solicitacao.funcionario?.nome || "N/A"} +

+
+ {#if solicitacao.time} +
+

Time

+
+ {solicitacao.time.nome} +
+
+ {/if} +
+
-
+
- -
-

- - - - Período da Ausência -

-
-
-
Data Início
-
- {new Date(solicitacao.dataInicio).toLocaleDateString('pt-BR')} -
-
-
-
Data Fim
-
- {new Date(solicitacao.dataFim).toLocaleDateString('pt-BR')} -
-
-
-
Total de Dias
-
- {totalDias} -
-
dias corridos
-
-
-
+ +
+

+ + + + Período da Ausência +

+
+
+
Data Início
+
+ {new Date(solicitacao.dataInicio).toLocaleDateString("pt-BR")} +
+
+
+
Data Fim
+
+ {new Date(solicitacao.dataFim).toLocaleDateString("pt-BR")} +
+
+
+
Total de Dias
+
+ {totalDias} +
+
dias corridos
+
+
+
-
+
- -
-

- - - - Motivo da Ausência -

-
-
-

{solicitacao.motivo}

-
-
-
+ +
+

+ + + + Motivo da Ausência +

+
+
+

{solicitacao.motivo}

+
+
+
- -
-
- Status: -
- {getStatusTexto(solicitacao.status)} -
-
-
+ +
+
+ Status: +
+ {getStatusTexto(solicitacao.status)} +
+
+
- - {#if erro} -
- - - - {erro} -
- {/if} + + {#if erro} +
+ + + + {erro} +
+ {/if} - - {#if solicitacao.status === 'aguardando_aprovacao'} -
- - -
+ + {#if solicitacao.status === "aguardando_aprovacao"} +
+ + +
- - {#if motivoReprovacao !== undefined} -
-
- - -
-
- {/if} - {:else} -
- - - - Esta solicitação já foi processada. -
- {/if} + + {#if motivoReprovacao !== undefined} +
+
+ + +
+
+ {/if} + {:else} +
+ + + + Esta solicitação já foi processada. +
+ {/if} - -
- -
-
-
+ +
+ +
+
+
diff --git a/apps/web/src/lib/components/AprovarFerias.svelte b/apps/web/src/lib/components/AprovarFerias.svelte index 7dc924e..f15afe9 100644 --- a/apps/web/src/lib/components/AprovarFerias.svelte +++ b/apps/web/src/lib/components/AprovarFerias.svelte @@ -1,462 +1,384 @@
-
-
-
-

- {solicitacao.funcionario?.nome || 'Funcionário'} -

-

- Ano de Referência: {solicitacao.anoReferencia} -

-
-
- {getStatusTexto(solicitacao.status)} -
-
- - -
-

Períodos Solicitados

-
- {#each solicitacao.periodos as periodo, index} -
-
{index + 1}
-
-
- Início: - {new Date(periodo.dataInicio).toLocaleDateString('pt-BR')} -
-
- Fim: - {new Date(periodo.dataFim).toLocaleDateString('pt-BR')} -
-
- Dias: - {periodo.diasCorridos} -
-
-
- {/each} -
-
- - - {#if solicitacao.observacao} -
-

Observações

-
- {solicitacao.observacao} -
-
- {/if} - - - {#if solicitacao.historicoAlteracoes && solicitacao.historicoAlteracoes.length > 0} -
-

Histórico

-
- {#each solicitacao.historicoAlteracoes as hist} -
- - - - {formatarData(hist.data)} - - - {hist.acao} -
- {/each} -
-
- {/if} - - - {#if solicitacao.status === 'aguardando_aprovacao'} -
- - {#if !modoAjuste} - -
-
- - - -
- - -
-
-

Reprovar Solicitação

- - -
-
-
- {:else} - -
-

Ajustar Períodos

- {#each periodos as periodo, index} -
-
-
Período {index + 1}
-
-
- - calcularDias(periodo)} - /> -
-
- - calcularDias(periodo)} - /> -
-
- -
- {periodo.diasCorridos} -
-
-
-
-
- {/each} - -
- - -
-
- {/if} - {/if} - - - {#if solicitacao.status === 'reprovado' && solicitacao.motivoReprovacao} -
- - - -
-
Motivo da Reprovação:
-
{solicitacao.motivoReprovacao}
-
-
- {/if} - - - {#if erro} -
- - - - {erro} -
- {/if} - - - {#if onCancelar} -
- -
- {/if} -
+
+
+
+

+ {solicitacao.funcionario?.nome || "Funcionário"} +

+

+ Ano de Referência: {solicitacao.anoReferencia} +

+
+
+ {getStatusTexto(solicitacao.status)} +
+
+ + +
+

Períodos Solicitados

+
+ {#each solicitacao.periodos as periodo, index} +
+
{index + 1}
+
+
+ Início: + {new Date(periodo.dataInicio).toLocaleDateString("pt-BR")} +
+
+ Fim: + {new Date(periodo.dataFim).toLocaleDateString("pt-BR")} +
+
+ Dias: + {periodo.diasCorridos} +
+
+
+ {/each} +
+
+ + + {#if solicitacao.observacao} +
+

Observações

+
+ {solicitacao.observacao} +
+
+ {/if} + + + {#if solicitacao.historicoAlteracoes && solicitacao.historicoAlteracoes.length > 0} +
+

Histórico

+
+ {#each solicitacao.historicoAlteracoes as hist} +
+ + + + {formatarData(hist.data)} + - + {hist.acao} +
+ {/each} +
+
+ {/if} + + + {#if solicitacao.status === "aguardando_aprovacao"} +
+ + {#if !modoAjuste} + +
+
+ + + +
+ + +
+
+

Reprovar Solicitação

+ + +
+
+
+ {:else} + +
+

Ajustar Períodos

+ {#each periodos as periodo, index} +
+
+
Período {index + 1}
+
+
+ + calcularDias(periodo)} + /> +
+
+ + calcularDias(periodo)} + /> +
+
+ +
+ {periodo.diasCorridos} +
+
+
+
+
+ {/each} + +
+ + +
+
+ {/if} + {/if} + + + {#if solicitacao.status === "reprovado" && solicitacao.motivoReprovacao} +
+ + + +
+
Motivo da Reprovação:
+
{solicitacao.motivoReprovacao}
+
+
+ {/if} + + + {#if erro} +
+ + + + {erro} +
+ {/if} + + + {#if onCancelar} +
+ +
+ {/if} +
+ diff --git a/apps/web/src/lib/components/ErrorModal.svelte b/apps/web/src/lib/components/ErrorModal.svelte index 5ccc653..ba035d8 100644 --- a/apps/web/src/lib/components/ErrorModal.svelte +++ b/apps/web/src/lib/components/ErrorModal.svelte @@ -1,73 +1,82 @@ {#if open} - e.target === e.currentTarget && handleClose()} - > - - - + + {/if} + diff --git a/apps/web/src/lib/components/FuncionarioSelect.svelte b/apps/web/src/lib/components/FuncionarioSelect.svelte index 7355f18..544dcd4 100644 --- a/apps/web/src/lib/components/FuncionarioSelect.svelte +++ b/apps/web/src/lib/components/FuncionarioSelect.svelte @@ -1,187 +1,189 @@ -
- +
+ -
- +
+ - {#if value} - - {:else} -
- - - -
- {/if} + {#if value} + + {:else} +
+ + + +
+ {/if} - {#if mostrarDropdown && funcionariosFiltrados.length > 0} -
- {#each funcionariosFiltrados as funcionario} - - {/each} -
- {/if} + {#if mostrarDropdown && funcionariosFiltrados.length > 0} +
+ {#each funcionariosFiltrados as funcionario} + + {/each} +
+ {/if} - {#if mostrarDropdown && busca && funcionariosFiltrados.length === 0} -
- Nenhum funcionário encontrado -
- {/if} -
+ {#if mostrarDropdown && busca && funcionariosFiltrados.length === 0} +
+ Nenhum funcionário encontrado +
+ {/if} +
- {#if funcionarioSelecionado} -
- Selecionado: {funcionarioSelecionado.nome} - {#if funcionarioSelecionado.matricula} - - {funcionarioSelecionado.matricula} - {/if} -
- {/if} + {#if funcionarioSelecionado} +
+ Selecionado: {funcionarioSelecionado.nome} + {#if funcionarioSelecionado.matricula} + - {funcionarioSelecionado.matricula} + {/if} +
+ {/if}
diff --git a/apps/web/src/lib/components/PrintModal.svelte b/apps/web/src/lib/components/PrintModal.svelte index 0995b0f..0811111 100644 --- a/apps/web/src/lib/components/PrintModal.svelte +++ b/apps/web/src/lib/components/PrintModal.svelte @@ -1,27 +1,23 @@ - + diff --git a/apps/web/src/lib/components/Sidebar.svelte b/apps/web/src/lib/components/Sidebar.svelte index b1d7e01..f184db7 100644 --- a/apps/web/src/lib/components/Sidebar.svelte +++ b/apps/web/src/lib/components/Sidebar.svelte @@ -1,622 +1,661 @@
- -
- -
- {@render children?.()} -
+ +
+ +
+ {@render children?.()} +
- -
-
- - - Contato - - Suporte - - Privacidade -
-
-
-
- Logo -
-
-
-

Governo do Estado de Pernambuco

-

Secretaria de Esportes

-
-
-

- © {new Date().getFullYear()} - Todos os direitos reservados -

-
-
-
- - -
+ +
+
+ + + Contato + + Suporte + + Privacidade +
+
+
+
+ Logo +
+
+
+

+ Governo do Estado de Pernambuco +

+

Secretaria de Esportes

+
+
+

+ © {new Date().getFullYear()} - Todos os direitos reservados +

+
+
+
+ + +
{#if loginModalStore.showModal} - - + + + + + {/if} {#if showAboutModal} - - + + + {/if} {#if currentUser.data} - - + + {/if} diff --git a/apps/web/src/lib/components/SolicitarFerias.svelte b/apps/web/src/lib/components/SolicitarFerias.svelte index 4da0ddb..c61f7bc 100644 --- a/apps/web/src/lib/components/SolicitarFerias.svelte +++ b/apps/web/src/lib/components/SolicitarFerias.svelte @@ -1,353 +1,304 @@
-
-

- - - - Solicitar Férias -

- - -
- - -
- - -
-
-

Períodos ({periodos.length}/3)

- {#if periodos.length < 3} - - {/if} -
- -
- {#each periodos as periodo, index} -
-
-
-

Período {index + 1}

- {#if periodos.length > 1} - - {/if} -
- -
-
- - calcularDias(periodo)} - /> -
- -
- - calcularDias(periodo)} - /> -
- -
- -
- {periodo.diasCorridos} - dias -
-
-
-
-
- {/each} -
-
- - -
- - -
- - - {#if erro} -
- - - - {erro} -
- {/if} - - -
- {#if onCancelar} - - {/if} - -
-
+
+

+ + + + Solicitar Férias +

+ + +
+ + +
+ + +
+
+

Períodos ({periodos.length}/3)

+ {#if periodos.length < 3} + + {/if} +
+ +
+ {#each periodos as periodo, index} +
+
+
+

Período {index + 1}

+ {#if periodos.length > 1} + + {/if} +
+ +
+
+ + calcularDias(periodo)} + /> +
+ +
+ + calcularDias(periodo)} + /> +
+ +
+ +
+ {periodo.diasCorridos} + dias +
+
+
+
+
+ {/each} +
+
+ + +
+ + +
+ + + {#if erro} +
+ + + + {erro} +
+ {/if} + + +
+ {#if onCancelar} + + {/if} + +
+
+ diff --git a/apps/web/src/lib/components/ausencias/WizardSolicitacaoAusencia.svelte b/apps/web/src/lib/components/ausencias/WizardSolicitacaoAusencia.svelte index 67a8b81..5ce13b6 100644 --- a/apps/web/src/lib/components/ausencias/WizardSolicitacaoAusencia.svelte +++ b/apps/web/src/lib/components/ausencias/WizardSolicitacaoAusencia.svelte @@ -1,486 +1,503 @@
- -
-

Solicite uma ausência para assuntos particulares

-
+ +
+

+ Solicite uma ausência para assuntos particulares +

+
- -
-
-
-
- {#if passoAtual > 1} - - - - {:else} - {passoAtual} - {/if} -
-
-
Selecionar Período
-
Escolha as datas no calendário
-
-
-
-
-
-
- {#if passoAtual > 2} - - - - {:else} - 2 - {/if} -
-
-
Informar Motivo
-
Descreva o motivo da ausência
-
-
-
-
+ +
+
+
+
+ {#if passoAtual > 1} + + + + {:else} + {passoAtual} + {/if} +
+
+
Selecionar Período
+
Escolha as datas no calendário
+
+
+
+
+
+
+ {#if passoAtual > 2} + + + + {:else} + 2 + {/if} +
+
+
Informar Motivo
+
Descreva o motivo da ausência
+
+
+
+
- -
-
- {#if passoAtual === 1} - -
-
-

Selecione o Período

-

- Clique e arraste no calendário para selecionar o período de ausência -

-
+ +
+
+ {#if passoAtual === 1} + +
+
+

Selecione o Período

+

+ Clique e arraste no calendário para selecionar o período de + ausência +

+
- {#if ausenciasExistentesQuery === undefined} -
- - Carregando ausências existentes... -
- {:else} - - {/if} + {#if ausenciasExistentesQuery === undefined} +
+ + Carregando ausências existentes... +
+ {:else} + + {/if} - {#if dataInicio && dataFim} -
- - - -
-

Período selecionado!

-

- De {new Date(dataInicio).toLocaleDateString('pt-BR')} até{' '} - {new Date(dataFim).toLocaleDateString('pt-BR')} ({totalDias} dias) -

-
-
- {/if} -
- {:else if passoAtual === 2} - -
-
-

Informe o Motivo

-

- Descreva o motivo da sua solicitação de ausência (mínimo 10 caracteres) -

-
+ {#if dataInicio && dataFim} +
+ + + +
+

Período selecionado!

+

+ De {new Date(dataInicio).toLocaleDateString("pt-BR")} até{" "} + {new Date(dataFim).toLocaleDateString("pt-BR")} ({totalDias} dias) +

+
+
+ {/if} +
+ {:else if passoAtual === 2} + +
+
+

Informe o Motivo

+

+ Descreva o motivo da sua solicitação de ausência (mínimo 10 + caracteres) +

+
- - {#if dataInicio && dataFim} -
-
-

- - - - Resumo do Período -

-
-
-

Data Início

-

- {new Date(dataInicio).toLocaleDateString('pt-BR')} -

-
-
-

Data Fim

-

- {new Date(dataFim).toLocaleDateString('pt-BR')} -

-
-
-

Total de Dias

-

- {totalDias} dias -

-
-
-
-
- {/if} + + {#if dataInicio && dataFim} +
+
+

+ + + + Resumo do Período +

+
+
+

Data Início

+

+ {new Date(dataInicio).toLocaleDateString("pt-BR")} +

+
+
+

Data Fim

+

+ {new Date(dataFim).toLocaleDateString("pt-BR")} +

+
+
+

Total de Dias

+

+ {totalDias} dias +

+
+
+
+
+ {/if} - -
- - - -
+ +
+ + + +
- {#if motivo.trim().length > 0 && motivo.trim().length < 10} -
- - - - O motivo deve ter no mínimo 10 caracteres -
- {/if} -
- {/if} + {#if motivo.trim().length > 0 && motivo.trim().length < 10} +
+ + + + O motivo deve ter no mínimo 10 caracteres +
+ {/if} +
+ {/if} - -
- + +
+ - {#if passoAtual < totalPassos} - - {:else} - - {/if} -
+ {#if passoAtual < totalPassos} + + {:else} + + {/if} +
- -
- -
-
-
+ +
+ +
+
+
diff --git a/apps/web/src/lib/components/chat/ChatList.svelte b/apps/web/src/lib/components/chat/ChatList.svelte index 61fe005..4468fe3 100644 --- a/apps/web/src/lib/components/chat/ChatList.svelte +++ b/apps/web/src/lib/components/chat/ChatList.svelte @@ -1,448 +1,514 @@ -
- -
-
- - - - -
-
+
+ +
+
+ + + + +
+
- -
- -
- - -
+ +
+ +
+ + +
- -
- -
-
+ +
+ +
+
- -
- {#if activeTab === 'usuarios'} - - {#if usuarios?.data && usuariosFiltrados.length > 0} - {#each usuariosFiltrados as usuario (usuario._id)} - - {/each} - {:else if !usuarios?.data} - -
- -
- {:else} - -
- - - -

Nenhum usuário encontrado

-
- {/if} - {:else} - - {#if conversas?.data && conversasFiltradas().length > 0} - {#each conversasFiltradas() as conversa (conversa._id)} - + {/each} + {:else if !usuarios?.data} + +
+ +
+ {:else} + +
+ + + +

Nenhum usuário encontrado

+
+ {/if} + {:else} + + {#if conversas?.data && conversasFiltradas().length > 0} + {#each conversasFiltradas() as conversa (conversa._id)} + - {/each} - {:else if !conversas?.data} - -
- -
- {:else} - -
- - - -

Nenhuma conversa encontrada

-

Crie um grupo ou sala de reunião para começar

-
- {/if} - {/if} -
+ +
+
+

+ {conversa.nome || + (conversa.tipo === "sala_reuniao" + ? "Sala sem nome" + : "Grupo sem nome")} +

+ {#if conversa.naoLidas > 0} + {conversa.naoLidas} + {/if} +
+
+ + {conversa.tipo === "sala_reuniao" + ? "👑 Sala de Reunião" + : "👥 Grupo"} + + {#if conversa.participantesInfo} + + {conversa.participantesInfo.length} participante{conversa + .participantesInfo.length !== 1 + ? "s" + : ""} + + {/if} +
+
+ + {/each} + {:else if !conversas?.data} + +
+ +
+ {:else} + +
+ + + +

+ Nenhuma conversa encontrada +

+

+ Crie um grupo ou sala de reunião para começar +

+
+ {/if} + {/if} +
{#if showNewConversationModal} - (showNewConversationModal = false)} /> + (showNewConversationModal = false)} /> {/if} diff --git a/apps/web/src/lib/components/chat/ChatWidget.svelte b/apps/web/src/lib/components/chat/ChatWidget.svelte index ecda3cf..9180f2b 100644 --- a/apps/web/src/lib/components/chat/ChatWidget.svelte +++ b/apps/web/src/lib/components/chat/ChatWidget.svelte @@ -34,8 +34,8 @@ if (!usuario) return null; // Prioridade: fotoPerfilUrl > avatar > fallback com nome - if (usuario.fotoPerfilUrl) { - return usuario.fotoPerfilUrl; + if (usuario.fotoPerfil) { + return usuario.fotoPerfil; } if (usuario.avatar) { return getAvatarUrl(usuario.avatar); @@ -768,14 +768,14 @@ type="button" class="group fixed border-0 backdrop-blur-xl" style=" - z-index: 99999 !important; - width: 4.5rem; - height: 4.5rem; + z-index: 99999 !important; + width: 4.5rem; + height: 4.5rem; bottom: {bottomPos}; right: {rightPos}; position: fixed !important; background: linear-gradient(135deg, #667eea 0%, #764ba2 50%, #f093fb 100%); - box-shadow: + box-shadow: 0 20px 60px -10px rgba(102, 126, 234, 0.5), 0 10px 30px -5px rgba(118, 75, 162, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.1) inset; @@ -839,7 +839,7 @@ class="absolute -top-1 -right-1 z-20 flex h-8 w-8 items-center justify-center rounded-full text-xs font-black text-white" style=" background: linear-gradient(135deg, #ff416c, #ff4b2b); - box-shadow: + box-shadow: 0 8px 24px -4px rgba(255, 65, 108, 0.6), 0 4px 12px -2px rgba(255, 75, 43, 0.4), 0 0 0 3px rgba(255, 255, 255, 0.3), @@ -883,7 +883,7 @@ position: fixed !important; background: linear-gradient(135deg, rgba(255,255,255,0.95) 0%, rgba(249,250,251,0.98) 100%); border-radius: 24px; - box-shadow: + box-shadow: 0 32px 64px -12px rgba(0, 0, 0, 0.15), 0 16px 32px -8px rgba(0, 0, 0, 0.1), 0 0 0 1px rgba(0, 0, 0, 0.05), diff --git a/apps/web/src/lib/components/chat/ChatWindow.svelte b/apps/web/src/lib/components/chat/ChatWindow.svelte index 14da539..9cecb9d 100644 --- a/apps/web/src/lib/components/chat/ChatWindow.svelte +++ b/apps/web/src/lib/components/chat/ChatWindow.svelte @@ -1,495 +1,545 @@ - +
(showAdminMenu = false)}> + +
e.stopPropagation()} + > + + -
- -
- - + +
+ {#if conversa() && conversa()?.tipo === "individual" && conversa()?.outroUsuario} + + {:else} +
+ {getAvatarConversa()} +
+ {/if} + {#if getStatusConversa()} +
+ +
+ {/if} +
- -
- {#if conversa() && conversa()?.tipo === 'individual' && conversa()?.outroUsuario} - - {:else} -
- {getAvatarConversa()} -
- {/if} - {#if getStatusConversa()} -
- -
- {/if} -
+
+

+ {getNomeConversa()} +

+ {#if getStatusMensagem()} +

+ {getStatusMensagem()} +

+ {:else if getStatusConversa()} +

+ {getStatusConversa() === "online" + ? "Online" + : getStatusConversa() === "ausente" + ? "Ausente" + : getStatusConversa() === "em_reuniao" + ? "Em reunião" + : getStatusConversa() === "externo" + ? "Externo" + : "Offline"} +

+ {:else if conversa() && (conversa()?.tipo === "grupo" || conversa()?.tipo === "sala_reuniao")} +
+

+ {conversa()?.participantesInfo?.length || 0} + {conversa()?.participantesInfo?.length === 1 + ? "participante" + : "participantes"} +

+ {#if conversa()?.participantesInfo && conversa()?.participantesInfo.length > 0} +
+
+ {#each conversa()?.participantesInfo.slice(0, 5) as participante (participante._id)} +
+ {#if participante.fotoPerfilUrl} + {participante.nome} + {:else if participante.avatar} + {participante.nome} + {:else} + {participante.nome} + {/if} +
+ {/each} + {#if conversa()?.participantesInfo.length > 5} +
+ +{conversa()?.participantesInfo.length - 5} +
+ {/if} +
+ {#if conversa()?.tipo === "sala_reuniao" && isAdmin?.data} + • Admin + {/if} +
+ {/if} +
+ {/if} +
-
-

- {getNomeConversa()} -

- {#if getStatusMensagem()} -

- {getStatusMensagem()} -

- {:else if getStatusConversa()} -

- {getStatusConversa() === 'online' - ? 'Online' - : getStatusConversa() === 'ausente' - ? 'Ausente' - : getStatusConversa() === 'em_reuniao' - ? 'Em reunião' - : getStatusConversa() === 'externo' - ? 'Externo' - : 'Offline'} -

- {:else if conversa() && (conversa()?.tipo === 'grupo' || conversa()?.tipo === 'sala_reuniao')} -
-

- {conversa()?.participantesInfo?.length || 0} - {conversa()?.participantesInfo?.length === 1 ? 'participante' : 'participantes'} -

- {#if conversa()?.participantesInfo && conversa()?.participantesInfo.length > 0} -
-
- {#each conversa()?.participantesInfo.slice(0, 5) as participante (participante._id)} -
- {#if participante.fotoPerfilUrl} - {participante.nome} - {:else if participante.avatar} - {participante.nome} - {:else} - {participante.nome} - {/if} -
- {/each} - {#if conversa()?.participantesInfo.length > 5} -
- +{conversa()?.participantesInfo.length - 5} -
- {/if} -
- {#if conversa()?.tipo === 'sala_reuniao' && isAdmin?.data} - • Admin - {/if} -
- {/if} -
- {/if} -
+ +
+ + {#if conversa() && (conversa()?.tipo === "grupo" || conversa()?.tipo === "sala_reuniao")} + + {/if} - -
- - {#if conversa() && (conversa()?.tipo === 'grupo' || conversa()?.tipo === 'sala_reuniao')} - - {/if} + + {#if conversa()?.tipo === "sala_reuniao" && isAdmin?.data} +
+ + {#if showAdminMenu} +
    e.stopPropagation()} + > +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+ {/if} +
+ {/if} - - {#if conversa()?.tipo === 'sala_reuniao' && isAdmin?.data} -
- - {#if showAdminMenu} -
    -
  • - -
  • -
  • - -
  • -
  • - -
  • -
- {/if} -
- {/if} + + +
+
- - -
-
+ +
+ } /> +
- -
- } /> -
- - -
- } /> -
+ +
+ } /> +
{#if showScheduleModal} - } - onClose={() => (showScheduleModal = false)} - /> + } + onClose={() => (showScheduleModal = false)} + /> {/if} -{#if showSalaManager && conversa()?.tipo === 'sala_reuniao'} - } - isAdmin={isAdmin?.data ?? false} - onClose={() => (showSalaManager = false)} - /> +{#if showSalaManager && conversa()?.tipo === "sala_reuniao"} + } + isAdmin={isAdmin?.data ?? false} + onClose={() => (showSalaManager = false)} + /> {/if} -{#if showNotificacaoModal && conversa()?.tipo === 'sala_reuniao' && isAdmin?.data} - e.target === e.currentTarget && (showNotificacaoModal = false)} - > - + + {/if} diff --git a/apps/web/src/lib/components/chat/NewConversationModal.svelte b/apps/web/src/lib/components/chat/NewConversationModal.svelte index 6adb2cc..3489113 100644 --- a/apps/web/src/lib/components/chat/NewConversationModal.svelte +++ b/apps/web/src/lib/components/chat/NewConversationModal.svelte @@ -1,423 +1,454 @@ - - - + + {#if activeTab === "grupo"} +
+ + {#if selectedUsers.length < 2 && activeTab === "grupo"} +

+ Selecione pelo menos 2 participantes +

+ {/if} +
+ {:else if activeTab === "sala_reuniao"} +
+ + {#if selectedUsers.length < 1 && activeTab === "sala_reuniao"} +

+ Selecione pelo menos 1 participante +

+ {/if} +
+ {/if} +
+ diff --git a/apps/web/src/lib/components/chat/SalaReuniaoManager.svelte b/apps/web/src/lib/components/chat/SalaReuniaoManager.svelte index b813bdc..fed2242 100644 --- a/apps/web/src/lib/components/chat/SalaReuniaoManager.svelte +++ b/apps/web/src/lib/components/chat/SalaReuniaoManager.svelte @@ -1,435 +1,487 @@ - e.target === e.currentTarget && onClose()}> - - + +
+ +
+ +
diff --git a/apps/web/src/lib/components/chat/ScheduleMessageModal.svelte b/apps/web/src/lib/components/chat/ScheduleMessageModal.svelte index 8a9363b..0ceddd2 100644 --- a/apps/web/src/lib/components/chat/ScheduleMessageModal.svelte +++ b/apps/web/src/lib/components/chat/ScheduleMessageModal.svelte @@ -1,269 +1,288 @@ - e.target === e.currentTarget && onClose()}> - + + diff --git a/apps/web/src/lib/components/chat/UserAvatar.svelte b/apps/web/src/lib/components/chat/UserAvatar.svelte index 1d880ec..7a09a69 100644 --- a/apps/web/src/lib/components/chat/UserAvatar.svelte +++ b/apps/web/src/lib/components/chat/UserAvatar.svelte @@ -1,36 +1,41 @@
-
- {`Avatar -
+
+ {`Avatar +
+ diff --git a/apps/web/src/lib/components/ti/AlertConfigModal.svelte b/apps/web/src/lib/components/ti/AlertConfigModal.svelte index db33da4..0551e90 100644 --- a/apps/web/src/lib/components/ti/AlertConfigModal.svelte +++ b/apps/web/src/lib/components/ti/AlertConfigModal.svelte @@ -1,481 +1,502 @@ - + + + diff --git a/apps/web/src/routes/(dashboard)/alterar-senha/+page.svelte b/apps/web/src/routes/(dashboard)/alterar-senha/+page.svelte index 11ca82d..fde48a7 100644 --- a/apps/web/src/routes/(dashboard)/alterar-senha/+page.svelte +++ b/apps/web/src/routes/(dashboard)/alterar-senha/+page.svelte @@ -1,495 +1,512 @@ -
- -
-
- - - -

Alterar Senha

-
-

Atualize sua senha de acesso ao sistema

-
+
+ +
+
+ + + +

Alterar Senha

+
+

+ Atualize sua senha de acesso ao sistema +

+
- - + + - - {#if notice} -
- - {#if notice.type === 'success'} - - {:else} - - {/if} - - {notice.message} -
- {/if} + + {#if notice} +
+ + {#if notice.type === "success"} + + {:else} + + {/if} + + {notice.message} +
+ {/if} - -
-
-
- -
- -
- - -
-
+ +
+
+ + +
+ +
+ + +
+
- -
- -
- - -
-
- - Mínimo 8 caracteres, com letras maiúsculas, minúsculas, números e caracteres especiais - -
-
+ +
+ +
+ + +
+
+ + Mínimo 8 caracteres, com letras maiúsculas, minúsculas, números e + caracteres especiais + +
+
- -
- -
- - -
-
+ +
+ +
+ + +
+
- -
- - - -
-

Requisitos de Senha:

-
    -
  • Mínimo de 8 caracteres
  • -
  • Pelo menos uma letra maiúscula (A-Z)
  • -
  • Pelo menos uma letra minúscula (a-z)
  • -
  • Pelo menos um número (0-9)
  • -
  • Pelo menos um caractere especial (!@#$%^&*...)
  • -
-
-
+ +
+ + + +
+

Requisitos de Senha:

+
    +
  • Mínimo de 8 caracteres
  • +
  • Pelo menos uma letra maiúscula (A-Z)
  • +
  • Pelo menos uma letra minúscula (a-z)
  • +
  • Pelo menos um número (0-9)
  • +
  • Pelo menos um caractere especial (!@#$%^&*...)
  • +
+
+
- -
- - -
- -
-
+ +
+ + +
+ +
+
- -
-
-

- - - - Dicas de Segurança -

-
    -
  • ✅ Nunca compartilhe sua senha com ninguém
  • -
  • ✅ Use uma senha única para cada sistema
  • -
  • ✅ Altere sua senha regularmente
  • -
  • ✅ Não use informações pessoais óbvias (nome, data de nascimento, etc.)
  • -
  • ✅ Considere usar um gerenciador de senhas
  • -
-
-
+ +
+
+

+ + + + Dicas de Segurança +

+
    +
  • ✅ Nunca compartilhe sua senha com ninguém
  • +
  • ✅ Use uma senha única para cada sistema
  • +
  • ✅ Altere sua senha regularmente
  • +
  • + ✅ Não use informações pessoais óbvias (nome, data de nascimento, + etc.) +
  • +
  • ✅ Considere usar um gerenciador de senhas
  • +
+
+
diff --git a/apps/web/src/routes/(dashboard)/esqueci-senha/+page.svelte b/apps/web/src/routes/(dashboard)/esqueci-senha/+page.svelte index 9d85216..2cedee5 100644 --- a/apps/web/src/routes/(dashboard)/esqueci-senha/+page.svelte +++ b/apps/web/src/routes/(dashboard)/esqueci-senha/+page.svelte @@ -1,363 +1,264 @@ -
- -
-
- - - -

Esqueci Minha Senha

-
-

Solicite a recuperação da sua senha de acesso

-
+
+ +
+
+ + + +

Esqueci Minha Senha

+
+

+ Solicite a recuperação da sua senha de acesso +

+
- - + + - - {#if notice} -
- - {#if notice.type === 'success'} - - {:else if notice.type === 'error'} - - {:else} - - {/if} - - {notice.message} -
- {/if} + + {#if notice} +
+ + {#if notice.type === "success"} + + {:else if notice.type === "error"} + + {:else} + + {/if} + + {notice.message} +
+ {/if} - {#if !solicitacaoEnviada} - -
-
-
- - - -
-

Como funciona?

-

- Informe sua matrícula e e-mail cadastrados. A equipe de TI receberá sua solicitação e - entrará em contato para resetar sua senha. -

-
-
+ {#if !solicitacaoEnviada} + +
+
+
+ + + +
+

Como funciona?

+

+ Informe sua matrícula e e-mail cadastrados. A equipe de TI receberá sua solicitação e entrará em contato para resetar sua senha. +

+
+
-
- -
- - -
+ + +
+ + +
- -
- - - -
+ +
+ + + +
- -
- - - - - Voltar - - -
-
-
-
- {:else} - -
-
-
- - - -
-

Solicitação Enviada!

-

- Sua solicitação de recuperação de senha foi enviada para a equipe de TI. Você receberá um - contato em breve com as instruções para resetar sua senha. -

-
- - - - - Voltar ao Dashboard - - -
-
-
- {/if} + +
+ + + + + Voltar + + +
+ +
+
+ {:else} + +
+
+
+ + + +
+

Solicitação Enviada!

+

+ Sua solicitação de recuperação de senha foi enviada para a equipe de TI. + Você receberá um contato em breve com as instruções para resetar sua senha. +

+
+ + + + + Voltar ao Dashboard + + +
+
+
+ {/if} - -
-
-

- - - - Precisa de Ajuda? -

-

- Se você não conseguir recuperar sua senha ou tiver problemas com o sistema, entre em contato - diretamente com a equipe de TI: -

-
-
- - - - ti@sgse.pe.gov.br -
-
- - - - (81) 3183-8000 -
-
-
-
+ +
+
+

+ + + + Precisa de Ajuda? +

+

+ Se você não conseguir recuperar sua senha ou tiver problemas com o sistema, entre em contato diretamente com a equipe de TI: +

+
+
+ + + + ti@sgse.pe.gov.br +
+
+ + + + (81) 3183-8000 +
+
+
+
+ diff --git a/apps/web/src/routes/(dashboard)/gestao-pessoas/gestao-ausencias/+page.svelte b/apps/web/src/routes/(dashboard)/gestao-pessoas/gestao-ausencias/+page.svelte index 774da20..9f54d61 100644 --- a/apps/web/src/routes/(dashboard)/gestao-pessoas/gestao-ausencias/+page.svelte +++ b/apps/web/src/routes/(dashboard)/gestao-pessoas/gestao-ausencias/+page.svelte @@ -1,407 +1,419 @@ -
- - +
+ + - -
-
-
-
- - - -
-
-

Gestão de Ausências

-

Visão geral de todas as solicitações de ausências

-
-
- -
-
+ +
+
+
+
+ + + +
+
+

Gestão de Ausências

+

+ Visão geral de todas as solicitações de ausências +

+
+
+ +
+
- -
-
-
- - - -
-
Total
-
{stats.total}
-
Solicitações
-
+ +
+
+
+ + + +
+
Total
+
{stats.total}
+
Solicitações
+
-
-
- - - -
-
Pendentes
-
{stats.aguardando}
-
Aguardando
-
+
+
+ + + +
+
Pendentes
+
{stats.aguardando}
+
Aguardando
+
-
-
- - - -
-
Aprovadas
-
{stats.aprovadas}
-
Deferidas
-
+
+
+ + + +
+
Aprovadas
+
{stats.aprovadas}
+
Deferidas
+
-
-
- - - -
-
Reprovadas
-
{stats.reprovadas}
-
Indeferidas
-
-
+
+
+ + + +
+
Reprovadas
+
{stats.reprovadas}
+
Indeferidas
+
+
- -
-
-

Filtros

-
-
- - -
-
-
-
+ +
+
+

Filtros

+
+
+ + +
+
+
+
- -
-
-

- Todas as Solicitações ({ausenciasFiltradas.length}) -

+ +
+
+

+ Todas as Solicitações ({ausenciasFiltradas.length}) +

- {#if ausenciasFiltradas.length === 0} -
- - - - Nenhuma solicitação encontrada com os filtros aplicados. -
- {:else} -
- - - - - - - - - - - - - - - {#each ausenciasFiltradas as ausencia} - - - - - - - - - - - {/each} - -
FuncionárioTimePeríodoDiasMotivoStatusSolicitado emAções
- {ausencia.funcionario?.nome || 'N/A'} - - {#if ausencia.time} -
- {ausencia.time.nome} -
- {:else} - Sem time - {/if} -
- {new Date(ausencia.dataInicio).toLocaleDateString('pt-BR')} até{' '} - {new Date(ausencia.dataFim).toLocaleDateString('pt-BR')} - - {calcularDias(ausencia.dataInicio, ausencia.dataFim)} dias - - {ausencia.motivo} - -
- {getStatusTexto(ausencia.status)} -
-
- {new Date(ausencia.criadoEm).toLocaleDateString('pt-BR')} - - {#if ausencia.status === 'aguardando_aprovacao'} - - {:else} - - {/if} -
-
- {/if} -
-
+ {#if ausenciasFiltradas.length === 0} +
+ + + + Nenhuma solicitação encontrada com os filtros aplicados. +
+ {:else} +
+ + + + + + + + + + + + + + + {#each ausenciasFiltradas as ausencia} + + + + + + + + + + + {/each} + +
FuncionárioTimePeríodoDiasMotivoStatusSolicitado emAções
+ {ausencia.funcionario?.nome || "N/A"} + + {#if ausencia.time} +
+ {ausencia.time.nome} +
+ {:else} + Sem time + {/if} +
+ {new Date(ausencia.dataInicio).toLocaleDateString("pt-BR")} até{" "} + {new Date(ausencia.dataFim).toLocaleDateString("pt-BR")} + + {calcularDias(ausencia.dataInicio, ausencia.dataFim)} dias + + {ausencia.motivo} + +
+ {getStatusTexto(ausencia.status)} +
+
+ {new Date(ausencia.criadoEm).toLocaleDateString("pt-BR")} + + {#if ausencia.status === "aguardando_aprovacao"} + + {:else} + + {/if} +
+
+ {/if} +
+
{#if solicitacaoSelecionada && currentUser.data} - {#await client.query( api.ausencias.obterDetalhes, { solicitacaoId: solicitacaoSelecionada } ) then detalhes} - {#if detalhes} - - - - - {/if} - {/await} + {#await client.query(api.ausencias.obterDetalhes, { + solicitacaoId: solicitacaoSelecionada, + }) then detalhes} + {#if detalhes} + + + + + {/if} + {/await} {/if} + diff --git a/apps/web/src/routes/(dashboard)/perfil/+page.svelte b/apps/web/src/routes/(dashboard)/perfil/+page.svelte index 9028496..fddfd59 100644 --- a/apps/web/src/routes/(dashboard)/perfil/+page.svelte +++ b/apps/web/src/routes/(dashboard)/perfil/+page.svelte @@ -9,7 +9,6 @@ import { generateAvatarGallery } from '$lib/utils/avatars'; import type { Id } from '@sgse-app/backend/convex/_generated/dataModel'; import { X, Calendar } from 'lucide-svelte'; - import type { FunctionReturnType } from 'convex/server'; const client = useConvexClient(); const currentUser = useQuery(api.auth.getCurrentUser, {}); @@ -29,6 +28,11 @@ let avatarSelecionado = $state(''); let mostrarBotaoCamera = $state(false); + // Estados locais para atualização imediata + let fotoPerfilLocal = $state(null); + let avatarLocal = $state(null); + let perfilCarregado = $state(false); + // Estados para Minhas Férias let mostrarWizard = $state(false); let filtroStatusFerias = $state('todos'); @@ -43,11 +47,39 @@ // Galeria de avatares (30 avatares profissionais 3D realistas) const avatarGallery = generateAvatarGallery(30); + // Carregar perfil ao montar a página para garantir dados atualizados (apenas uma vez) + $effect(() => { + if (currentUser?.data && !perfilCarregado) { + perfilCarregado = true; + } + }); + + // Sincronizar com currentUser - atualiza automaticamente quando o usuário muda + $effect(() => { + const usuario = currentUser?.data; + if (usuario) { + // Atualizar foto de perfil (pode ser null ou string) + fotoPerfilLocal = usuario.fotoPerfil ?? null; + // Atualizar avatar (pode ser undefined ou string) + avatarLocal = usuario.avatar ?? null; + } else { + // Se não há usuário, limpar estados locais + fotoPerfilLocal = null; + avatarLocal = null; + perfilCarregado = false; // Reset para permitir recarregar quando houver usuário novamente + } + }); + // FuncionarioId disponível diretamente do usuário atual const funcionarioIdDisponivel = $derived(currentUser?.data?.funcionarioId ?? null); - const funcionarioQuery = useQuery(api.funcionarios.getCurrent, () => - funcionarioIdDisponivel ? {} : 'skip' + // Queries + const funcionarioQuery = $derived( + currentUser?.data?.funcionarioId + ? useQuery(api.funcionarios.getById, { + id: currentUser.data.funcionarioId + }) + : { data: null } ); const solicitacoesSubordinadosQuery = $derived( @@ -157,9 +189,9 @@ solicitacaoSelecionada = null; } - async function selecionarSolicitacao(solicitacaoId: Id<'solicitacoesFerias'>) { + async function selecionarSolicitacao(solicitacaoId: string) { const detalhes = await client.query(api.ferias.obterDetalhes, { - solicitacaoId: solicitacaoId + solicitacaoId: solicitacaoId as Id<'solicitacoesFerias'> }); solicitacaoSelecionada = detalhes; } @@ -206,6 +238,14 @@ erroUpload = ''; try { + // 1. Criar preview local IMEDIATAMENTE para feedback visual + const reader = new FileReader(); + reader.onload = (e) => { + fotoPerfilLocal = e.target?.result as string; + avatarLocal = null; + }; + reader.readAsDataURL(file); + // 2. Gerar URL de upload const uploadUrl = await client.mutation(api.usuarios.uploadFotoPerfil, {}); @@ -228,6 +268,15 @@ avatar: undefined // Remove avatar se colocar foto }); + // 5. Aguardar um pouco para garantir que o backend processou + await new Promise((resolve) => setTimeout(resolve, 300)); + + // 6. Atualizar localmente com a URL retornada pelo backend (ou pelo currentUser) + if (currentUser?.data?.fotoPerfil) { + fotoPerfilLocal = currentUser.data.fotoPerfil; + avatarLocal = null; + } + // 8. Limpar o input para permitir novo upload input.value = ''; @@ -248,8 +297,11 @@ document.body.appendChild(toast); setTimeout(() => toast.remove(), 3000); } catch (e: unknown) { - const error = e as Error; - erroUpload = error.message || 'Erro ao fazer upload da foto'; + const errorMessage = e instanceof Error ? e.message : String(e); + erroUpload = errorMessage || 'Erro ao fazer upload da foto'; + // Reverter mudança local se houver erro + fotoPerfilLocal = currentUser?.data?.fotoPerfil || null; + avatarLocal = currentUser?.data?.avatar || null; } finally { uploadandoFoto = false; } @@ -260,6 +312,10 @@ erroUpload = ''; try { + // 1. Atualizar localmente IMEDIATAMENTE para feedback visual instantâneo + avatarLocal = avatarUrl; + fotoPerfilLocal = null; + // 2. Salvar avatar selecionado no backend await client.mutation(api.usuarios.atualizarPerfil, { avatar: avatarUrl, @@ -269,6 +325,12 @@ // 3. Aguardar um pouco para garantir que o backend processou await new Promise((resolve) => setTimeout(resolve, 300)); + // 4. Garantir que os estados locais estão sincronizados com o usuário atual + if (currentUser?.data?.avatar) { + avatarLocal = currentUser.data.avatar; + fotoPerfilLocal = null; + } + // 6. Fechar modal após sucesso mostrarModalFoto = false; @@ -286,8 +348,11 @@ document.body.appendChild(toast); setTimeout(() => toast.remove(), 3000); } catch (e: unknown) { - const error = e as Error; - erroUpload = error.message || 'Erro ao salvar avatar'; + const errorMessage = e instanceof Error ? e.message : String(e); + erroUpload = errorMessage || 'Erro ao salvar avatar'; + // Reverter mudança local se houver erro + avatarLocal = currentUser?.data?.avatar || null; + fotoPerfilLocal = currentUser?.data?.fotoPerfil || null; } finally { uploadandoFoto = false; } @@ -334,14 +399,10 @@
- {#if currentUser.data?.fotoPerfilUrl} - Foto de perfil - {:else if currentUser.data?.avatar} - Foto de perfil + {#if fotoPerfilLocal} + Foto de perfil + {:else if avatarLocal} + Avatar {:else}
selecionarSolicitacao(solicitacao._id)} > (solicitacaoAusenciaAprovar = ausencia._id)} > - {#if currentUser.data?.fotoPerfilUrl} - Foto atual + {#if fotoPerfilLocal} + Foto atual + {:else if avatarLocal} + Avatar atual {:else}
-
-
+ +
+
+
+
+ + + +
+
+

Atestados & Licenças

+

+ Registro de atestados médicos e licenças +

+
+
+ +
+
- -
- - - - - -
+ +
+ + + + + +
- - {#if abaAtiva === 'dashboard'} - - - {#if statsQuery?.data} -
-
-
- - - -
-
Atestados Ativos
-
- {statsQuery.data.totalAtestadosAtivos} -
-
+ + {#if abaAtiva === "dashboard"} + + + {#if statsQuery?.data} +
+
+
+ + + +
+
Atestados Ativos
+
+ {statsQuery.data.totalAtestadosAtivos} +
+
-
-
- - - -
-
Licenças Ativas
-
- {statsQuery.data.totalLicencasAtivas} -
-
+
+
+ + + +
+
Licenças Ativas
+
+ {statsQuery.data.totalLicencasAtivas} +
+
-
-
- - - -
-
Afastados Hoje
-
- {statsQuery.data.funcionariosAfastadosHoje} -
-
+
+
+ + + +
+
Afastados Hoje
+
+ {statsQuery.data.funcionariosAfastadosHoje} +
+
-
-
- - - -
-
Dias no Mês
-
- {statsQuery.data.totalDiasAfastamentoMes} -
-
-
- {/if} +
+
+ + + +
+
Dias no Mês
+
+ {statsQuery.data.totalDiasAfastamentoMes} +
+
+
+ {/if} - -
-
-

Filtros

-
-
- -
+ +
+
+

Filtros

+
+
+ +
-
- -
+
+ +
-
- -
+
+ +
-
- -
+
+ +
-
- -
-
-
-
+
+ +
+
+
+
- - {#if eventosQuery?.data} - - {/if} + + {#if eventosQuery?.data} + + {/if} - - {#if graficosQuery?.data} - {@const dados = graficosQuery.data.totalDiasPorTipo} - {@const maxDias = Math.max(...dados.map((d) => d.dias), 1)} - {@const chartWidth = 800} - {@const chartHeight = 350} - {@const padding = { top: 20, right: 40, bottom: 80, left: 70 }} - {@const barWidth = (chartWidth - padding.left - padding.right) / dados.length - 10} - {@const innerHeight = chartHeight - padding.top - padding.bottom} - {@const tendencias = graficosQuery.data.tendenciasMensais} - {@const tipos = [ - 'atestado_medico', - 'declaracao_comparecimento', - 'maternidade', - 'paternidade', - 'ferias' - ]} - {@const cores = ['#ef4444', '#f97316', '#ec4899', '#3b82f6', '#10b981']} - {@const nomes = ['Atestado Médico', 'Declaração', 'Maternidade', 'Paternidade', 'Férias']} - {@const maxValor = Math.max( - ...tendencias.flatMap((t) => tipos.map((tipo) => t[tipo as keyof typeof t] as number)), - 1 - )} - {@const chartWidth2 = 900} - {@const chartHeight2 = 400} - {@const padding2 = { top: 20, right: 40, bottom: 80, left: 70 }} - {@const innerWidth = chartWidth2 - padding2.left - padding2.right} - {@const innerHeight2 = chartHeight2 - padding2.top - padding2.bottom} - -
-
-

Total de Dias por Tipo

-
- - - {#each [0, 1, 2, 3, 4, 5] as t} - {@const val = Math.round((maxDias / 5) * t)} - {@const y = chartHeight - padding.bottom - (val / maxDias) * innerHeight} - - - {val} - - {/each} + + {#if graficosQuery?.data} + {@const dados = graficosQuery.data.totalDiasPorTipo} + {@const maxDias = Math.max(...dados.map((d) => d.dias), 1)} + {@const chartWidth = 800} + {@const chartHeight = 350} + {@const padding = { top: 20, right: 40, bottom: 80, left: 70 }} + {@const barWidth = (chartWidth - padding.left - padding.right) / dados.length - 10} + {@const innerHeight = chartHeight - padding.top - padding.bottom} + {@const tendencias = graficosQuery.data.tendenciasMensais} + {@const tipos = ["atestado_medico", "declaracao_comparecimento", "maternidade", "paternidade", "ferias"]} + {@const cores = ["#ef4444", "#f97316", "#ec4899", "#3b82f6", "#10b981"]} + {@const nomes = ["Atestado Médico", "Declaração", "Maternidade", "Paternidade", "Férias"]} + {@const maxValor = Math.max( + ...tendencias.flatMap((t) => + tipos.map((tipo) => t[tipo as keyof typeof t] as number) + ), + 1 + )} + {@const chartWidth2 = 900} + {@const chartHeight2 = 400} + {@const padding2 = { top: 20, right: 40, bottom: 80, left: 70 }} + {@const innerWidth = chartWidth2 - padding2.left - padding2.right} + {@const innerHeight2 = chartHeight2 - padding2.top - padding2.bottom} + +
+
+

Total de Dias por Tipo

+
- - - + + + {#each [0, 1, 2, 3, 4, 5] as t} + {@const val = Math.round((maxDias / 5) * t)} + {@const y = chartHeight - padding.bottom - (val / maxDias) * innerHeight} + + + {val} + + {/each} - - {#each dados as item, i} - {@const x = padding.left + i * (barWidth + 10) + 5} - {@const height = (item.dias / maxDias) * innerHeight} - {@const y = chartHeight - padding.bottom - height} - {@const colors = ['#ef4444', '#f97316', '#ec4899', '#3b82f6', '#10b981']} + + + - - - - - - - + + {#each dados as item, i} + {@const x = padding.left + i * (barWidth + 10) + 5} + {@const height = (item.dias / maxDias) * innerHeight} + {@const y = chartHeight - padding.bottom - height} + {@const colors = ["#ef4444", "#f97316", "#ec4899", "#3b82f6", "#10b981"]} - - + + + + + + + - - {#if item.dias > 0} - - {item.dias} - - {/if} + + - - -
- - {item.tipo} - -
-
- {/each} -
-
-
-
+ + {#if item.dias > 0} + + {item.dias} + + {/if} - -
-
-

Tendências Mensais (Últimos 6 Meses)

-
- - - {#each [0, 1, 2, 3, 4, 5] as t} - {@const val = Math.round((maxValor / 5) * t)} - {@const y = chartHeight2 - padding2.bottom - (val / maxValor) * innerHeight2} - - - {val} - - {/each} + + +
+ + {item.tipo} + +
+
+ {/each} +
+
+
+
- - - + +
+
+

Tendências Mensais (Últimos 6 Meses)

+
+ + + {#each [0, 1, 2, 3, 4, 5] as t} + {@const val = Math.round((maxValor / 5) * t)} + {@const y = chartHeight2 - padding2.bottom - (val / maxValor) * innerHeight2} + + + {val} + + {/each} - - {#each tipos as tipo, tipoIdx} - {@const cor = cores[tipoIdx]} + + + - - - - - - - + + {#each tipos as tipo, tipoIdx} + {@const cor = cores[tipoIdx]} + + + + + + + + - {@const pontos = tendencias.map((t, i) => { - const x = padding2.left + (i / (tendencias.length - 1 || 1)) * innerWidth; - const valor = t[tipo as keyof typeof t] as number; - const y = chartHeight2 - padding2.bottom - (valor / maxValor) * innerHeight2; - return { x, y, valor }; - })} + {@const pontos = tendencias.map((t, i) => { + const x = padding2.left + (i / (tendencias.length - 1 || 1)) * innerWidth; + const valor = t[tipo as keyof typeof t] as number; + const y = chartHeight2 - padding2.bottom - (valor / maxValor) * innerHeight2; + return { x, y, valor }; + })} - - {#if pontos.length > 0} - {@const pathArea = - `M ${pontos[0].x} ${chartHeight2 - padding2.bottom} ` + - pontos.map((p) => `L ${p.x} ${p.y}`).join(' ') + - ` L ${pontos[pontos.length - 1].x} ${chartHeight2 - padding2.bottom} Z`} - - {/if} + + {#if pontos.length > 0} + {@const pathArea = `M ${pontos[0].x} ${chartHeight2 - padding2.bottom} ` + pontos.map(p => `L ${p.x} ${p.y}`).join(' ') + ` L ${pontos[pontos.length - 1].x} ${chartHeight2 - padding2.bottom} Z`} + + {/if} - - {#if pontos.length > 1} - `${p.x},${p.y}`).join(' ')} - fill="none" - stroke={cor} - stroke-width="3" - stroke-linecap="round" - stroke-linejoin="round" - /> - {/if} + + {#if pontos.length > 1} + `${p.x},${p.y}`).join(' ')} + fill="none" + stroke={cor} + stroke-width="3" + stroke-linecap="round" + stroke-linejoin="round" + /> + {/if} - - {#each pontos as ponto, pontoIdx} - - - {nomes[tipoIdx]}: {ponto.valor} dias em {tendencias[pontoIdx]?.mes || - ''} - {/each} - {/each} + + {#each pontos as ponto, pontoIdx} + + + {nomes[tipoIdx]}: {ponto.valor} dias em {tendencias[pontoIdx]?.mes || ""} + {/each} + {/each} - - {#each tendencias as t, i} - {@const x = padding2.left + (i / (tendencias.length - 1 || 1)) * innerWidth} - -
- - {t.mes} - -
-
- {/each} -
+ + {#each tendencias as t, i} + {@const x = padding2.left + (i / (tendencias.length - 1 || 1)) * innerWidth} + +
+ + {t.mes} + +
+
+ {/each} + - -
- {#each tipos as tipo, idx} -
-
- {nomes[idx]} -
- {/each} -
-
-
-
+ +
+ {#each tipos as tipo, idx} +
+
+ {nomes[idx]} +
+ {/each} +
+
+
+
- -
-
-

Funcionários Atualmente Afastados

- {#if graficosQuery.data.funcionariosAfastados.length > 0} -
- - - - - - - - - - - {#each graficosQuery.data.funcionariosAfastados as item} - - - - - - - {/each} - -
FuncionárioTipoData InícioData Fim
{item.funcionarioNome} - - {item.tipo === 'atestado_medico' - ? 'Atestado Médico' - : item.tipo === 'declaracao_comparecimento' - ? 'Declaração' - : item.tipo === 'maternidade' - ? 'Licença Maternidade' - : item.tipo === 'paternidade' - ? 'Licença Paternidade' - : item.tipo} - - {formatarData(item.dataInicio)}{formatarData(item.dataFim)}
-
- {:else} -
- Nenhum funcionário afastado no momento -
- {/if} -
-
- {/if} + +
+
+

Funcionários Atualmente Afastados

+ {#if graficosQuery.data.funcionariosAfastados.length > 0} +
+ + + + + + + + + + + {#each graficosQuery.data.funcionariosAfastados as item} + + + + + + + {/each} + +
FuncionárioTipoData InícioData Fim
{item.funcionarioNome} + + {item.tipo === "atestado_medico" + ? "Atestado Médico" + : item.tipo === "declaracao_comparecimento" + ? "Declaração" + : item.tipo === "maternidade" + ? "Licença Maternidade" + : item.tipo === "paternidade" + ? "Licença Paternidade" + : item.tipo} + + {formatarData(item.dataInicio)}{formatarData(item.dataFim)}
+
+ {:else} +
+ Nenhum funcionário afastado no momento +
+ {/if} +
+
+ {/if} - -
-
-

Registros

-
- - - - - - - - - - - - - - {#each registrosFiltrados.atestados as atestado} - - - - - - - - - - {/each} - {#each registrosFiltrados.licencas as licenca} - - - - - - - - - - {/each} - -
FuncionárioTipoData InícioData FimDiasStatusAções
{atestado.funcionario?.nome || '-'} - - {atestado.tipo === 'atestado_medico' ? 'Atestado Médico' : 'Declaração'} - - {formatarData(atestado.dataInicio)}{formatarData(atestado.dataFim)}{atestado.dias} - - {atestado.status === 'ativo' ? 'Ativo' : 'Finalizado'} - - -
- {#if atestado.documentoId} - - {/if} - -
-
{licenca.funcionario?.nome || '-'} - - Licença{' '} - {licenca.tipo === 'maternidade' ? 'Maternidade' : 'Paternidade'} - {licenca.ehProrrogacao ? ' (Prorrogação)' : ''} - - {formatarData(licenca.dataInicio)}{formatarData(licenca.dataFim)}{licenca.dias} - - {licenca.status === 'ativo' ? 'Ativo' : 'Finalizado'} - - -
- {#if licenca.documentoId} - - {/if} - -
-
- {#if registrosFiltrados.atestados.length === 0 && registrosFiltrados.licencas.length === 0} -
Nenhum registro encontrado
- {/if} -
-
-
- {:else if abaAtiva === 'atestado'} - -
-
-

Registrar Atestado Médico

+ +
+
+

Registros

+
+ + + + + + + + + + + + + + {#each registrosFiltrados.atestados as atestado} + + + + + + + + + + {/each} + {#each registrosFiltrados.licencas as licenca} + + + + + + + + + + {/each} + +
FuncionárioTipoData InícioData FimDiasStatusAções
{atestado.funcionario?.nome || "-"} + + {atestado.tipo === "atestado_medico" + ? "Atestado Médico" + : "Declaração"} + + {formatarData(atestado.dataInicio)}{formatarData(atestado.dataFim)}{atestado.dias} + + {atestado.status === "ativo" ? "Ativo" : "Finalizado"} + + +
+ {#if atestado.documentoId} + + {/if} + +
+
{licenca.funcionario?.nome || "-"} + + Licença{" "} + {licenca.tipo === "maternidade" + ? "Maternidade" + : "Paternidade"} + {licenca.ehProrrogacao ? " (Prorrogação)" : ""} + + {formatarData(licenca.dataInicio)}{formatarData(licenca.dataFim)}{licenca.dias} + + {licenca.status === "ativo" ? "Ativo" : "Finalizado"} + + +
+ {#if licenca.documentoId} + + {/if} + +
+
+ {#if registrosFiltrados.atestados.length === 0 && registrosFiltrados.licencas.length === 0} +
+ Nenhum registro encontrado +
+ {/if} +
+
+
+ {:else if abaAtiva === "atestado"} + +
+
+

Registrar Atestado Médico

-
- +
+ -
-
- Data Início * -
- -
+
+
+ Data Início * +
+ +
-
-
- Data Fim * -
- -
+
+
+ Data Fim * +
+ +
-
-
- CID * -
- -
+
+
+ CID * +
+ +
-
- { - atestadoMedico.documentoId = await handleDocumentoUpload(file); - }} - onRemove={async () => { - atestadoMedico.documentoId = undefined; - }} - /> -
+
+ { + atestadoMedico.documentoId = await handleDocumentoUpload( + file + ); + }} + onRemove={async () => { + atestadoMedico.documentoId = undefined; + }} + /> +
-
-
- Observações -
- -
-
+
+
+ Observações +
+ +
+
-
- - -
-
-
- {:else if abaAtiva === 'declaracao'} - -
-
-

Registrar Declaração de Comparecimento

+
+ + +
+
+
+ {:else if abaAtiva === "declaracao"} + +
+
+

Registrar Declaração de Comparecimento

-
- +
+ -
-
- Data Início * -
- -
+
+
+ Data Início * +
+ +
-
-
- Data Fim * -
- -
+
+
+ Data Fim * +
+ +
-
- { - declaracao.documentoId = await handleDocumentoUpload(file); - }} - onRemove={async () => { - declaracao.documentoId = undefined; - }} - /> -
+
+ { + declaracao.documentoId = await handleDocumentoUpload(file); + }} + onRemove={async () => { + declaracao.documentoId = undefined; + }} + /> +
-
-
- Observações -
- -
-
+
+
+ Observações +
+ +
+
-
- - -
-
-
- {:else if abaAtiva === 'maternidade'} - -
-
-

Registrar Licença Maternidade

+
+ + +
+
+
+ {:else if abaAtiva === "maternidade"} + +
+
+

Registrar Licença Maternidade

-
- +
+ -
-
- Data Início * -
- -
+
+
+ Data Início * +
+ +
-
-
- Data Fim * -
- -
- Calculado automaticamente (120 dias) -
-
+
+
+ Data Fim * +
+ +
+ Calculado automaticamente (120 dias) +
+
-
- -
+
+ +
- {#if licencaMaternidade.ehProrrogacao} -
-
- Licença Original * -
- -
- {/if} + {#if licencaMaternidade.ehProrrogacao} +
+
+ Licença Original * +
+ +
+ {/if} -
- { - licencaMaternidade.documentoId = await handleDocumentoUpload(file); - }} - onRemove={async () => { - licencaMaternidade.documentoId = undefined; - }} - /> -
+
+ { + licencaMaternidade.documentoId = await handleDocumentoUpload( + file + ); + }} + onRemove={async () => { + licencaMaternidade.documentoId = undefined; + }} + /> +
-
-
- Observações -
- -
-
+
+
+ Observações +
+ +
+
-
- - -
-
-
- {:else if abaAtiva === 'paternidade'} - -
-
-

Registrar Licença Paternidade

+
+ + +
+
+
+ {:else if abaAtiva === "paternidade"} + +
+
+

Registrar Licença Paternidade

-
- +
+ -
-
- Data Início * -
- -
+
+
+ Data Início * +
+ +
-
-
- Data Fim * -
- -
- Calculado automaticamente (20 dias) -
-
+
+
+ Data Fim * +
+ +
+ Calculado automaticamente (20 dias) +
+
-
- { - licencaPaternidade.documentoId = await handleDocumentoUpload(file); - }} - onRemove={async () => { - licencaPaternidade.documentoId = undefined; - }} - /> -
+
+ { + licencaPaternidade.documentoId = await handleDocumentoUpload( + file + ); + }} + onRemove={async () => { + licencaPaternidade.documentoId = undefined; + }} + /> +
-
-
- Observações -
- -
-
+
+
+ Observações +
+ +
+
-
- - -
-
-
- {/if} +
+ + +
+
+
+ {/if}
{ - erroModal.aberto = false; - }} + bind:open={erroModal.aberto} + title={erroModal.titulo} + message={erroModal.mensagem} + details={erroModal.detalhes} + onClose={() => { + erroModal.aberto = false; + }} /> + diff --git a/apps/web/src/routes/(dashboard)/recursos-humanos/ausencias/+page.svelte b/apps/web/src/routes/(dashboard)/recursos-humanos/ausencias/+page.svelte index 829ff89..cfd5744 100644 --- a/apps/web/src/routes/(dashboard)/recursos-humanos/ausencias/+page.svelte +++ b/apps/web/src/routes/(dashboard)/recursos-humanos/ausencias/+page.svelte @@ -1,405 +1,426 @@ -
- - +
+ + - -
-
-
-
- - - -
-
-

Dashboard de Ausências

-

Visão geral de todas as solicitações de ausências

-
-
- -
-
+ +
+
+
+
+ + + +
+
+

+ Dashboard de Ausências +

+

+ Visão geral de todas as solicitações de ausências +

+
+
+ +
+
- -
-
-
- - - -
-
Total
-
{stats.total}
-
Solicitações
-
+ +
+
+
+ + + +
+
Total
+
{stats.total}
+
Solicitações
+
-
-
- - - -
-
Pendentes
-
{stats.aguardando}
-
Aguardando
-
+
+
+ + + +
+
Pendentes
+
{stats.aguardando}
+
Aguardando
+
-
-
- - - -
-
Aprovadas
-
{stats.aprovadas}
-
Deferidas
-
+
+
+ + + +
+
Aprovadas
+
{stats.aprovadas}
+
Deferidas
+
-
-
- - - -
-
Reprovadas
-
{stats.reprovadas}
-
Indeferidas
-
-
+
+
+ + + +
+
Reprovadas
+
{stats.reprovadas}
+
Indeferidas
+
+
- -
-
-

Filtros

-
-
- - -
-
-
-
+ +
+
+

Filtros

+
+
+ + +
+
+
+
- -
-
-

- Todas as Solicitações ({ausenciasFiltradas.length}) -

+ +
+
+

+ Todas as Solicitações ({ausenciasFiltradas.length}) +

- {#if ausenciasFiltradas.length === 0} -
- - - - Nenhuma solicitação encontrada com os filtros aplicados. -
- {:else} -
- - - - - - - - - - - - - - - {#each ausenciasFiltradas as ausencia} - - - - - - - - - - - {/each} - -
FuncionárioTimePeríodoDiasMotivoStatusSolicitado emAções
- {ausencia.funcionario?.nome || 'N/A'} - - {#if ausencia.time} -
- {ausencia.time.nome} -
- {:else} - Sem time - {/if} -
- {new Date(ausencia.dataInicio).toLocaleDateString('pt-BR')} até{' '} - {new Date(ausencia.dataFim).toLocaleDateString('pt-BR')} - - {calcularDias(ausencia.dataInicio, ausencia.dataFim)} dias - - {ausencia.motivo} - -
- {getStatusTexto(ausencia.status)} -
-
- {new Date(ausencia.criadoEm).toLocaleDateString('pt-BR')} - - {#if ausencia.status === 'aguardando_aprovacao'} - - {:else} - - {/if} -
-
- {/if} -
-
+ {#if ausenciasFiltradas.length === 0} +
+ + + + Nenhuma solicitação encontrada com os filtros aplicados. +
+ {:else} +
+ + + + + + + + + + + + + + + {#each ausenciasFiltradas as ausencia} + + + + + + + + + + + {/each} + +
FuncionárioTimePeríodoDiasMotivoStatusSolicitado emAções
+ {ausencia.funcionario?.nome || "N/A"} + + {#if ausencia.time} +
+ {ausencia.time.nome} +
+ {:else} + Sem time + {/if} +
+ {new Date(ausencia.dataInicio).toLocaleDateString("pt-BR")} até{" "} + {new Date(ausencia.dataFim).toLocaleDateString("pt-BR")} + + {calcularDias(ausencia.dataInicio, ausencia.dataFim)} dias + + {ausencia.motivo} + +
+ {getStatusTexto(ausencia.status)} +
+
+ {new Date(ausencia.criadoEm).toLocaleDateString("pt-BR")} + + {#if ausencia.status === "aguardando_aprovacao"} + + {:else} + + {/if} +
+
+ {/if} +
+
{#if solicitacaoSelecionada && currentUser.data} - {#await client.query( api.ausencias.obterDetalhes, { solicitacaoId: solicitacaoSelecionada } ) then detalhes} - {#if detalhes} - - - - - {/if} - {/await} + {#await client.query( api.ausencias.obterDetalhes, { solicitacaoId: solicitacaoSelecionada }, ) then detalhes} + {#if detalhes} + + + + + {/if} + {/await} {/if} diff --git a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/+page.svelte b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/+page.svelte index 97abb91..54a14f0 100644 --- a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/+page.svelte +++ b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/+page.svelte @@ -1,310 +1,236 @@
- - + + - -
-
-
-
- - - -
-
-

Funcionários Cadastrados

-

Gerencie os funcionários da secretaria

-
-
- -
-
+ +
+
+
+
+ + + +
+
+

Funcionários Cadastrados

+

Gerencie os funcionários da secretaria

+
+
+ +
+
- -
-
-

- - - - Filtros de Pesquisa -

-
-
- - -
-
- - -
-
- - -
-
- - -
-
- {#if filtroNome || filtroCPF || filtroMatricula || filtroTipo} -
- -
- {/if} -
-
+ +
+
+

+ + + + Filtros de Pesquisa +

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ {#if filtroNome || filtroCPF || filtroMatricula || filtroTipo} +
+ +
+ {/if} +
+
- -
-
-
-
- - - - - - - - - - - - - - {#each filtered as f} - - - - - - - - - - {/each} - -
NomeCPFMatrículaTipoCidadeUFAções
{f.nome}{f.cpf}{f.matricula}{f.simboloTipo}{f.cidade}{f.uf} - -
-
-
-
-
+ +
+
+
+
+ + + + + + + + + + + + + + {#each filtered as f} + + + + + + + + + + {/each} + +
NomeCPFMatrículaTipoCidadeUFAções
{f.nome}{f.cpf}{f.matricula}{f.simboloTipo}{f.cidade}{f.uf} + +
+
+
+
+
- -
- Exibindo {filtered.length} de {list.length} funcionário(s) -
+ +
+ Exibindo {filtered.length} de {list.length} funcionário(s) +
- - {#if funcionarioParaImprimir} - (funcionarioParaImprimir = null)} - /> - {/if} + + {#if funcionarioParaImprimir} + funcionarioParaImprimir = null} + /> + {/if}
diff --git a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/+page.svelte b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/+page.svelte index 29d5c2b..4b98e09 100644 --- a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/+page.svelte +++ b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/+page.svelte @@ -1,23 +1,23 @@ {#if loading} -
- -
+
+ +
{:else if funcionario} -
- - +
+ + - -
-
-
-
- - - -
-
-

{funcionario.nome}

-

- Matrícula: {funcionario.matricula} -

-
-
+ +
+
+
+
+ + + +
+
+

{funcionario.nome}

+

+ Matrícula: {funcionario.matricula} +

+
+
- - {#if simbolo} -
-
-

- - - - Dados Financeiros -

-
-
-
Símbolo
-
{simbolo.nome}
-
- {simbolo.tipo === 'cargo_comissionado' - ? 'Cargo Comissionado' - : 'Função Gratificada'} -
-
- {#if funcionario.simboloTipo === 'cargo_comissionado'} -
-
Vencimento
-
- R$ {simbolo.vencValor} -
-
Valor base
-
-
-
Representação
-
- R$ {simbolo.repValor} -
-
Adicional
-
- {/if} -
-
Total
-
- R$ {simbolo.valor} -
-
Remuneração total
-
-
-
-
- {/if} + + {#if simbolo} +
+
+

+ + + + Dados Financeiros +

+
+
+
Símbolo
+
{simbolo.nome}
+
+ {simbolo.tipo === "cargo_comissionado" + ? "Cargo Comissionado" + : "Função Gratificada"} +
+
+ {#if funcionario.simboloTipo === "cargo_comissionado"} +
+
Vencimento
+
+ R$ {simbolo.vencValor} +
+
Valor base
+
+
+
Representação
+
+ R$ {simbolo.repValor} +
+
Adicional
+
+ {/if} +
+
Total
+
+ R$ {simbolo.valor} +
+
Remuneração total
+
+
+
+
+ {/if} - -
-
-
-
-
- - - -
-
-

Status Atual

-
- {#if funcionario.statusFerias === 'em_ferias'} -
🏖️ Em Férias
- {:else} -
✅ Ativo
- {/if} -
-
-
- - - - - Gerenciar Férias - -
-
-
+ +
+
+
+
+
+ + + +
+
+

Status Atual

+
+ {#if funcionario.statusFerias === "em_ferias"} +
🏖️ Em Férias
+ {:else} +
✅ Ativo
+ {/if} +
+
+
+ + + + + Gerenciar Férias + +
+
+
- -
- -
- -
-
-

Informações Pessoais

-
-
- CPF: - {maskCPF(funcionario.cpf)} -
-
RG: {funcionario.rg}
- {#if funcionario.rgOrgaoExpedidor} -
- Órgão Expedidor: - {funcionario.rgOrgaoExpedidor} -
- {/if} - {#if funcionario.rgDataEmissao} -
- Data Emissão RG: - {funcionario.rgDataEmissao} -
- {/if} -
- Data Nascimento: - {funcionario.nascimento} -
- {#if funcionario.sexo} -
- Sexo: - {getLabelFromOptions(funcionario.sexo, SEXO_OPTIONS)} -
- {/if} - {#if funcionario.estadoCivil} -
- Estado Civil: - {getLabelFromOptions(funcionario.estadoCivil, ESTADO_CIVIL_OPTIONS)} -
- {/if} - {#if funcionario.nacionalidade} -
- Nacionalidade: - {funcionario.nacionalidade} -
- {/if} -
-
-
+ +
+ +
+ +
+
+

+ Informações Pessoais +

+
+
+ CPF: + {maskCPF(funcionario.cpf)} +
+
RG: {funcionario.rg}
+ {#if funcionario.rgOrgaoExpedidor} +
+ Órgão Expedidor: + {funcionario.rgOrgaoExpedidor} +
+ {/if} + {#if funcionario.rgDataEmissao} +
+ Data Emissão RG: + {funcionario.rgDataEmissao} +
+ {/if} +
+ Data Nascimento: + {funcionario.nascimento} +
+ {#if funcionario.sexo} +
+ Sexo: + {getLabelFromOptions(funcionario.sexo, SEXO_OPTIONS)} +
+ {/if} + {#if funcionario.estadoCivil} +
+ Estado Civil: + {getLabelFromOptions( + funcionario.estadoCivil, + ESTADO_CIVIL_OPTIONS, + )} +
+ {/if} + {#if funcionario.nacionalidade} +
+ Nacionalidade: + {funcionario.nacionalidade} +
+ {/if} +
+
+
- - {#if funcionario.nomePai || funcionario.nomeMae} -
-
-

Filiação

-
- {#if funcionario.nomePai} -
- Pai: - {funcionario.nomePai} -
- {/if} - {#if funcionario.nomeMae} -
- Mãe: - {funcionario.nomeMae} -
- {/if} -
-
-
- {/if} + + {#if funcionario.nomePai || funcionario.nomeMae} +
+
+

Filiação

+
+ {#if funcionario.nomePai} +
+ Pai: + {funcionario.nomePai} +
+ {/if} + {#if funcionario.nomeMae} +
+ Mãe: + {funcionario.nomeMae} +
+ {/if} +
+
+
+ {/if} - - {#if funcionario.naturalidade || funcionario.naturalidadeUF} -
-
-

Naturalidade

-
- {#if funcionario.naturalidade} -
- Cidade: - {funcionario.naturalidade} -
- {/if} - {#if funcionario.naturalidadeUF} -
- UF: - {funcionario.naturalidadeUF} -
- {/if} -
-
-
- {/if} -
+ + {#if funcionario.naturalidade || funcionario.naturalidadeUF} +
+
+

+ Naturalidade +

+
+ {#if funcionario.naturalidade} +
+ Cidade: + {funcionario.naturalidade} +
+ {/if} + {#if funcionario.naturalidadeUF} +
+ UF: + {funcionario.naturalidadeUF} +
+ {/if} +
+
+
+ {/if} +
- -
- -
-
-

Cargo e Vínculo

-
-
- Tipo: - {funcionario.simboloTipo === 'cargo_comissionado' - ? 'Cargo Comissionado' - : 'Função Gratificada'} -
- {#if simbolo} -
- Símbolo: - {simbolo.nome} -
-
- {simbolo.descricao} -
- {/if} - {#if funcionario.descricaoCargo} -
- Descrição: - {funcionario.descricaoCargo} -
- {/if} - {#if funcionario.admissaoData} -
- Data Admissão: - {funcionario.admissaoData} -
- {/if} - {#if funcionario.nomeacaoPortaria} -
- Portaria: - {funcionario.nomeacaoPortaria} -
- {/if} - {#if funcionario.nomeacaoData} -
- Data Nomeação: - {funcionario.nomeacaoData} -
- {/if} - {#if funcionario.nomeacaoDOE} -
- DOE: - {funcionario.nomeacaoDOE} -
- {/if} - {#if funcionario.pertenceOrgaoPublico} -
- Pertence Órgão Público: Sim -
- {#if funcionario.orgaoOrigem} -
- Órgão Origem: - {funcionario.orgaoOrigem} -
- {/if} - {/if} - {#if funcionario.aposentado && funcionario.aposentado !== 'nao'} -
- Aposentado: - {getLabelFromOptions(funcionario.aposentado, APOSENTADO_OPTIONS)} -
- {/if} -
-
-
- -
-
-

Documentos Pessoais

-
- {#if funcionario.carteiraProfissionalNumero} -
- Cart. Profissional: - {funcionario.carteiraProfissionalNumero} - {#if funcionario.carteiraProfissionalSerie} - - Série: {funcionario.carteiraProfissionalSerie} - {/if} -
- {/if} - {#if funcionario.reservistaNumero} -
- Reservista: - {funcionario.reservistaNumero} - {#if funcionario.reservistaSerie} - - Série: {funcionario.reservistaSerie} - {/if} -
- {/if} - {#if funcionario.tituloEleitorNumero} -
- Título Eleitor: - {funcionario.tituloEleitorNumero} -
- {#if funcionario.tituloEleitorZona || funcionario.tituloEleitorSecao} -
- {#if funcionario.tituloEleitorZona}Zona: {funcionario.tituloEleitorZona}{/if} - {#if funcionario.tituloEleitorSecao} - - Seção: {funcionario.tituloEleitorSecao}{/if} -
- {/if} - {/if} - {#if funcionario.pisNumero} -
- PIS/PASEP: - {funcionario.pisNumero} -
- {/if} -
-
-
+ +
+ +
+
+

+ Cargo e Vínculo +

+
+
+ Tipo: + {funcionario.simboloTipo === "cargo_comissionado" + ? "Cargo Comissionado" + : "Função Gratificada"} +
+ {#if simbolo} +
+ Símbolo: + {simbolo.nome} +
+
+ {simbolo.descricao} +
+ {/if} + {#if funcionario.descricaoCargo} +
+ Descrição: + {funcionario.descricaoCargo} +
+ {/if} + {#if funcionario.admissaoData} +
+ Data Admissão: + {funcionario.admissaoData} +
+ {/if} + {#if funcionario.nomeacaoPortaria} +
+ Portaria: + {funcionario.nomeacaoPortaria} +
+ {/if} + {#if funcionario.nomeacaoData} +
+ Data Nomeação: + {funcionario.nomeacaoData} +
+ {/if} + {#if funcionario.nomeacaoDOE} +
+ DOE: + {funcionario.nomeacaoDOE} +
+ {/if} + {#if funcionario.pertenceOrgaoPublico} +
+ Pertence Órgão Público: Sim +
+ {#if funcionario.orgaoOrigem} +
+ Órgão Origem: + {funcionario.orgaoOrigem} +
+ {/if} + {/if} + {#if funcionario.aposentado && funcionario.aposentado !== "nao"} +
+ Aposentado: + {getLabelFromOptions( + funcionario.aposentado, + APOSENTADO_OPTIONS, + )} +
+ {/if} +
+
+
+ +
+
+

+ Documentos Pessoais +

+
+ {#if funcionario.carteiraProfissionalNumero} +
+ Cart. Profissional: + {funcionario.carteiraProfissionalNumero} + {#if funcionario.carteiraProfissionalSerie} + - Série: {funcionario.carteiraProfissionalSerie} + {/if} +
+ {/if} + {#if funcionario.reservistaNumero} +
+ Reservista: + {funcionario.reservistaNumero} + {#if funcionario.reservistaSerie} + - Série: {funcionario.reservistaSerie} + {/if} +
+ {/if} + {#if funcionario.tituloEleitorNumero} +
+ Título Eleitor: + {funcionario.tituloEleitorNumero} +
+ {#if funcionario.tituloEleitorZona || funcionario.tituloEleitorSecao} +
+ {#if funcionario.tituloEleitorZona}Zona: {funcionario.tituloEleitorZona}{/if} + {#if funcionario.tituloEleitorSecao} + - Seção: {funcionario.tituloEleitorSecao}{/if} +
+ {/if} + {/if} + {#if funcionario.pisNumero} +
+ PIS/PASEP: + {funcionario.pisNumero} +
+ {/if} +
+
+
- - {#if funcionario.grauInstrucao || funcionario.formacao} -
-
-

Formação

-
- {#if funcionario.grauInstrucao} -
- Grau Instrução: - {getLabelFromOptions(funcionario.grauInstrucao, GRAU_INSTRUCAO_OPTIONS)} -
- {/if} - {#if funcionario.formacao} -
- Formação: - {funcionario.formacao} -
- {/if} - {#if funcionario.formacaoRegistro} -
- Registro Nº: - {funcionario.formacaoRegistro} -
- {/if} -
-
-
- {/if} + + {#if funcionario.grauInstrucao || funcionario.formacao} +
+
+

Formação

+
+ {#if funcionario.grauInstrucao} +
+ Grau Instrução: + {getLabelFromOptions( + funcionario.grauInstrucao, + GRAU_INSTRUCAO_OPTIONS, + )} +
+ {/if} + {#if funcionario.formacao} +
+ Formação: + {funcionario.formacao} +
+ {/if} + {#if funcionario.formacaoRegistro} +
+ Registro Nº: + {funcionario.formacaoRegistro} +
+ {/if} +
+
+
+ {/if} - - {#if cursos && cursos.length > 0} -
-
-

- - - - Cursos e Treinamentos -

-
- {#each cursos as curso} -
-
-

{curso.descricao}

-

- - - - {curso.data} -

-
- {#if curso.certificadoUrl} - - - - - Certificado - - {/if} -
- {/each} -
-
-
- {/if} + + {#if cursos && cursos.length > 0} +
+
+

+ + + + Cursos e Treinamentos +

+
+ {#each cursos as curso} +
+
+

{curso.descricao}

+

+ + + + {curso.data} +

+
+ {#if curso.certificadoUrl} + + + + + Certificado + + {/if} +
+ {/each} +
+
+
+ {/if} - - {#if funcionario.grupoSanguineo || funcionario.fatorRH} -
-
-

Saúde

-
- {#if funcionario.grupoSanguineo} -
- Grupo Sanguíneo: - {funcionario.grupoSanguineo} -
- {/if} - {#if funcionario.fatorRH} -
- Fator RH: - {getLabelFromOptions(funcionario.fatorRH, FATOR_RH_OPTIONS)} -
- {/if} -
-
-
- {/if} + + {#if funcionario.grupoSanguineo || funcionario.fatorRH} +
+
+

Saúde

+
+ {#if funcionario.grupoSanguineo} +
+ Grupo Sanguíneo: + {funcionario.grupoSanguineo} +
+ {/if} + {#if funcionario.fatorRH} +
+ Fator RH: + {getLabelFromOptions(funcionario.fatorRH, FATOR_RH_OPTIONS)} +
+ {/if} +
+
+
+ {/if} - -
-
-

Contato

-
-
- E-mail: - {funcionario.email} -
-
- Telefone: - {maskPhone(funcionario.telefone)} -
-
-
-
+ +
+
+

Contato

+
+
+ E-mail: + {funcionario.email} +
+
+ Telefone: + {maskPhone(funcionario.telefone)} +
+
+
+
- -
-
-

Endereço

-
-
{funcionario.endereco}
-
{funcionario.cidade} - {funcionario.uf}
-
- CEP: - {maskCEP(funcionario.cep)} -
-
-
-
+ +
+
+

Endereço

+
+
{funcionario.endereco}
+
{funcionario.cidade} - {funcionario.uf}
+
+ CEP: + {maskCEP(funcionario.cep)} +
+
+
+
- - {#if funcionario.contaBradescoNumero} -
-
-

Dados Bancários - Bradesco

-
-
- Conta: - {funcionario.contaBradescoNumero} - {#if funcionario.contaBradescoDV}-{funcionario.contaBradescoDV}{/if} -
- {#if funcionario.contaBradescoAgencia} -
- Agência: - {funcionario.contaBradescoAgencia} -
- {/if} -
-
-
- {/if} -
-
+ + {#if funcionario.contaBradescoNumero} +
+
+

+ Dados Bancários - Bradesco +

+
+
+ Conta: + {funcionario.contaBradescoNumero} + {#if funcionario.contaBradescoDV}-{funcionario.contaBradescoDV}{/if} +
+ {#if funcionario.contaBradescoAgencia} +
+ Agência: + {funcionario.contaBradescoAgencia} +
+ {/if} +
+
+
+ {/if} +
+
- -
-
-

- - - - Documentos Anexados -

+ +
+
+

+ + + + Documentos Anexados +

-
- {#each documentos as doc} - {@const temDocumento = documentosUrls[doc.campo]} -
-
-
-
- {#if temDocumento} - - - - {:else} - - - - {/if} -
-
-

{doc.nome}

-

- {temDocumento ? 'Enviado' : 'Pendente'} -

- {#if temDocumento} - - {/if} -
-
-
-
- {/each} -
+
+ {#each documentos as doc} + {@const temDocumento = documentosUrls[doc.campo]} +
+
+
+
+ {#if temDocumento} + + + + {:else} + + + + {/if} +
+
+

{doc.nome}

+

+ {temDocumento ? "Enviado" : "Pendente"} +

+ {#if temDocumento} + + {/if} +
+
+
+
+ {/each} +
-
- -
-
-
-
+
+ +
+ + +
- - {#if showPrintModal} - (showPrintModal = false)} /> - {/if} + + {#if showPrintModal} + (showPrintModal = false)} /> + {/if} {/if} diff --git a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/documentos/+page.svelte b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/documentos/+page.svelte index f96c08b..5e02825 100644 --- a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/documentos/+page.svelte +++ b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/documentos/+page.svelte @@ -1,358 +1,277 @@ {#if loading} -
- -
+
+ +
{:else if funcionario} -
- - +
+ + - -
-
-
-
- - - -
-
-

Gerenciar Documentos

-

- {funcionario.nome} - Matrícula: {funcionario.matricula} -

-
-
+ +
+
+
+
+ + + +
+
+

Gerenciar Documentos

+

{funcionario.nome} - Matrícula: {funcionario.matricula}

+
+
- -
-
+ +
+
- -
-
-
-
- - - -
-
Total de Documentos
-
{contarDocumentos().total}
-
-
+ +
+
+
+
+ + + +
+
Total de Documentos
+
{contarDocumentos().total}
+
+
-
-
-
- - - -
-
Documentos Enviados
-
{contarDocumentos().enviados}
-
-
+
+
+
+ + + +
+
Documentos Enviados
+
{contarDocumentos().enviados}
+
+
-
-
-
- - - -
-
Documentos Pendentes
-
{contarDocumentos().pendentes}
-
-
-
+
+
+
+ + + +
+
Documentos Pendentes
+
{contarDocumentos().pendentes}
+
+
+
- -
- -
+ +
+ +
- -
-
-
- - - -
-
-
+ +
+
+
+ + + +
+
+
- - {#each categoriasDocumentos as categoria} - {@const docsCategoria = getDocumentosByCategoria(categoria).filter((doc) => { - const temDocumento = !!documentosStorage[doc.campo]; - if (filtro === 'enviados') return temDocumento; - if (filtro === 'pendentes') return !temDocumento; - return true; - })} + + {#each categoriasDocumentos as categoria} + {@const docsCategoria = getDocumentosByCategoria(categoria).filter(doc => { + const temDocumento = !!documentosStorage[doc.campo]; + if (filtro === "enviados") return temDocumento; + if (filtro === "pendentes") return !temDocumento; + return true; + })} + + {#if docsCategoria.length > 0} +
+
+

+ {categoria} +
{docsCategoria.length}
+

- {#if docsCategoria.length > 0} -
-
-

- {categoria} -
{docsCategoria.length}
-

+
+ {#each docsCategoria as doc} + handleDocumentoUpload(doc.campo, file)} + onRemove={() => handleDocumentoRemove(doc.campo)} + /> + {/each} +
+
+
+ {/if} + {/each} -
- {#each docsCategoria as doc} - handleDocumentoUpload(doc.campo, file)} - onRemove={() => handleDocumentoRemove(doc.campo)} - /> - {/each} -
-
-
- {/if} - {/each} - - {#if documentosFiltrados().length === 0} -
- - - - Nenhum documento encontrado com o filtro selecionado. -
- {/if} -
+ {#if documentosFiltrados().length === 0} +
+ + + + Nenhum documento encontrado com o filtro selecionado. +
+ {/if} +
{/if} + diff --git a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/editar/+page.svelte b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/editar/+page.svelte index 785ddff..f38dca4 100644 --- a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/editar/+page.svelte +++ b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/[funcionarioId]/editar/+page.svelte @@ -1,38 +1,31 @@ {#if loadingData} -
- -
+
+ +
{:else}
@@ -1780,4 +1552,4 @@
-{/if} +{/if} \ No newline at end of file diff --git a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/cadastro/+page.svelte b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/cadastro/+page.svelte index ff9fd38..e2d8851 100644 --- a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/cadastro/+page.svelte +++ b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/cadastro/+page.svelte @@ -1,198 +1,202 @@ -
- - - - -
-
-
- - - -
-
-

Cadastro de Funcionário

-

- Preencha os campos abaixo para cadastrar um novo funcionário -

-
-
-
- - - {#if notice} -
- - {#if notice.kind === 'success'} - - {:else} - - {/if} - - {notice.text} -
- {/if} - - -
{ - e.preventDefault(); - }} - > - -
-
-

- - - - Informações Pessoais -

- -
- -
- - -
- - -
- - -
- - -
- - { - const target = e.target as HTMLInputElement; - cpf = maskCPF(target.value); - target.value = cpf; - }} - required - /> -
- - -
- - { - const target = e.target as HTMLInputElement; - rg = onlyDigits(target.value); - target.value = rg; - }} - required - /> -
- - -
- - -
- - -
- - { - const target = e.target as HTMLInputElement; - rgDataEmissao = maskDate(target.value); - target.value = rgDataEmissao; - }} - /> -
- - -
- - -
- - -
- - -
- - -
- - { - const target = e.target as HTMLInputElement; - nascimento = maskDate(target.value); - target.value = nascimento; - }} - required - /> -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
-
-
-
- - -
-
-

- - - - Documentos Pessoais -

- -
- -
- - -
- -
- - -
- -
- - { - const target = e.target as HTMLInputElement; - carteiraProfissionalDataEmissao = maskDate(target.value); - target.value = carteiraProfissionalDataEmissao; - }} - /> -
- - -
- - -
- -
- - -
- - -
- - -
- -
- - -
- -
- - -
- - -
- - -
-
-
-
- - -
-
-

- - - - Formação e Saúde -

- -
- -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
-
-
-
- - -
-
-

- - - - Cursos e Treinamentos -

- -

- Adicione até 7 cursos ou treinamentos realizados pelo funcionário (opcional) -

- - - {#if cursos.length > 0} -
-

Cursos adicionados ({cursos.length}/7)

- {#each cursos as curso} -
-
-

{curso.descricao}

-

{curso.data}

-
- -
- {/each} -
- {/if} - - - {#if cursos.length < 7} -
- -
Adicionar Curso/Treinamento
-
-
-
- - -
- -
- - (cursoAtual.data = maskDate(e.currentTarget.value))} - /> -
- -
- - { - const file = e.currentTarget.files?.[0]; - if (file) cursoAtual.arquivo = file; - }} - /> -
- - -
-
-
- {:else} -
- - - - Limite de 7 cursos atingido -
- {/if} -
-
- - -
-
-

- - - - - Endereço e Contato -

- -
- -
- - { - const target = e.target as HTMLInputElement; - cep = maskCEP(target.value); - target.value = cep; - }} - onblur={() => fillFromCEP(cep)} - required - /> -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- - { - const target = e.target as HTMLInputElement; - telefone = maskPhone(target.value); - target.value = telefone; - }} - required - /> -
-
-
-
- - -
-
-

- - - - Dependentes -

- - {#if dependentes.length > 0} -
-

Dependentes adicionados ({dependentes.length}/10)

- {#each dependentes as dep} -
-
-

{dep.nome} — {dep.parentesco}

-

- CPF: {dep.cpf} • Nasc.: {dep.nascimento} -

-
- - -
-
- -
- {/each} -
- {/if} - - {#if dependentes.length < 10} -
- -
Adicionar Dependente
-
-
-
- - -
- -
- - -
- -
- - { - const t = e.target as HTMLInputElement; - dependenteAtual.cpf = maskCPF(t.value); - t.value = dependenteAtual.cpf; - }} - /> -
- -
- - { - const t = e.target as HTMLInputElement; - dependenteAtual.nascimento = maskDate(t.value); - t.value = dependenteAtual.nascimento; - }} - /> -
- -
- - { - const file = e.currentTarget.files?.[0]; - dependenteAtual.arquivo = file || null; - if (file) { - try { - dependenteAtual.documentoId = await uploadDocumentoDependente(file); - } catch { - alert('Falha no upload do documento do dependente'); - } - } - }} - /> -
- - -
- -
-
- -
- -
- -
-
-
-
- {/if} -
-
- - -
-
-

- - - - Cargo e Vínculo -

- -
- -
- - -
- - -
- - -
- - -
- - -
- - -
- - -
- -
- - { - const target = e.target as HTMLInputElement; - nomeacaoData = maskDate(target.value); - target.value = nomeacaoData; - }} - /> -
- -
- - { - const target = e.target as HTMLInputElement; - nomeacaoDOE = maskDate(target.value); - target.value = nomeacaoDOE; - }} - /> -
- - -
- - { - const target = e.target as HTMLInputElement; - admissaoData = maskDate(target.value); - target.value = admissaoData; - }} - /> -
- - -
- - -
- - -
- -
- - - {#if pertenceOrgaoPublico} -
- - -
- {/if} - - -
- - -
-
-
-
- - -
-
-

- - - - Dados Bancários - Bradesco -

- -
- -
- - -
- - -
- - -
- - -
- - -
-
-
-
- - - - - -
-
-

- - - - Documentação Anexa -

- -

- Anexe os documentos necessários em formato PDF ou imagem (máximo 10MB cada) -

- - {#each categoriasDocumentos as categoria (categoria)} -
-

{categoria}

-
- {#each getDocumentosByCategoria(categoria) as doc} - handleDocumentoUpload(doc.campo, file)} - onRemove={() => handleDocumentoRemove(doc.campo)} - disabled={loading} - /> - {/each} -
-
- {/each} -
-
- - -
-
-
- - -
-
-
- - - - - - +
+ + + + +
+
+
+ + + +
+
+

Cadastro de Funcionário

+

Preencha os campos abaixo para cadastrar um novo funcionário

+
+
+
+ + + {#if notice} +
+ + {#if notice.kind === "success"} + + {:else} + + {/if} + + {notice.text} +
+ {/if} + + +
{ e.preventDefault(); }}> + + +
+
+

+ + + + Informações Pessoais +

+ +
+ +
+ + +
+ + +
+ + +
+ + +
+ + { + const target = e.target as HTMLInputElement; + cpf = maskCPF(target.value); + target.value = cpf; + }} + required + /> +
+ + +
+ + { + const target = e.target as HTMLInputElement; + rg = onlyDigits(target.value); + target.value = rg; + }} + required + /> +
+ + +
+ + +
+ + +
+ + { + const target = e.target as HTMLInputElement; + rgDataEmissao = maskDate(target.value); + target.value = rgDataEmissao; + }} + /> +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + { + const target = e.target as HTMLInputElement; + nascimento = maskDate(target.value); + target.value = nascimento; + }} + required + /> +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+
+
+
+ + +
+
+

+ + + + Documentos Pessoais +

+ +
+ +
+ + +
+ +
+ + +
+ +
+ + { + const target = e.target as HTMLInputElement; + carteiraProfissionalDataEmissao = maskDate(target.value); + target.value = carteiraProfissionalDataEmissao; + }} + /> +
+ + +
+ + +
+ +
+ + +
+ + +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ + +
+
+
+
+ + +
+
+

+ + + + Formação e Saúde +

+ +
+ +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+
+
+
+ + +
+
+

+ + + + Cursos e Treinamentos +

+ +

+ Adicione até 7 cursos ou treinamentos realizados pelo funcionário (opcional) +

+ + + {#if cursos.length > 0} +
+

Cursos adicionados ({cursos.length}/7)

+ {#each cursos as curso} +
+
+

{curso.descricao}

+

{curso.data}

+
+ +
+ {/each} +
+ {/if} + + + {#if cursos.length < 7} +
+ +
+ Adicionar Curso/Treinamento +
+
+
+
+ + +
+ +
+ + cursoAtual.data = maskDate(e.currentTarget.value)} + /> +
+ +
+ + { + const file = e.currentTarget.files?.[0]; + if (file) cursoAtual.arquivo = file; + }} + /> +
+ + +
+
+
+ {:else} +
+ + + + Limite de 7 cursos atingido +
+ {/if} +
+
+ + +
+
+

+ + + + + Endereço e Contato +

+ +
+ +
+ + { + const target = e.target as HTMLInputElement; + cep = maskCEP(target.value); + target.value = cep; + }} + onblur={() => fillFromCEP(cep)} + required + /> +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + { + const target = e.target as HTMLInputElement; + telefone = maskPhone(target.value); + target.value = telefone; + }} + required + /> +
+
+
+
+ + +
+
+

+ + + + Dependentes +

+ + {#if dependentes.length > 0} +
+

Dependentes adicionados ({dependentes.length}/10)

+ {#each dependentes as dep} +
+
+

{dep.nome} — {dep.parentesco}

+

CPF: {dep.cpf} • Nasc.: {dep.nascimento}

+
+ + +
+
+ +
+ {/each} +
+ {/if} + + {#if dependentes.length < 10} +
+ +
Adicionar Dependente
+
+
+
+ + +
+ +
+ + +
+ +
+ + { const t = e.target as HTMLInputElement; dependenteAtual.cpf = maskCPF(t.value); t.value = dependenteAtual.cpf; }} /> +
+ +
+ + { const t = e.target as HTMLInputElement; dependenteAtual.nascimento = maskDate(t.value); t.value = dependenteAtual.nascimento; }} /> +
+ +
+ + { const file = e.currentTarget.files?.[0]; dependenteAtual.arquivo = file || null; if (file) { try { dependenteAtual.documentoId = await uploadDocumentoDependente(file); } catch { alert("Falha no upload do documento do dependente"); } } }} /> +
+ + +
+ +
+
+ +
+ +
+ +
+
+
+
+ {/if} +
+
+ + +
+
+

+ + + + Cargo e Vínculo +

+ +
+ +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ + +
+ +
+ + { + const target = e.target as HTMLInputElement; + nomeacaoData = maskDate(target.value); + target.value = nomeacaoData; + }} + /> +
+ +
+ + { + const target = e.target as HTMLInputElement; + nomeacaoDOE = maskDate(target.value); + target.value = nomeacaoDOE; + }} + /> +
+ + +
+ + { + const target = e.target as HTMLInputElement; + admissaoData = maskDate(target.value); + target.value = admissaoData; + }} + /> +
+ + +
+ + +
+ + +
+ +
+ + + {#if pertenceOrgaoPublico} +
+ + +
+ {/if} + + +
+ + +
+
+
+
+ + +
+
+

+ + + + Dados Bancários - Bradesco +

+ +
+ +
+ + +
+ + +
+ + +
+ + +
+ + +
+
+
+
+ + + + + +
+
+

+ + + + Documentação Anexa +

+ +

+ Anexe os documentos necessários em formato PDF ou imagem (máximo 10MB cada) +

+ + {#each categoriasDocumentos as categoria} +
+

{categoria}

+
+ {#each getDocumentosByCategoria(categoria) as doc} + handleDocumentoUpload(doc.campo, file)} + onRemove={() => handleDocumentoRemove(doc.campo)} + disabled={loading} + /> + {/each} +
+
+ {/each} +
+
+ + +
+
+
+ + +
+
+
+ + + + + +
diff --git a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/excluir/+page.svelte b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/excluir/+page.svelte index cf72eb7..9ec3f57 100644 --- a/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/excluir/+page.svelte +++ b/apps/web/src/routes/(dashboard)/recursos-humanos/funcionarios/excluir/+page.svelte @@ -1,514 +1,330 @@ -
diff --git a/apps/web/src/routes/(dashboard)/ti/monitoramento-emails/+page.svelte b/apps/web/src/routes/(dashboard)/ti/monitoramento-emails/+page.svelte index 0a3cd0e..214332c 100644 --- a/apps/web/src/routes/(dashboard)/ti/monitoramento-emails/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/monitoramento-emails/+page.svelte @@ -1,568 +1,463 @@
-
-

📧 Monitoramento de Emails

-

- Acompanhe o status da fila de emails e identifique problemas de envio -

-
+
+

📧 Monitoramento de Emails

+

+ Acompanhe o status da fila de emails e identifique problemas de envio +

+
- - {#if estatisticas?.data} -
-
-
Total
-
{estatisticas.data.total}
-
Emails na fila
-
+ + {#if estatisticas?.data} +
+
+
Total
+
{estatisticas.data.total}
+
Emails na fila
+
-
-
Pendentes
-
{estatisticas.data.pendentes}
-
Aguardando envio
-
+
+
Pendentes
+
{estatisticas.data.pendentes}
+
Aguardando envio
+
-
-
Enviando
-
{estatisticas.data.enviando}
-
Em processamento
-
+
+
Enviando
+
{estatisticas.data.enviando}
+
Em processamento
+
-
-
Enviados
-
{estatisticas.data.enviados}
-
Concluídos
-
+
+
Enviados
+
{estatisticas.data.enviados}
+
Concluídos
+
-
-
Falhas
-
{estatisticas.data.falhas}
-
Com erro
-
-
- {:else if estatisticas === undefined} -
- -
- {/if} +
+
Falhas
+
{estatisticas.data.falhas}
+
Com erro
+
+
+ {:else if estatisticas === undefined} +
+ +
+ {/if} - -
-
-
-
- -
+ +
+
+
+
+ +
- -
-
-
+ +
+
+
- -
-
-

Fila de Emails

+ +
+
+

Fila de Emails

- {#if filaEmails?.data && filaEmails.data.length > 0} -
- - - - - - - - - - - - - - - {#each filaEmails.data as email} - - - - - - - - - - - {/each} - -
DestinatárioAssuntoStatusTentativasCriado emÚltima tentativaErroAções
-
{email.destinatario}
-
-
- {email.assunto} -
-
- - {getStatusLabel(email.status)} - - {email.tentativas || 0}{formatarData(email.criadoEm)} - {formatarData(email.ultimaTentativa)} - - {#if email.erroDetalhes} - - {:else} - - - {/if} - - -
-
- {:else if filaEmails?.data !== undefined} -
-

Nenhum email na fila

-
- {:else} -
- -
- {/if} -
-
+ {#if filaEmails?.data && filaEmails.data.length > 0} +
+ + + + + + + + + + + + + + + {#each filaEmails.data as email} + + + + + + + + + + + {/each} + +
DestinatárioAssuntoStatusTentativasCriado emÚltima tentativaErroAções
+
{email.destinatario}
+
+
+ {email.assunto} +
+
+ + {getStatusLabel(email.status)} + + {email.tentativas || 0}{formatarData(email.criadoEm)} + {formatarData(email.ultimaTentativa)} + + {#if email.erroDetalhes} + + {:else} + - + {/if} + + +
+
+ {:else if filaEmails?.data !== undefined} +
+

Nenhum email na fila

+
+ {:else} +
+ +
+ {/if} +
+
- -
-
-

🔍 Troubleshooting

-
-

- Emails pendentes não estão sendo enviados? -

-
    -
  • Verifique se a configuração SMTP está ativa em Configurações de Email
  • -
  • Confirme se o cron job está rodando (verifique logs do Convex)
  • -
  • Clique em "Processar Fila Manualmente" para forçar o processamento
  • -
+ +
+
+

🔍 Troubleshooting

+
+

+ Emails pendentes não estão sendo enviados? +

+
    +
  • Verifique se a configuração SMTP está ativa em Configurações de Email
  • +
  • Confirme se o cron job está rodando (verifique logs do Convex)
  • +
  • Clique em "Processar Fila Manualmente" para forçar o processamento
  • +
-

- Emails com status "Falha"? -

-
    -
  • Verifique as credenciais SMTP em Configurações de Email
  • -
  • Confirme se o servidor SMTP está acessível
  • -
  • Verifique os logs do Convex para detalhes do erro
  • -
  • Teste a conexão SMTP na página de configurações
  • -
-
-
-
+

+ Emails com status "Falha"? +

+
    +
  • Verifique as credenciais SMTP em Configurações de Email
  • +
  • Confirme se o servidor SMTP está acessível
  • +
  • Verifique os logs do Convex para detalhes do erro
  • +
  • Teste a conexão SMTP na página de configurações
  • +
+
+
+
{#if modalDetalhesAberto && emailSelecionado} - {/if} + diff --git a/apps/web/src/routes/(dashboard)/ti/monitoramento/+page.svelte b/apps/web/src/routes/(dashboard)/ti/monitoramento/+page.svelte index 32b2e99..274680b 100644 --- a/apps/web/src/routes/(dashboard)/ti/monitoramento/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/monitoramento/+page.svelte @@ -30,7 +30,7 @@

- + - import { useQuery, useConvexClient } from 'convex-svelte'; - import { api } from '@sgse-app/backend/convex/_generated/api'; - import { format } from 'date-fns'; - import { ptBR } from 'date-fns/locale'; - import type { Id, Doc } from '@sgse-app/backend/convex/_generated/dataModel'; - - // Tipos para agendamentos - type TipoAgendamento = 'email' | 'chat'; - type StatusAgendamento = 'agendado' | 'enviado' | 'cancelado'; - - interface AgendamentoEmail { - _id: Id<'notificacoesEmail'>; - _creationTime: number; - destinatario: string; - destinatarioId: Id<'usuarios'> | undefined; - assunto: string; - corpo: string; - templateId: Id<'templatesMensagens'> | undefined; - status: 'pendente' | 'enviando' | 'enviado' | 'falha'; - agendadaPara: number | undefined; - enviadoPor: Id<'usuarios'>; - criadoEm: number; - enviadoEm: number | undefined; - destinatarioInfo: Doc<'usuarios'> | null; - templateInfo: Doc<'templatesMensagens'> | null; - } - - interface AgendamentoChat { - _id: Id<'mensagens'>; - _creationTime: number; - conversaId: Id<'conversas'>; - remetenteId: Id<'usuarios'>; - conteudo: string; - agendadaPara: number | undefined; - enviadaEm: number; - conversaInfo: Doc<'conversas'> | null; - destinatarioInfo: Doc<'usuarios'> | null; - } - - type Agendamento = - | { tipo: 'email'; dados: AgendamentoEmail } - | { tipo: 'chat'; dados: AgendamentoChat }; - - const client = useConvexClient(); - const currentUser = useQuery(api.auth.getCurrentUser, {}); - - // Queries - const templatesQuery = useQuery(api.templatesMensagens.listarTemplates, {}); - const usuariosQuery = useQuery(api.usuarios.listar, {}); - - // Mapa de emailIds para rastrear status - let emailIdsRastreados = $state>(new Set()); - - // Query para buscar status dos emails (só executa quando há IDs) - const emailIdsArray = $derived( - Array.from(emailIdsRastreados).map((id) => id as Id<'notificacoesEmail'>) - ); - // Usar função para evitar execução quando array está vazio - const emailsStatusQuery = $derived.by(() => { - if (emailIdsArray.length === 0) return null; - return useQuery(api.email.buscarEmailsPorIds, { emailIds: emailIdsArray }); - }); - - // Queries para agendamentos - const agendamentosEmailQuery = useQuery(api.email.listarAgendamentosEmail, {}); - const agendamentosChatQuery = useQuery(api.chat.listarAgendamentosChat, {}); - - // Filtro de agendamentos - type FiltroAgendamento = 'todos' | 'agendados' | 'enviados'; - let filtroAgendamento = $state('todos'); - - // Extrair dados das queries de forma robusta - const templates = $derived.by(() => { - if (templatesQuery === undefined || templatesQuery === null) { - return []; - } - if ('data' in templatesQuery && templatesQuery.data !== undefined) { - return Array.isArray(templatesQuery.data) ? templatesQuery.data : []; - } - if (Array.isArray(templatesQuery)) { - return templatesQuery; - } - return []; - }); - - const usuarios = $derived.by(() => { - if (usuariosQuery === undefined || usuariosQuery === null) { - return []; - } - if ('data' in usuariosQuery && usuariosQuery.data !== undefined) { - return Array.isArray(usuariosQuery.data) ? usuariosQuery.data : []; - } - if (Array.isArray(usuariosQuery)) { - return usuariosQuery; - } - return []; - }); - - // Estados de carregamento e erro - const carregandoTemplates = $derived(templatesQuery === undefined || templatesQuery === null); - const carregandoUsuarios = $derived(usuariosQuery === undefined || usuariosQuery === null); - - // Verificar erros de forma mais robusta - const erroTemplates = $derived.by(() => { - if (templatesQuery === undefined || templatesQuery === null) return false; - // Verificar se é um objeto com propriedade error - if (typeof templatesQuery === 'object' && 'error' in templatesQuery) { - return templatesQuery.error !== undefined && templatesQuery.error !== null; - } - return false; - }); - - const erroUsuarios = $derived.by(() => { - if (usuariosQuery === undefined || usuariosQuery === null) return false; - if (typeof usuariosQuery === 'object' && 'error' in usuariosQuery) { - return usuariosQuery.error !== undefined && usuariosQuery.error !== null; - } - return false; - }); - - // Log para debug (remover depois se necessário) - $effect(() => { - if (templatesQuery !== undefined && templatesQuery !== null) { - console.log('Templates Query:', templatesQuery); - console.log('Templates Extraídos:', templates); - } - }); - - let destinatarioId = $state(''); - let enviarParaTodos = $state(false); - let canal = $state<'chat' | 'email' | 'ambos'>('chat'); - let templateId = $state(''); - let mensagemPersonalizada = $state(''); - let usarTemplate = $state(true); - let processando = $state(false); - let criandoTemplates = $state(false); - let progressoEnvio = $state({ total: 0, enviados: 0, falhas: 0 }); - - // Estrutura de dados para logs de envio - type StatusLog = 'sucesso' | 'erro' | 'fila' | 'info' | 'enviando'; - type TipoLog = 'chat' | 'email'; - type LogEnvio = { - timestamp: number; - tipo: TipoLog; - destinatario: string; - status: StatusLog; - mensagem: string; - emailId?: string; // Para emails, guardar o ID para rastrear status - }; - - let logsEnvio = $state([]); - let terminalScrollRef: HTMLDivElement | null = $state(null); - - // Estados para agendamento - let agendarEnvio = $state(false); - let dataAgendamento = $state(''); - let horaAgendamento = $state(''); - - // Calcular data/hora mínimas - const now = new Date(); - const minDate = format(now, 'yyyy-MM-dd'); - - // Hora mínima recalculada baseada na data selecionada - const horaMinima = $derived.by(() => { - if (!dataAgendamento) return format(now, 'HH:mm'); - const hoje = format(now, 'yyyy-MM-dd'); - if (dataAgendamento === hoje) { - return format(now, 'HH:mm'); - } - return undefined; // Sem restrição se for data futura - }); - - function getPreviewAgendamento(): string { - if (!agendarEnvio || !dataAgendamento || !horaAgendamento) return ''; - try { - const dataHora = new Date(`${dataAgendamento}T${horaAgendamento}`); - return `Será enviada em ${format(dataHora, "dd/MM/yyyy 'às' HH:mm", { locale: ptBR })}`; - } catch { - return ''; - } - } - - // Estados para modal de novo template - let modalNovoTemplateAberto = $state(false); - let codigoTemplate = $state(''); - let nomeTemplate = $state(''); - let tituloTemplate = $state(''); - let corpoTemplate = $state(''); - let variaveisTemplate = $state(''); - let criandoNovoTemplate = $state(false); - - // Estado para mensagens de feedback - let mensagem = $state<{ - tipo: 'success' | 'error' | 'info'; - texto: string; - } | null>(null); - - const templateSelecionado = $derived(templates.find((t) => t._id === templateId)); - - // Função para renderizar template com variáveis (similar à função do backend) - function renderizarTemplate(template: string, variaveis: Record): string { - let resultado = template; - - for (const [chave, valor] of Object.entries(variaveis)) { - const placeholder = `{{${chave}}}`; - resultado = resultado.replace(new RegExp(placeholder, 'g'), valor); - } - - return resultado; - } - - // Função para mostrar mensagens - function mostrarMensagem(tipo: 'success' | 'error' | 'info', texto: string) { - mensagem = { tipo, texto }; - setTimeout(() => { - mensagem = null; - }, 5000); - } - - // Função para adicionar log ao terminal - function adicionarLog( - tipo: TipoLog, - destinatario: string, - status: StatusLog, - mensagem: string, - emailId?: string - ) { - logsEnvio = [ - ...logsEnvio, - { - timestamp: Date.now(), - tipo, - destinatario, - status, - mensagem, - emailId - } - ]; - - // Adicionar emailId ao rastreamento se fornecido - if (emailId) { - emailIdsRastreados = new Set([...emailIdsRastreados, emailId]); - } - - // Auto-scroll para o final - setTimeout(() => { - if (terminalScrollRef) { - terminalScrollRef.scrollTop = terminalScrollRef.scrollHeight; - } - }, 10); - } - - // Atualizar logs quando status dos emails mudar - $effect(() => { - if (!emailsStatusQuery || emailsStatusQuery === undefined) return; - - // Extrair dados da query - const emails = Array.isArray(emailsStatusQuery) - ? emailsStatusQuery - : 'data' in emailsStatusQuery && Array.isArray(emailsStatusQuery.data) - ? emailsStatusQuery.data - : []; - - if (emails.length === 0) return; - - for (const email of emails) { - if (!email) continue; - - // Encontrar logs relacionados a este email - const logsRelacionados = logsEnvio.filter((log) => log.emailId === email._id); - - for (const log of logsRelacionados) { - // Verificar se o status mudou - const novoStatus: StatusLog = - email.status === 'enviado' - ? 'sucesso' - : email.status === 'falha' - ? 'erro' - : email.status === 'enviando' - ? 'enviando' - : email.status === 'pendente' - ? 'fila' - : 'info'; - - // Se o status mudou, atualizar o log - if (log.status !== novoStatus) { - const indice = logsEnvio.findIndex((l) => l === log); - if (indice !== -1) { - const novaMensagem = - email.status === 'enviado' - ? 'Email enviado com sucesso' - : email.status === 'falha' - ? `Falha ao enviar: ${email.erroDetalhes || 'Erro desconhecido'}` - : email.status === 'enviando' - ? 'Enviando email...' - : email.status === 'pendente' - ? 'Email em fila de envio' - : log.mensagem; - - logsEnvio = logsEnvio.map((l, i) => - i === indice ? { ...l, status: novoStatus, mensagem: novaMensagem } : l - ); - } - } - } - } - }); - - // Função para limpar logs - function limparLogs() { - logsEnvio = []; - emailIdsRastreados = new Set(); - } - - // Extrair e processar agendamentos - const agendamentosEmail = $derived.by(() => { - if (!agendamentosEmailQuery || agendamentosEmailQuery === undefined) return []; - const dados = Array.isArray(agendamentosEmailQuery) - ? agendamentosEmailQuery - : 'data' in agendamentosEmailQuery && Array.isArray(agendamentosEmailQuery.data) - ? agendamentosEmailQuery.data - : []; - return dados as AgendamentoEmail[]; - }); - - const agendamentosChat = $derived.by(() => { - if (!agendamentosChatQuery || agendamentosChatQuery === undefined) return []; - const dados = Array.isArray(agendamentosChatQuery) - ? agendamentosChatQuery - : 'data' in agendamentosChatQuery && Array.isArray(agendamentosChatQuery.data) - ? agendamentosChatQuery.data - : []; - return dados as AgendamentoChat[]; - }); - - // Combinar e processar agendamentos - const todosAgendamentos = $derived.by(() => { - const agendamentos: Agendamento[] = []; - - for (const email of agendamentosEmail) { - if (email.agendadaPara) { - agendamentos.push({ - tipo: 'email', - dados: email - }); - } - } - - for (const chat of agendamentosChat) { - if (chat.agendadaPara) { - agendamentos.push({ - tipo: 'chat', - dados: chat - }); - } - } - - // Ordenar: futuros primeiro (mais próximos primeiro), depois passados (mais recentes primeiro) - return agendamentos.sort((a, b) => { - const timestampA = - a.tipo === 'email' ? (a.dados.agendadaPara ?? 0) : (a.dados.agendadaPara ?? 0); - const timestampB = - b.tipo === 'email' ? (b.dados.agendadaPara ?? 0) : (b.dados.agendadaPara ?? 0); - const agora = Date.now(); - - const aFuturo = timestampA > agora; - const bFuturo = timestampB > agora; - - // Futuros primeiro - if (aFuturo && !bFuturo) return -1; - if (!aFuturo && bFuturo) return 1; - - // Dentro do mesmo grupo, ordenar por timestamp - if (aFuturo) { - // Futuros: mais próximos primeiro - return timestampA - timestampB; - } else { - // Passados: mais recentes primeiro - return timestampB - timestampA; - } - }); - }); - - // Filtrar agendamentos - const agendamentosFiltrados = $derived.by(() => { - if (filtroAgendamento === 'todos') return todosAgendamentos; - - return todosAgendamentos.filter((ag) => { - const status = obterStatusAgendamento(ag); - if (filtroAgendamento === 'agendados') return status === 'agendado'; - if (filtroAgendamento === 'enviados') return status === 'enviado'; - return true; - }); - }); - - // Função para obter status do agendamento - function obterStatusAgendamento(agendamento: Agendamento): StatusAgendamento { - if (agendamento.tipo === 'email') { - const email = agendamento.dados; - if (email.status === 'enviado') return 'enviado'; - if (email.agendadaPara && email.agendadaPara <= Date.now()) return 'enviado'; - return 'agendado'; - } else { - const chat = agendamento.dados; - if (chat.agendadaPara && chat.agendadaPara <= Date.now()) return 'enviado'; - return 'agendado'; - } - } - - // Função para cancelar agendamento - async function cancelarAgendamento(agendamento: Agendamento) { - if (!confirm('Tem certeza que deseja cancelar este agendamento?')) { - return; - } - - try { - if (agendamento.tipo === 'email') { - const resultado = await client.mutation(api.email.cancelarAgendamentoEmail, { - emailId: agendamento.dados._id - }); - if (resultado.sucesso) { - mostrarMensagem('success', 'Agendamento de email cancelado com sucesso!'); - } else { - mostrarMensagem('error', resultado.erro || 'Erro ao cancelar agendamento'); - } - } else { - const resultado = await client.mutation(api.chat.cancelarMensagemAgendada, { - mensagemId: agendamento.dados._id - }); - if (resultado.sucesso) { - mostrarMensagem('success', 'Agendamento de chat cancelado com sucesso!'); - } else { - mostrarMensagem('error', resultado.erro || 'Erro ao cancelar agendamento'); - } - } - } catch (error) { - const erro = error instanceof Error ? error.message : 'Erro desconhecido'; - mostrarMensagem('error', `Erro ao cancelar agendamento: ${erro}`); - } - } - - // Função para obter nome do destinatário - function obterNomeDestinatario(agendamento: Agendamento): string { - if (agendamento.tipo === 'email') { - return ( - agendamento.dados.destinatarioInfo?.nome || agendamento.dados.destinatario || 'Usuário' - ); - } else { - return agendamento.dados.destinatarioInfo?.nome || 'Usuário'; - } - } - - // Função para formatar data/hora do agendamento - function formatarDataAgendamento(agendamento: Agendamento): string { - const timestamp = - agendamento.tipo === 'email' - ? agendamento.dados.agendadaPara - : agendamento.dados.agendadaPara; - - if (!timestamp) return 'N/A'; - - return format(new Date(timestamp), "dd/MM/yyyy 'às' HH:mm", { - locale: ptBR - }); - } - - // Função para formatar timestamp - function formatarTimestamp(timestamp: number): string { - return format(new Date(timestamp), 'HH:mm:ss', { locale: ptBR }); - } - - // Função para obter cor do status - function obterCorStatus(status: StatusLog): string { - switch (status) { - case 'sucesso': - return 'text-success'; - case 'erro': - return 'text-error'; - case 'fila': - return 'text-warning'; - case 'enviando': - return 'text-info'; - case 'info': - return 'text-info'; - default: - return 'text-base-content'; - } - } - - async function criarTemplatesPadrao() { - if (criandoTemplates) return; - - criandoTemplates = true; - try { - const resultado = await client.mutation(api.templatesMensagens.criarTemplatesPadrao, {}); - if (resultado.sucesso) { - mostrarMensagem( - 'success', - 'Templates padrão criados com sucesso! A página será recarregada.' - ); - setTimeout(() => { - window.location.reload(); - }, 2000); - } else { - mostrarMensagem('error', 'Erro ao criar templates padrão.'); - } - } catch (error) { - const erro = error instanceof Error ? error.message : 'Erro desconhecido'; - console.error('Erro ao criar templates:', error); - mostrarMensagem('error', 'Erro ao criar templates: ' + erro); - } finally { - criandoTemplates = false; - } - } - - function abrirModalNovoTemplate() { - modalNovoTemplateAberto = true; - // Limpar campos - codigoTemplate = ''; - nomeTemplate = ''; - tituloTemplate = ''; - corpoTemplate = ''; - variaveisTemplate = ''; - } - - function fecharModalNovoTemplate() { - modalNovoTemplateAberto = false; - } - - async function salvarNovoTemplate() { - if (!currentUser?.data) { - mostrarMensagem('error', 'Você precisa estar autenticado para criar templates.'); - return; - } - - // Validações - if (!codigoTemplate.trim()) { - mostrarMensagem('error', 'O código do template é obrigatório.'); - return; - } - if (!nomeTemplate.trim()) { - mostrarMensagem('error', 'O nome do template é obrigatório.'); - return; - } - if (!tituloTemplate.trim()) { - mostrarMensagem('error', 'O título do template é obrigatório.'); - return; - } - if (!corpoTemplate.trim()) { - mostrarMensagem('error', 'O corpo do template é obrigatório.'); - return; - } - - // Processar variáveis (separadas por vírgula ou espaço) - const variaveis = variaveisTemplate - .split(/[,;\s]+/) - .map((v) => v.trim()) - .filter((v) => v.length > 0); - - criandoNovoTemplate = true; - try { - const resultado = await client.mutation(api.templatesMensagens.criarTemplate, { - codigo: codigoTemplate.trim().toUpperCase().replace(/\s+/g, '_'), - nome: nomeTemplate.trim(), - titulo: tituloTemplate.trim(), - corpo: corpoTemplate.trim(), - variaveis: variaveis.length > 0 ? variaveis : undefined, - criadoPorId: currentUser.data._id as Id<'usuarios'> - }); - - if (resultado.sucesso) { - mostrarMensagem('success', 'Template criado com sucesso!'); - fecharModalNovoTemplate(); - // Recarregar a página para atualizar a lista - setTimeout(() => { - window.location.reload(); - }, 1500); - } else { - mostrarMensagem( - 'error', - 'Erro ao criar template: ' + (resultado.erro || 'Erro desconhecido') - ); - } - } catch (error) { - const erro = error instanceof Error ? error.message : 'Erro desconhecido'; - console.error('Erro ao criar template:', error); - mostrarMensagem('error', 'Erro ao criar template: ' + erro); - } finally { - criandoNovoTemplate = false; - } - } - - async function enviarNotificacao() { - if (!enviarParaTodos && !destinatarioId) { - mostrarMensagem('error', "Selecione um destinatário ou marque 'Enviar para todos'"); - return; - } - - if (usarTemplate && !templateId) { - mostrarMensagem('error', 'Selecione um template'); - return; - } - - if (!usarTemplate && !mensagemPersonalizada.trim()) { - mostrarMensagem('error', 'Digite uma mensagem'); - return; - } - - // Validar agendamento se marcado - let agendadaPara: number | undefined = undefined; - if (agendarEnvio) { - if (!dataAgendamento || !horaAgendamento) { - mostrarMensagem('error', 'Preencha a data e hora para agendamento'); - return; - } - - try { - const dataHora = new Date(`${dataAgendamento}T${horaAgendamento}`); - if (dataHora.getTime() <= Date.now()) { - mostrarMensagem('error', 'A data e hora devem ser futuras'); - return; - } - agendadaPara = dataHora.getTime(); - } catch (error) { - mostrarMensagem('error', 'Data ou hora inválida'); - return; - } - } - - processando = true; - progressoEnvio = { total: 0, enviados: 0, falhas: 0 }; - - // Limpar logs anteriores quando iniciar novo envio - logsEnvio = []; - emailIdsRastreados = new Set(); - - try { - // Obter lista de destinatários - const destinatarios: typeof usuarios = enviarParaTodos - ? usuarios - : usuarios.filter((u) => u._id === destinatarioId); - - if (destinatarios.length === 0) { - adicionarLog('email', 'Sistema', 'erro', 'Nenhum destinatário encontrado'); - mostrarMensagem('error', 'Nenhum destinatário encontrado'); - return; - } - - progressoEnvio.total = destinatarios.length; - - // Log inicial - const tipoMensagem = usarTemplate - ? `Template: ${templateSelecionado?.nome || ''}` - : 'Mensagem personalizada'; - const destinatariosText = enviarParaTodos - ? `Todos os usuários (${destinatarios.length})` - : destinatarios.map((d) => d.nome).join(', '); - adicionarLog( - 'email', - 'Sistema', - 'info', - `Iniciando envio de notificação via ${canal} para ${destinatariosText} - ${tipoMensagem}` - ); - - // Se for envio para um único usuário - if (destinatarios.length === 1) { - const destinatario = destinatarios[0]; - let resultadoChat = null; - let resultadoEmail = null; - - // ENVIAR PARA CHAT - if (canal === 'chat' || canal === 'ambos') { - try { - adicionarLog('chat', destinatario.nome, 'enviando', 'Criando/buscando conversa...'); - const conversaId = await client.mutation(api.chat.criarOuBuscarConversaIndividual, { - outroUsuarioId: destinatario._id as Id<'usuarios'> - }); - - if (conversaId) { - const mensagem = - usarTemplate && templateSelecionado - ? renderizarTemplate(templateSelecionado.corpo, { - nome: destinatario.nome, - matricula: destinatario.matricula || '' - }) - : mensagemPersonalizada; - - if (agendadaPara) { - // Agendar mensagem - adicionarLog('chat', destinatario.nome, 'info', 'Agendando mensagem...'); - resultadoChat = await client.mutation(api.chat.agendarMensagem, { - conversaId: conversaId, - conteudo: mensagem, - agendadaPara: agendadaPara - }); - const dataFormatada = format(new Date(agendadaPara), "dd/MM/yyyy 'às' HH:mm", { - locale: ptBR - }); - adicionarLog( - 'chat', - destinatario.nome, - 'sucesso', - `Mensagem agendada para ${dataFormatada}` - ); - } else { - // Envio imediato - adicionarLog('chat', destinatario.nome, 'enviando', 'Enviando mensagem...'); - resultadoChat = await client.mutation(api.chat.enviarMensagem, { - conversaId: conversaId, - conteudo: mensagem, - tipo: 'texto', - permitirNotificacaoParaSiMesmo: true - }); - adicionarLog('chat', destinatario.nome, 'sucesso', 'Mensagem enviada com sucesso'); - } - } else { - adicionarLog('chat', destinatario.nome, 'erro', 'Falha ao criar/buscar conversa'); - } - } catch (error) { - const erro = error instanceof Error ? error.message : 'Erro desconhecido'; - console.error('Erro ao enviar chat:', error); - adicionarLog('chat', destinatario.nome, 'erro', `Erro: ${erro}`); - } - } - - // ENVIAR PARA EMAIL - if (canal === 'email' || canal === 'ambos') { - if (destinatario.email) { - try { - adicionarLog( - 'email', - destinatario.nome, - 'enviando', - `Enfileirando email para ${destinatario.email}...` - ); - if (usarTemplate && templateId) { - const template = templateSelecionado; - if (template) { - const emailId = await client.action(api.email.enviarEmailComTemplate, { - destinatario: destinatario.email, - destinatarioId: destinatario._id as Id<'usuarios'>, - templateCodigo: template.codigo, - variaveis: { - nome: destinatario.nome, - matricula: destinatario.matricula - }, - enviadoPor: currentUser.data._id as Id<'usuarios'>, - agendadaPara: agendadaPara - }); - if (emailId) { - if (agendadaPara) { - const dataFormatada = format( - new Date(agendadaPara), - "dd/MM/yyyy 'às' HH:mm", - { locale: ptBR } - ); - adicionarLog( - 'email', - destinatario.nome, - 'fila', - `Email agendado para ${dataFormatada}`, - emailId - ); - } else { - adicionarLog( - 'email', - destinatario.nome, - 'fila', - 'Email enfileirado para envio', - emailId - ); - } - } else { - adicionarLog('email', destinatario.nome, 'erro', 'Falha ao enfileirar email'); - } - } else { - adicionarLog('email', destinatario.nome, 'erro', 'Template não encontrado'); - } - } else { - const emailId = await client.mutation(api.email.enfileirarEmail, { - destinatario: destinatario.email, - destinatarioId: destinatario._id as Id<'usuarios'>, - assunto: 'Notificação do Sistema', - corpo: mensagemPersonalizada, - enviadoPor: currentUser.data._id as Id<'usuarios'>, - agendadaPara: agendadaPara - }); - if (emailId) { - resultadoEmail = { sucesso: true, emailId }; - if (agendadaPara) { - const dataFormatada = format(new Date(agendadaPara), "dd/MM/yyyy 'às' HH:mm", { - locale: ptBR - }); - adicionarLog( - 'email', - destinatario.nome, - 'fila', - `Email agendado para ${dataFormatada}`, - emailId - ); - } else { - adicionarLog( - 'email', - destinatario.nome, - 'fila', - 'Email enfileirado para envio', - emailId - ); - } - } else { - adicionarLog('email', destinatario.nome, 'erro', 'Falha ao enfileirar email'); - } - } - } catch (error) { - const erro = error instanceof Error ? error.message : 'Erro desconhecido'; - console.error('Erro ao enviar email:', error); - adicionarLog('email', destinatario.nome, 'erro', `Erro: ${erro}`); - } - } else { - adicionarLog( - 'email', - destinatario.nome, - 'erro', - 'Destinatário não possui email cadastrado' - ); - } - } - - // Feedback de sucesso - let mensagemSucesso = agendadaPara - ? `Notificação agendada com sucesso!` - : 'Notificação enviada com sucesso!'; - if (agendadaPara) { - const dataFormatada = format(new Date(agendadaPara), "dd/MM/yyyy 'às' HH:mm", { - locale: ptBR - }); - mensagemSucesso += ` Será enviada em: ${dataFormatada}`; - } else { - if (canal === 'ambos') { - if (resultadoChat && resultadoEmail) { - mensagemSucesso = 'Notificação enviada para Chat e Email!'; - } else if (resultadoChat) { - mensagemSucesso = 'Notificação enviada para Chat. Email falhou.'; - } else if (resultadoEmail) { - mensagemSucesso = 'Notificação enviada para Email. Chat falhou.'; - } - } else if (canal === 'chat' && resultadoChat) { - mensagemSucesso = 'Mensagem enviada no Chat!'; - } else if (canal === 'email' && resultadoEmail) { - mensagemSucesso = 'Email enfileirado para envio!'; - } - } - - mostrarMensagem('success', mensagemSucesso); - progressoEnvio.enviados = 1; - } else { - // ENVIO EM MASSA - let sucessosChat = 0; - let sucessosEmail = 0; - let falhasChat = 0; - let falhasEmail = 0; - - adicionarLog( - 'email', - 'Sistema', - 'info', - `Processando ${destinatarios.length} destinatários...` - ); - - for (const destinatario of destinatarios) { - try { - // ENVIAR PARA CHAT - if (canal === 'chat' || canal === 'ambos') { - try { - adicionarLog('chat', destinatario.nome, 'enviando', 'Processando...'); - const conversaId = await client.mutation(api.chat.criarOuBuscarConversaIndividual, { - outroUsuarioId: destinatario._id as Id<'usuarios'> - }); - - if (conversaId) { - // Renderizar template com variáveis do destinatário - const mensagem = - usarTemplate && templateSelecionado - ? renderizarTemplate(templateSelecionado.corpo, { - nome: destinatario.nome, - matricula: destinatario.matricula || '' - }) - : mensagemPersonalizada; - - if (agendadaPara) { - await client.mutation(api.chat.agendarMensagem, { - conversaId: conversaId, - conteudo: mensagem, - agendadaPara: agendadaPara - }); - const dataFormatada = format(new Date(agendadaPara), "dd/MM/yyyy 'às' HH:mm", { - locale: ptBR - }); - adicionarLog( - 'chat', - destinatario.nome, - 'sucesso', - `Agendado para ${dataFormatada}` - ); - } else { - await client.mutation(api.chat.enviarMensagem, { - conversaId: conversaId, - conteudo: mensagem, - tipo: 'texto', - permitirNotificacaoParaSiMesmo: true - }); - adicionarLog('chat', destinatario.nome, 'sucesso', 'Enviado com sucesso'); - } - sucessosChat++; - } else { - adicionarLog('chat', destinatario.nome, 'erro', 'Falha ao criar/buscar conversa'); - falhasChat++; - } - } catch (error) { - const erro = error instanceof Error ? error.message : 'Erro desconhecido'; - console.error(`Erro ao enviar chat para ${destinatario.nome}:`, error); - adicionarLog('chat', destinatario.nome, 'erro', `Erro: ${erro}`); - falhasChat++; - } - } - - // ENVIAR PARA EMAIL - if (canal === 'email' || canal === 'ambos') { - if (destinatario.email) { - try { - adicionarLog( - 'email', - destinatario.nome, - 'enviando', - `Enfileirando email para ${destinatario.email}...` - ); - if (usarTemplate && templateId) { - const template = templateSelecionado; - if (template) { - const emailId = await client.action(api.email.enviarEmailComTemplate, { - destinatario: destinatario.email, - destinatarioId: destinatario._id as Id<'usuarios'>, - templateCodigo: template.codigo, - variaveis: { - nome: destinatario.nome, - matricula: destinatario.matricula || '' - }, - enviadoPor: currentUser.data._id as Id<'usuarios'>, - agendadaPara: agendadaPara - }); - if (emailId) { - if (agendadaPara) { - const dataFormatada = format( - new Date(agendadaPara), - "dd/MM/yyyy 'às' HH:mm", - { locale: ptBR } - ); - adicionarLog( - 'email', - destinatario.nome, - 'fila', - `Agendado para ${dataFormatada}`, - emailId - ); - } else { - adicionarLog( - 'email', - destinatario.nome, - 'fila', - 'Enfileirado para envio', - emailId - ); - } - sucessosEmail++; - } else { - adicionarLog( - 'email', - destinatario.nome, - 'erro', - 'Falha ao enfileirar email' - ); - falhasEmail++; - } - } else { - adicionarLog('email', destinatario.nome, 'erro', 'Template não encontrado'); - falhasEmail++; - } - } else { - const emailId = await client.mutation(api.email.enfileirarEmail, { - destinatario: destinatario.email, - destinatarioId: destinatario._id as Id<'usuarios'>, - assunto: 'Notificação do Sistema', - corpo: mensagemPersonalizada, - enviadoPor: currentUser.data?._id as Id<'usuarios'>, - agendadaPara: agendadaPara - }); - if (emailId) { - resultadoEmail = { sucesso: true, emailId }; - if (agendadaPara) { - const dataFormatada = format( - new Date(agendadaPara), - "dd/MM/yyyy 'às' HH:mm", - { locale: ptBR } - ); - adicionarLog( - 'email', - destinatario.nome, - 'fila', - `Agendado para ${dataFormatada}`, - emailId - ); - } else { - adicionarLog( - 'email', - destinatario.nome, - 'fila', - 'Enfileirado para envio', - emailId - ); - } - sucessosEmail++; - } else { - adicionarLog('email', destinatario.nome, 'erro', 'Falha ao enfileirar email'); - falhasEmail++; - } - } - } catch (error) { - const erro = error instanceof Error ? error.message : 'Erro desconhecido'; - console.error(`Erro ao enviar email para ${destinatario.nome}:`, error); - adicionarLog('email', destinatario.nome, 'erro', `Erro: ${erro}`); - falhasEmail++; - } - } else { - adicionarLog( - 'email', - destinatario.nome, - 'erro', - 'Destinatário não possui email cadastrado' - ); - falhasEmail++; - } - } - - progressoEnvio.enviados++; - } catch (error) { - console.error(`Erro geral ao enviar para ${destinatario.nome}:`, error); - progressoEnvio.falhas++; - } - } - - // Feedback de envio em massa - let mensagemMassa = agendadaPara - ? `Agendamento em massa concluído! ` - : `Envio em massa concluído! `; - - if (agendadaPara) { - const dataFormatada = format(new Date(agendadaPara), "dd/MM/yyyy 'às' HH:mm", { - locale: ptBR - }); - mensagemMassa += `Será enviado em: ${dataFormatada}. `; - } - - if (canal === 'ambos') { - mensagemMassa += `Chat: ${sucessosChat} ${agendadaPara ? 'agendados' : 'enviados'}, ${falhasChat} falhas. `; - mensagemMassa += `Email: ${sucessosEmail} ${agendadaPara ? 'agendados' : 'enviados'}, ${falhasEmail} falhas.`; - } else if (canal === 'chat') { - mensagemMassa += `Chat: ${sucessosChat} ${agendadaPara ? 'agendados' : 'enviados'}, ${falhasChat} falhas.`; - } else if (canal === 'email') { - mensagemMassa += `Email: ${sucessosEmail} ${agendadaPara ? 'agendados' : 'enviados'}, ${falhasEmail} falhas.`; - } - - // Adicionar log resumo - adicionarLog('email', 'Sistema', 'info', mensagemMassa); - mostrarMensagem('success', mensagemMassa); - } - - // Limpar form - destinatarioId = ''; - enviarParaTodos = false; - templateId = ''; - mensagemPersonalizada = ''; - agendarEnvio = false; - dataAgendamento = ''; - horaAgendamento = ''; - } catch (error) { - const erro = error instanceof Error ? error.message : 'Erro desconhecido'; - console.error('Erro ao enviar notificação:', error); - adicionarLog('email', 'Sistema', 'erro', `Erro geral: ${erro}`); - mostrarMensagem('error', 'Erro ao enviar notificação: ' + erro); - } finally { - processando = false; - progressoEnvio = { total: 0, enviados: 0, falhas: 0 }; - adicionarLog('email', 'Sistema', 'info', 'Processo de envio finalizado'); - } - } + import { useQuery, useConvexClient } from "convex-svelte"; + import { api } from "@sgse-app/backend/convex/_generated/api"; + import { format } from "date-fns"; + import { ptBR } from "date-fns/locale"; + import type { Id, Doc } from "@sgse-app/backend/convex/_generated/dataModel"; + + // Tipos para agendamentos + type TipoAgendamento = "email" | "chat"; + type StatusAgendamento = "agendado" | "enviado" | "cancelado"; + + interface AgendamentoEmail { + _id: Id<"notificacoesEmail">; + _creationTime: number; + destinatario: string; + destinatarioId: Id<"usuarios"> | undefined; + assunto: string; + corpo: string; + templateId: Id<"templatesMensagens"> | undefined; + status: "pendente" | "enviando" | "enviado" | "falha"; + agendadaPara: number | undefined; + enviadoPor: Id<"usuarios">; + criadoEm: number; + enviadoEm: number | undefined; + destinatarioInfo: Doc<"usuarios"> | null; + templateInfo: Doc<"templatesMensagens"> | null; + } + + interface AgendamentoChat { + _id: Id<"mensagens">; + _creationTime: number; + conversaId: Id<"conversas">; + remetenteId: Id<"usuarios">; + conteudo: string; + agendadaPara: number | undefined; + enviadaEm: number; + conversaInfo: Doc<"conversas"> | null; + destinatarioInfo: Doc<"usuarios"> | null; + } + + type Agendamento = + | { tipo: "email"; dados: AgendamentoEmail } + | { tipo: "chat"; dados: AgendamentoChat }; + + const client = useConvexClient(); + const currentUser = useQuery(api.auth.getCurrentUser, {}); + + // Queries + const templatesQuery = useQuery(api.templatesMensagens.listarTemplates, {}); + const usuariosQuery = useQuery(api.usuarios.listar, {}); + + // Mapa de emailIds para rastrear status + let emailIdsRastreados = $state>(new Set()); + + // Query para buscar status dos emails (só executa quando há IDs) + const emailIdsArray = $derived( + Array.from(emailIdsRastreados).map((id) => id as Id<"notificacoesEmail">), + ); + // Usar função para evitar execução quando array está vazio + const emailsStatusQuery = $derived.by(() => { + if (emailIdsArray.length === 0) return null; + return useQuery(api.email.buscarEmailsPorIds, { emailIds: emailIdsArray }); + }); + + // Queries para agendamentos + const agendamentosEmailQuery = useQuery( + api.email.listarAgendamentosEmail, + {}, + ); + const agendamentosChatQuery = useQuery(api.chat.listarAgendamentosChat, {}); + + // Filtro de agendamentos + type FiltroAgendamento = "todos" | "agendados" | "enviados"; + let filtroAgendamento = $state("todos"); + + // Extrair dados das queries de forma robusta + const templates = $derived.by(() => { + if (templatesQuery === undefined || templatesQuery === null) { + return []; + } + if ("data" in templatesQuery && templatesQuery.data !== undefined) { + return Array.isArray(templatesQuery.data) ? templatesQuery.data : []; + } + if (Array.isArray(templatesQuery)) { + return templatesQuery; + } + return []; + }); + + const usuarios = $derived.by(() => { + if (usuariosQuery === undefined || usuariosQuery === null) { + return []; + } + if ("data" in usuariosQuery && usuariosQuery.data !== undefined) { + return Array.isArray(usuariosQuery.data) ? usuariosQuery.data : []; + } + if (Array.isArray(usuariosQuery)) { + return usuariosQuery; + } + return []; + }); + + // Estados de carregamento e erro + const carregandoTemplates = $derived( + templatesQuery === undefined || templatesQuery === null, + ); + const carregandoUsuarios = $derived( + usuariosQuery === undefined || usuariosQuery === null, + ); + + // Verificar erros de forma mais robusta + const erroTemplates = $derived.by(() => { + if (templatesQuery === undefined || templatesQuery === null) return false; + // Verificar se é um objeto com propriedade error + if (typeof templatesQuery === "object" && "error" in templatesQuery) { + return ( + templatesQuery.error !== undefined && templatesQuery.error !== null + ); + } + return false; + }); + + const erroUsuarios = $derived.by(() => { + if (usuariosQuery === undefined || usuariosQuery === null) return false; + if (typeof usuariosQuery === "object" && "error" in usuariosQuery) { + return usuariosQuery.error !== undefined && usuariosQuery.error !== null; + } + return false; + }); + + // Log para debug (remover depois se necessário) + $effect(() => { + if (templatesQuery !== undefined && templatesQuery !== null) { + console.log("Templates Query:", templatesQuery); + console.log("Templates Extraídos:", templates); + } + }); + + let destinatarioId = $state(""); + let enviarParaTodos = $state(false); + let canal = $state<"chat" | "email" | "ambos">("chat"); + let templateId = $state(""); + let mensagemPersonalizada = $state(""); + let usarTemplate = $state(true); + let processando = $state(false); + let criandoTemplates = $state(false); + let progressoEnvio = $state({ total: 0, enviados: 0, falhas: 0 }); + + // Estrutura de dados para logs de envio + type StatusLog = "sucesso" | "erro" | "fila" | "info" | "enviando"; + type TipoLog = "chat" | "email"; + type LogEnvio = { + timestamp: number; + tipo: TipoLog; + destinatario: string; + status: StatusLog; + mensagem: string; + emailId?: string; // Para emails, guardar o ID para rastrear status + }; + + let logsEnvio = $state([]); + let terminalScrollRef: HTMLDivElement | null = $state(null); + + // Estados para agendamento + let agendarEnvio = $state(false); + let dataAgendamento = $state(""); + let horaAgendamento = $state(""); + + // Calcular data/hora mínimas + const now = new Date(); + const minDate = format(now, "yyyy-MM-dd"); + + // Hora mínima recalculada baseada na data selecionada + const horaMinima = $derived.by(() => { + if (!dataAgendamento) return format(now, "HH:mm"); + const hoje = format(now, "yyyy-MM-dd"); + if (dataAgendamento === hoje) { + return format(now, "HH:mm"); + } + return undefined; // Sem restrição se for data futura + }); + + function getPreviewAgendamento(): string { + if (!agendarEnvio || !dataAgendamento || !horaAgendamento) return ""; + try { + const dataHora = new Date(`${dataAgendamento}T${horaAgendamento}`); + return `Será enviada em ${format(dataHora, "dd/MM/yyyy 'às' HH:mm", { locale: ptBR })}`; + } catch { + return ""; + } + } + + // Estados para modal de novo template + let modalNovoTemplateAberto = $state(false); + let codigoTemplate = $state(""); + let nomeTemplate = $state(""); + let tituloTemplate = $state(""); + let corpoTemplate = $state(""); + let variaveisTemplate = $state(""); + let criandoNovoTemplate = $state(false); + + // Estado para mensagens de feedback + let mensagem = $state<{ + tipo: "success" | "error" | "info"; + texto: string; + } | null>(null); + + const templateSelecionado = $derived( + templates.find((t) => t._id === templateId), + ); + + // Função para renderizar template com variáveis (similar à função do backend) + function renderizarTemplate( + template: string, + variaveis: Record, + ): string { + let resultado = template; + + for (const [chave, valor] of Object.entries(variaveis)) { + const placeholder = `{{${chave}}}`; + resultado = resultado.replace(new RegExp(placeholder, "g"), valor); + } + + return resultado; + } + + // Função para mostrar mensagens + function mostrarMensagem(tipo: "success" | "error" | "info", texto: string) { + mensagem = { tipo, texto }; + setTimeout(() => { + mensagem = null; + }, 5000); + } + + // Função para adicionar log ao terminal + function adicionarLog( + tipo: TipoLog, + destinatario: string, + status: StatusLog, + mensagem: string, + emailId?: string, + ) { + logsEnvio = [ + ...logsEnvio, + { + timestamp: Date.now(), + tipo, + destinatario, + status, + mensagem, + emailId, + }, + ]; + + // Adicionar emailId ao rastreamento se fornecido + if (emailId) { + emailIdsRastreados = new Set([...emailIdsRastreados, emailId]); + } + + // Auto-scroll para o final + setTimeout(() => { + if (terminalScrollRef) { + terminalScrollRef.scrollTop = terminalScrollRef.scrollHeight; + } + }, 10); + } + + // Atualizar logs quando status dos emails mudar + $effect(() => { + if (!emailsStatusQuery || emailsStatusQuery === undefined) return; + + // Extrair dados da query + const emails = Array.isArray(emailsStatusQuery) + ? emailsStatusQuery + : "data" in emailsStatusQuery && Array.isArray(emailsStatusQuery.data) + ? emailsStatusQuery.data + : []; + + if (emails.length === 0) return; + + for (const email of emails) { + if (!email) continue; + + // Encontrar logs relacionados a este email + const logsRelacionados = logsEnvio.filter( + (log) => log.emailId === email._id, + ); + + for (const log of logsRelacionados) { + // Verificar se o status mudou + const novoStatus: StatusLog = + email.status === "enviado" + ? "sucesso" + : email.status === "falha" + ? "erro" + : email.status === "enviando" + ? "enviando" + : email.status === "pendente" + ? "fila" + : "info"; + + // Se o status mudou, atualizar o log + if (log.status !== novoStatus) { + const indice = logsEnvio.findIndex((l) => l === log); + if (indice !== -1) { + const novaMensagem = + email.status === "enviado" + ? "Email enviado com sucesso" + : email.status === "falha" + ? `Falha ao enviar: ${email.erroDetalhes || "Erro desconhecido"}` + : email.status === "enviando" + ? "Enviando email..." + : email.status === "pendente" + ? "Email em fila de envio" + : log.mensagem; + + logsEnvio = logsEnvio.map((l, i) => + i === indice + ? { ...l, status: novoStatus, mensagem: novaMensagem } + : l, + ); + } + } + } + } + }); + + // Função para limpar logs + function limparLogs() { + logsEnvio = []; + emailIdsRastreados = new Set(); + } + + // Extrair e processar agendamentos + const agendamentosEmail = $derived.by(() => { + if (!agendamentosEmailQuery || agendamentosEmailQuery === undefined) + return []; + const dados = Array.isArray(agendamentosEmailQuery) + ? agendamentosEmailQuery + : "data" in agendamentosEmailQuery && + Array.isArray(agendamentosEmailQuery.data) + ? agendamentosEmailQuery.data + : []; + return dados as AgendamentoEmail[]; + }); + + const agendamentosChat = $derived.by(() => { + if (!agendamentosChatQuery || agendamentosChatQuery === undefined) + return []; + const dados = Array.isArray(agendamentosChatQuery) + ? agendamentosChatQuery + : "data" in agendamentosChatQuery && + Array.isArray(agendamentosChatQuery.data) + ? agendamentosChatQuery.data + : []; + return dados as AgendamentoChat[]; + }); + + // Combinar e processar agendamentos + const todosAgendamentos = $derived.by(() => { + const agendamentos: Agendamento[] = []; + + for (const email of agendamentosEmail) { + if (email.agendadaPara) { + agendamentos.push({ + tipo: "email", + dados: email, + }); + } + } + + for (const chat of agendamentosChat) { + if (chat.agendadaPara) { + agendamentos.push({ + tipo: "chat", + dados: chat, + }); + } + } + + // Ordenar: futuros primeiro (mais próximos primeiro), depois passados (mais recentes primeiro) + return agendamentos.sort((a, b) => { + const timestampA = + a.tipo === "email" + ? (a.dados.agendadaPara ?? 0) + : (a.dados.agendadaPara ?? 0); + const timestampB = + b.tipo === "email" + ? (b.dados.agendadaPara ?? 0) + : (b.dados.agendadaPara ?? 0); + const agora = Date.now(); + + const aFuturo = timestampA > agora; + const bFuturo = timestampB > agora; + + // Futuros primeiro + if (aFuturo && !bFuturo) return -1; + if (!aFuturo && bFuturo) return 1; + + // Dentro do mesmo grupo, ordenar por timestamp + if (aFuturo) { + // Futuros: mais próximos primeiro + return timestampA - timestampB; + } else { + // Passados: mais recentes primeiro + return timestampB - timestampA; + } + }); + }); + + // Filtrar agendamentos + const agendamentosFiltrados = $derived.by(() => { + if (filtroAgendamento === "todos") return todosAgendamentos; + + return todosAgendamentos.filter((ag) => { + const status = obterStatusAgendamento(ag); + if (filtroAgendamento === "agendados") return status === "agendado"; + if (filtroAgendamento === "enviados") return status === "enviado"; + return true; + }); + }); + + // Função para obter status do agendamento + function obterStatusAgendamento(agendamento: Agendamento): StatusAgendamento { + if (agendamento.tipo === "email") { + const email = agendamento.dados; + if (email.status === "enviado") return "enviado"; + if (email.agendadaPara && email.agendadaPara <= Date.now()) + return "enviado"; + return "agendado"; + } else { + const chat = agendamento.dados; + if (chat.agendadaPara && chat.agendadaPara <= Date.now()) + return "enviado"; + return "agendado"; + } + } + + // Função para cancelar agendamento + async function cancelarAgendamento(agendamento: Agendamento) { + if (!confirm("Tem certeza que deseja cancelar este agendamento?")) { + return; + } + + try { + if (agendamento.tipo === "email") { + const resultado = await client.mutation( + api.email.cancelarAgendamentoEmail, + { + emailId: agendamento.dados._id, + }, + ); + if (resultado.sucesso) { + mostrarMensagem( + "success", + "Agendamento de email cancelado com sucesso!", + ); + } else { + mostrarMensagem( + "error", + resultado.erro || "Erro ao cancelar agendamento", + ); + } + } else { + const resultado = await client.mutation( + api.chat.cancelarMensagemAgendada, + { + mensagemId: agendamento.dados._id, + }, + ); + if (resultado.sucesso) { + mostrarMensagem( + "success", + "Agendamento de chat cancelado com sucesso!", + ); + } else { + mostrarMensagem( + "error", + resultado.erro || "Erro ao cancelar agendamento", + ); + } + } + } catch (error) { + const erro = error instanceof Error ? error.message : "Erro desconhecido"; + mostrarMensagem("error", `Erro ao cancelar agendamento: ${erro}`); + } + } + + // Função para obter nome do destinatário + function obterNomeDestinatario(agendamento: Agendamento): string { + if (agendamento.tipo === "email") { + return ( + agendamento.dados.destinatarioInfo?.nome || + agendamento.dados.destinatario || + "Usuário" + ); + } else { + return agendamento.dados.destinatarioInfo?.nome || "Usuário"; + } + } + + // Função para formatar data/hora do agendamento + function formatarDataAgendamento(agendamento: Agendamento): string { + const timestamp = + agendamento.tipo === "email" + ? agendamento.dados.agendadaPara + : agendamento.dados.agendadaPara; + + if (!timestamp) return "N/A"; + + return format(new Date(timestamp), "dd/MM/yyyy 'às' HH:mm", { + locale: ptBR, + }); + } + + // Função para formatar timestamp + function formatarTimestamp(timestamp: number): string { + return format(new Date(timestamp), "HH:mm:ss", { locale: ptBR }); + } + + // Função para obter cor do status + function obterCorStatus(status: StatusLog): string { + switch (status) { + case "sucesso": + return "text-success"; + case "erro": + return "text-error"; + case "fila": + return "text-warning"; + case "enviando": + return "text-info"; + case "info": + return "text-info"; + default: + return "text-base-content"; + } + } + + async function criarTemplatesPadrao() { + if (criandoTemplates) return; + + criandoTemplates = true; + try { + const resultado = await client.mutation( + api.templatesMensagens.criarTemplatesPadrao, + {}, + ); + if (resultado.sucesso) { + mostrarMensagem( + "success", + "Templates padrão criados com sucesso! A página será recarregada.", + ); + setTimeout(() => { + window.location.reload(); + }, 2000); + } else { + mostrarMensagem("error", "Erro ao criar templates padrão."); + } + } catch (error) { + const erro = error instanceof Error ? error.message : "Erro desconhecido"; + console.error("Erro ao criar templates:", error); + mostrarMensagem("error", "Erro ao criar templates: " + erro); + } finally { + criandoTemplates = false; + } + } + + function abrirModalNovoTemplate() { + modalNovoTemplateAberto = true; + // Limpar campos + codigoTemplate = ""; + nomeTemplate = ""; + tituloTemplate = ""; + corpoTemplate = ""; + variaveisTemplate = ""; + } + + function fecharModalNovoTemplate() { + modalNovoTemplateAberto = false; + } + + async function salvarNovoTemplate() { + if (!currentUser?.data) { + mostrarMensagem( + "error", + "Você precisa estar autenticado para criar templates.", + ); + return; + } + + // Validações + if (!codigoTemplate.trim()) { + mostrarMensagem("error", "O código do template é obrigatório."); + return; + } + if (!nomeTemplate.trim()) { + mostrarMensagem("error", "O nome do template é obrigatório."); + return; + } + if (!tituloTemplate.trim()) { + mostrarMensagem("error", "O título do template é obrigatório."); + return; + } + if (!corpoTemplate.trim()) { + mostrarMensagem("error", "O corpo do template é obrigatório."); + return; + } + + // Processar variáveis (separadas por vírgula ou espaço) + const variaveis = variaveisTemplate + .split(/[,;\s]+/) + .map((v) => v.trim()) + .filter((v) => v.length > 0); + + criandoNovoTemplate = true; + try { + const resultado = await client.mutation( + api.templatesMensagens.criarTemplate, + { + codigo: codigoTemplate.trim().toUpperCase().replace(/\s+/g, "_"), + nome: nomeTemplate.trim(), + titulo: tituloTemplate.trim(), + corpo: corpoTemplate.trim(), + variaveis: variaveis.length > 0 ? variaveis : undefined, + criadoPorId: currentUser.data._id as Id<"usuarios">, + }, + ); + + if (resultado.sucesso) { + mostrarMensagem("success", "Template criado com sucesso!"); + fecharModalNovoTemplate(); + // Recarregar a página para atualizar a lista + setTimeout(() => { + window.location.reload(); + }, 1500); + } else { + mostrarMensagem( + "error", + "Erro ao criar template: " + (resultado.erro || "Erro desconhecido"), + ); + } + } catch (error) { + const erro = error instanceof Error ? error.message : "Erro desconhecido"; + console.error("Erro ao criar template:", error); + mostrarMensagem("error", "Erro ao criar template: " + erro); + } finally { + criandoNovoTemplate = false; + } + } + + async function enviarNotificacao() { + if (!enviarParaTodos && !destinatarioId) { + mostrarMensagem( + "error", + "Selecione um destinatário ou marque 'Enviar para todos'", + ); + return; + } + + if (usarTemplate && !templateId) { + mostrarMensagem("error", "Selecione um template"); + return; + } + + if (!usarTemplate && !mensagemPersonalizada.trim()) { + mostrarMensagem("error", "Digite uma mensagem"); + return; + } + + // Validar agendamento se marcado + let agendadaPara: number | undefined = undefined; + if (agendarEnvio) { + if (!dataAgendamento || !horaAgendamento) { + mostrarMensagem("error", "Preencha a data e hora para agendamento"); + return; + } + + try { + const dataHora = new Date(`${dataAgendamento}T${horaAgendamento}`); + if (dataHora.getTime() <= Date.now()) { + mostrarMensagem("error", "A data e hora devem ser futuras"); + return; + } + agendadaPara = dataHora.getTime(); + } catch (error) { + mostrarMensagem("error", "Data ou hora inválida"); + return; + } + } + + processando = true; + progressoEnvio = { total: 0, enviados: 0, falhas: 0 }; + + // Limpar logs anteriores quando iniciar novo envio + logsEnvio = []; + emailIdsRastreados = new Set(); + + try { + // Obter lista de destinatários + const destinatarios: typeof usuarios = enviarParaTodos + ? usuarios + : usuarios.filter((u) => u._id === destinatarioId); + + if (destinatarios.length === 0) { + adicionarLog( + "email", + "Sistema", + "erro", + "Nenhum destinatário encontrado", + ); + mostrarMensagem("error", "Nenhum destinatário encontrado"); + return; + } + + progressoEnvio.total = destinatarios.length; + + // Log inicial + const tipoMensagem = usarTemplate + ? `Template: ${templateSelecionado?.nome || ""}` + : "Mensagem personalizada"; + const destinatariosText = enviarParaTodos + ? `Todos os usuários (${destinatarios.length})` + : destinatarios.map((d) => d.nome).join(", "); + adicionarLog( + "email", + "Sistema", + "info", + `Iniciando envio de notificação via ${canal} para ${destinatariosText} - ${tipoMensagem}`, + ); + + // Se for envio para um único usuário + if (destinatarios.length === 1) { + const destinatario = destinatarios[0]; + let resultadoChat = null; + let resultadoEmail = null; + + // ENVIAR PARA CHAT + if (canal === "chat" || canal === "ambos") { + try { + adicionarLog( + "chat", + destinatario.nome, + "enviando", + "Criando/buscando conversa...", + ); + const conversaId = await client.mutation( + api.chat.criarOuBuscarConversaIndividual, + { outroUsuarioId: destinatario._id as Id<"usuarios"> }, + ); + + if (conversaId) { + const mensagem = + usarTemplate && templateSelecionado + ? renderizarTemplate(templateSelecionado.corpo, { + nome: destinatario.nome, + matricula: destinatario.matricula || "", + }) + : mensagemPersonalizada; + + if (agendadaPara) { + // Agendar mensagem + adicionarLog( + "chat", + destinatario.nome, + "info", + "Agendando mensagem...", + ); + resultadoChat = await client.mutation( + api.chat.agendarMensagem, + { + conversaId: conversaId, + conteudo: mensagem, + agendadaPara: agendadaPara, + }, + ); + const dataFormatada = format( + new Date(agendadaPara), + "dd/MM/yyyy 'às' HH:mm", + { locale: ptBR }, + ); + adicionarLog( + "chat", + destinatario.nome, + "sucesso", + `Mensagem agendada para ${dataFormatada}`, + ); + } else { + // Envio imediato + adicionarLog( + "chat", + destinatario.nome, + "enviando", + "Enviando mensagem...", + ); + resultadoChat = await client.mutation(api.chat.enviarMensagem, { + conversaId: conversaId, + conteudo: mensagem, + tipo: "texto", + permitirNotificacaoParaSiMesmo: true, + }); + adicionarLog( + "chat", + destinatario.nome, + "sucesso", + "Mensagem enviada com sucesso", + ); + } + } else { + adicionarLog( + "chat", + destinatario.nome, + "erro", + "Falha ao criar/buscar conversa", + ); + } + } catch (error) { + const erro = + error instanceof Error ? error.message : "Erro desconhecido"; + console.error("Erro ao enviar chat:", error); + adicionarLog("chat", destinatario.nome, "erro", `Erro: ${erro}`); + } + } + + // ENVIAR PARA EMAIL + if (canal === "email" || canal === "ambos") { + if (destinatario.email) { + try { + adicionarLog( + "email", + destinatario.nome, + "enviando", + `Enfileirando email para ${destinatario.email}...`, + ); + if (usarTemplate && templateId) { + const template = templateSelecionado; + if (template) { + const emailId = await client.action( + api.email.enviarEmailComTemplate, + { + destinatario: destinatario.email, + destinatarioId: destinatario._id as Id<"usuarios">, + templateCodigo: template.codigo, + variaveis: { + nome: destinatario.nome, + matricula: destinatario.matricula, + }, + enviadoPor: currentUser.data._id as Id<"usuarios">, + agendadaPara: agendadaPara, + }, + ); + if (emailId) { + if (agendadaPara) { + const dataFormatada = format( + new Date(agendadaPara), + "dd/MM/yyyy 'às' HH:mm", + { locale: ptBR }, + ); + adicionarLog( + "email", + destinatario.nome, + "fila", + `Email agendado para ${dataFormatada}`, + emailId, + ); + } else { + adicionarLog( + "email", + destinatario.nome, + "fila", + "Email enfileirado para envio", + emailId, + ); + } + } else { + adicionarLog( + "email", + destinatario.nome, + "erro", + "Falha ao enfileirar email", + ); + } + } else { + adicionarLog( + "email", + destinatario.nome, + "erro", + "Template não encontrado", + ); + } + } else { + const emailId = await client.mutation( + api.email.enfileirarEmail, + { + destinatario: destinatario.email, + destinatarioId: destinatario._id as Id<"usuarios">, + assunto: "Notificação do Sistema", + corpo: mensagemPersonalizada, + enviadoPor: currentUser.data._id as Id<"usuarios">, + agendadaPara: agendadaPara, + }, + ); + if (emailId) { + resultadoEmail = { sucesso: true, emailId }; + if (agendadaPara) { + const dataFormatada = format( + new Date(agendadaPara), + "dd/MM/yyyy 'às' HH:mm", + { locale: ptBR }, + ); + adicionarLog( + "email", + destinatario.nome, + "fila", + `Email agendado para ${dataFormatada}`, + emailId, + ); + } else { + adicionarLog( + "email", + destinatario.nome, + "fila", + "Email enfileirado para envio", + emailId, + ); + } + } else { + adicionarLog( + "email", + destinatario.nome, + "erro", + "Falha ao enfileirar email", + ); + } + } + } catch (error) { + const erro = + error instanceof Error ? error.message : "Erro desconhecido"; + console.error("Erro ao enviar email:", error); + adicionarLog("email", destinatario.nome, "erro", `Erro: ${erro}`); + } + } else { + adicionarLog( + "email", + destinatario.nome, + "erro", + "Destinatário não possui email cadastrado", + ); + } + } + + // Feedback de sucesso + let mensagemSucesso = agendadaPara + ? `Notificação agendada com sucesso!` + : "Notificação enviada com sucesso!"; + if (agendadaPara) { + const dataFormatada = format( + new Date(agendadaPara), + "dd/MM/yyyy 'às' HH:mm", + { locale: ptBR }, + ); + mensagemSucesso += ` Será enviada em: ${dataFormatada}`; + } else { + if (canal === "ambos") { + if (resultadoChat && resultadoEmail) { + mensagemSucesso = "Notificação enviada para Chat e Email!"; + } else if (resultadoChat) { + mensagemSucesso = "Notificação enviada para Chat. Email falhou."; + } else if (resultadoEmail) { + mensagemSucesso = "Notificação enviada para Email. Chat falhou."; + } + } else if (canal === "chat" && resultadoChat) { + mensagemSucesso = "Mensagem enviada no Chat!"; + } else if (canal === "email" && resultadoEmail) { + mensagemSucesso = "Email enfileirado para envio!"; + } + } + + mostrarMensagem("success", mensagemSucesso); + progressoEnvio.enviados = 1; + } else { + // ENVIO EM MASSA + let sucessosChat = 0; + let sucessosEmail = 0; + let falhasChat = 0; + let falhasEmail = 0; + + adicionarLog( + "email", + "Sistema", + "info", + `Processando ${destinatarios.length} destinatários...`, + ); + + for (const destinatario of destinatarios) { + try { + // ENVIAR PARA CHAT + if (canal === "chat" || canal === "ambos") { + try { + adicionarLog( + "chat", + destinatario.nome, + "enviando", + "Processando...", + ); + const conversaId = await client.mutation( + api.chat.criarOuBuscarConversaIndividual, + { outroUsuarioId: destinatario._id as Id<"usuarios"> }, + ); + + if (conversaId) { + // Renderizar template com variáveis do destinatário + const mensagem = + usarTemplate && templateSelecionado + ? renderizarTemplate(templateSelecionado.corpo, { + nome: destinatario.nome, + matricula: destinatario.matricula || "", + }) + : mensagemPersonalizada; + + if (agendadaPara) { + await client.mutation(api.chat.agendarMensagem, { + conversaId: conversaId, + conteudo: mensagem, + agendadaPara: agendadaPara, + }); + const dataFormatada = format( + new Date(agendadaPara), + "dd/MM/yyyy 'às' HH:mm", + { locale: ptBR }, + ); + adicionarLog( + "chat", + destinatario.nome, + "sucesso", + `Agendado para ${dataFormatada}`, + ); + } else { + await client.mutation(api.chat.enviarMensagem, { + conversaId: conversaId, + conteudo: mensagem, + tipo: "texto", + permitirNotificacaoParaSiMesmo: true, + }); + adicionarLog( + "chat", + destinatario.nome, + "sucesso", + "Enviado com sucesso", + ); + } + sucessosChat++; + } else { + adicionarLog( + "chat", + destinatario.nome, + "erro", + "Falha ao criar/buscar conversa", + ); + falhasChat++; + } + } catch (error) { + const erro = + error instanceof Error ? error.message : "Erro desconhecido"; + console.error( + `Erro ao enviar chat para ${destinatario.nome}:`, + error, + ); + adicionarLog( + "chat", + destinatario.nome, + "erro", + `Erro: ${erro}`, + ); + falhasChat++; + } + } + + // ENVIAR PARA EMAIL + if (canal === "email" || canal === "ambos") { + if (destinatario.email) { + try { + adicionarLog( + "email", + destinatario.nome, + "enviando", + `Enfileirando email para ${destinatario.email}...`, + ); + if (usarTemplate && templateId) { + const template = templateSelecionado; + if (template) { + const emailId = await client.action( + api.email.enviarEmailComTemplate, + { + destinatario: destinatario.email, + destinatarioId: destinatario._id as Id<"usuarios">, + templateCodigo: template.codigo, + variaveis: { + nome: destinatario.nome, + matricula: destinatario.matricula || "", + }, + enviadoPor: currentUser.data._id as Id<"usuarios">, + agendadaPara: agendadaPara, + }, + ); + if (emailId) { + if (agendadaPara) { + const dataFormatada = format( + new Date(agendadaPara), + "dd/MM/yyyy 'às' HH:mm", + { locale: ptBR }, + ); + adicionarLog( + "email", + destinatario.nome, + "fila", + `Agendado para ${dataFormatada}`, + emailId, + ); + } else { + adicionarLog( + "email", + destinatario.nome, + "fila", + "Enfileirado para envio", + emailId, + ); + } + sucessosEmail++; + } else { + adicionarLog( + "email", + destinatario.nome, + "erro", + "Falha ao enfileirar email", + ); + falhasEmail++; + } + } else { + adicionarLog( + "email", + destinatario.nome, + "erro", + "Template não encontrado", + ); + falhasEmail++; + } + } else { + const emailId = await client.mutation( + api.email.enfileirarEmail, + { + destinatario: destinatario.email, + destinatarioId: destinatario._id as Id<"usuarios">, + assunto: "Notificação do Sistema", + corpo: mensagemPersonalizada, + enviadoPor: currentUser.data?._id as Id<"usuarios">, + agendadaPara: agendadaPara, + }, + ); + if (emailId) { + resultadoEmail = { sucesso: true, emailId }; + if (agendadaPara) { + const dataFormatada = format( + new Date(agendadaPara), + "dd/MM/yyyy 'às' HH:mm", + { locale: ptBR }, + ); + adicionarLog( + "email", + destinatario.nome, + "fila", + `Agendado para ${dataFormatada}`, + emailId, + ); + } else { + adicionarLog( + "email", + destinatario.nome, + "fila", + "Enfileirado para envio", + emailId, + ); + } + sucessosEmail++; + } else { + adicionarLog( + "email", + destinatario.nome, + "erro", + "Falha ao enfileirar email", + ); + falhasEmail++; + } + } + } catch (error) { + const erro = + error instanceof Error + ? error.message + : "Erro desconhecido"; + console.error( + `Erro ao enviar email para ${destinatario.nome}:`, + error, + ); + adicionarLog( + "email", + destinatario.nome, + "erro", + `Erro: ${erro}`, + ); + falhasEmail++; + } + } else { + adicionarLog( + "email", + destinatario.nome, + "erro", + "Destinatário não possui email cadastrado", + ); + falhasEmail++; + } + } + + progressoEnvio.enviados++; + } catch (error) { + console.error( + `Erro geral ao enviar para ${destinatario.nome}:`, + error, + ); + progressoEnvio.falhas++; + } + } + + // Feedback de envio em massa + let mensagemMassa = agendadaPara + ? `Agendamento em massa concluído! ` + : `Envio em massa concluído! `; + + if (agendadaPara) { + const dataFormatada = format( + new Date(agendadaPara), + "dd/MM/yyyy 'às' HH:mm", + { locale: ptBR }, + ); + mensagemMassa += `Será enviado em: ${dataFormatada}. `; + } + + if (canal === "ambos") { + mensagemMassa += `Chat: ${sucessosChat} ${agendadaPara ? "agendados" : "enviados"}, ${falhasChat} falhas. `; + mensagemMassa += `Email: ${sucessosEmail} ${agendadaPara ? "agendados" : "enviados"}, ${falhasEmail} falhas.`; + } else if (canal === "chat") { + mensagemMassa += `Chat: ${sucessosChat} ${agendadaPara ? "agendados" : "enviados"}, ${falhasChat} falhas.`; + } else if (canal === "email") { + mensagemMassa += `Email: ${sucessosEmail} ${agendadaPara ? "agendados" : "enviados"}, ${falhasEmail} falhas.`; + } + + // Adicionar log resumo + adicionarLog("email", "Sistema", "info", mensagemMassa); + mostrarMensagem("success", mensagemMassa); + } + + // Limpar form + destinatarioId = ""; + enviarParaTodos = false; + templateId = ""; + mensagemPersonalizada = ""; + agendarEnvio = false; + dataAgendamento = ""; + horaAgendamento = ""; + } catch (error) { + const erro = error instanceof Error ? error.message : "Erro desconhecido"; + console.error("Erro ao enviar notificação:", error); + adicionarLog("email", "Sistema", "erro", `Erro geral: ${erro}`); + mostrarMensagem("error", "Erro ao enviar notificação: " + erro); + } finally { + processando = false; + progressoEnvio = { total: 0, enviados: 0, falhas: 0 }; + adicionarLog("email", "Sistema", "info", "Processo de envio finalizado"); + } + } -
- -
-
-
- - - -
-
-

Notificações e Mensagens

-

Enviar notificações para usuários do sistema

-
-
-
+
+ +
+
+
+ + + +
+
+

+ Notificações e Mensagens +

+

+ Enviar notificações para usuários do sistema +

+
+
+
- - {#if mensagem} -
- - {#if mensagem.tipo === 'success'} - - {:else if mensagem.tipo === 'error'} - - {:else} - - {/if} - - {mensagem.texto} - -
- {/if} + + {#if mensagem} +
+ + {#if mensagem.tipo === "success"} + + {:else if mensagem.tipo === "error"} + + {:else} + + {/if} + + {mensagem.texto} + +
+ {/if} -
- -
-
-

Enviar Notificação

+
+ +
+
+

Enviar Notificação

- -
-
- - -
- - {#if enviarParaTodos} - - {/if} -
+ +
+
+ + +
+ + {#if enviarParaTodos} + + {/if} +
- -
-
- Canal de Envio * -
-
- - - -
-
+ +
+
+ Canal de Envio * +
+
+ + + +
+
- -
-
- Tipo de Mensagem -
-
- - -
-
+ +
+
+ Tipo de Mensagem +
+
+ + +
+
- {#if usarTemplate} - -
- - -
+ {#if usarTemplate} + +
+ + +
- {#if templateSelecionado} -
- - - -
-
{templateSelecionado.titulo}
-
{templateSelecionado.corpo}
-
-
- {/if} - {:else} - -
- - -
- {/if} + {#if templateSelecionado} +
+ + + +
+
{templateSelecionado.titulo}
+
{templateSelecionado.corpo}
+
+
+ {/if} + {:else} + +
+ + +
+ {/if} - -
- + +
+ - {#if agendarEnvio} -
-
- - -
+ {#if agendarEnvio} +
+
+ + +
-
- - -
-
+
+ + +
+
- {#if getPreviewAgendamento()} -
- - - - {getPreviewAgendamento()} -
- {/if} - {/if} -
+ {#if getPreviewAgendamento()} +
+ + + + {getPreviewAgendamento()} +
+ {/if} + {/if} +
- -
- -
+ +
+ +
- -
-
- - {#if logsEnvio.length > 0} - - {/if} -
-
- {#if logsEnvio.length === 0} -
Aguardando envio de notificação...
- {:else} - {#each logsEnvio as log} -
- [{formatarTimestamp(log.timestamp)}] - - {log.tipo.toUpperCase()} - - {log.destinatario}: - - {log.mensagem} - -
- {/each} - {/if} -
-
-
-
+ +
+
+ + {#if logsEnvio.length > 0} + + {/if} +
+
+ {#if logsEnvio.length === 0} +
+ Aguardando envio de notificação... +
+ {:else} + {#each logsEnvio as log} +
+ [{formatarTimestamp(log.timestamp)}] + + {log.tipo.toUpperCase()} + + {log.destinatario}: + + {log.mensagem} + +
+ {/each} + {/if} +
+
+
+
- -
-
-
-

Templates Disponíveis

- -
+ +
+
+
+

Templates Disponíveis

+ +
- {#if carregandoTemplates} -
- -

Carregando templates...

-
- {:else if templates.length > 0} - -
- {#each templates as template} -
-
-
-
-

{template.nome}

-

{template.titulo}

-

{template.corpo}

-
- - {template.tipo} - - {#if template.variaveis && template.variaveis.length > 0} - - {template.variaveis.length} variáveis - - {/if} -
-
- {#if template.tipo !== 'sistema'} - - {/if} -
-
-
- {/each} -
- {:else} - -
- - - -

Nenhum template disponível

-

- Clique no botão abaixo para criar os templates padrão do sistema. -

- -
- {/if} -
-
-
+ {#if carregandoTemplates} +
+ +

Carregando templates...

+
+ {:else if templates.length > 0} + +
+ {#each templates as template} +
+
+
+
+

{template.nome}

+

{template.titulo}

+

{template.corpo}

+
+ + {template.tipo} + + {#if template.variaveis && template.variaveis.length > 0} + + {template.variaveis.length} variáveis + + {/if} +
+
+ {#if template.tipo !== "sistema"} + + {/if} +
+
+
+ {/each} +
+ {:else} + +
+ + + +

+ Nenhum template disponível +

+

+ Clique no botão abaixo para criar os templates padrão do sistema. +

+ +
+ {/if} +
+
+
- -
-
-
-
-
- - - -
-

Histórico de Agendamentos

-
+ +
+
+
+
+
+ + + +
+

Histórico de Agendamentos

+
- -
- - - -
-
+ +
+ + + +
+
- {#if agendamentosFiltrados.length === 0} -
- - - -

Nenhum agendamento encontrado

-

- Os agendamentos aparecerão aqui quando você agendar envios. -

-
- {:else} - -
- - - - - - - - - - - - - {#each agendamentosFiltrados as agendamento} - {@const status = obterStatusAgendamento(agendamento)} - {@const nomeDestinatario = obterNomeDestinatario(agendamento)} - {@const dataFormatada = formatarDataAgendamento(agendamento)} - {@const podeCancelar = status === 'agendado'} - {@const templateNome = - agendamento.tipo === 'email' && agendamento.dados.templateInfo - ? agendamento.dados.templateInfo.nome - : agendamento.tipo === 'email' && agendamento.dados.templateId - ? 'Template removido' - : '-'} - - - - - - - - - {/each} - -
TipoDestinatárioData/HoraStatusTemplateAções
-
- {#if agendamento.tipo === 'email'} - - - - Email - {:else} - - - - Chat - {/if} -
-
-
{nomeDestinatario}
- {#if agendamento.tipo === 'email'} -
- {agendamento.dados.destinatario} -
- {/if} -
-
{dataFormatada}
- {#if podeCancelar} - {@const tempoRestante = - agendamento.tipo === 'email' - ? (agendamento.dados.agendadaPara ?? 0) - Date.now() - : (agendamento.dados.agendadaPara ?? 0) - Date.now()} - {@const horasRestantes = Math.floor(tempoRestante / (1000 * 60 * 60))} - {@const minutosRestantes = Math.floor( - (tempoRestante % (1000 * 60 * 60)) / (1000 * 60) - )} - {#if horasRestantes < 1 && minutosRestantes < 60} -
- Em {minutosRestantes} min -
- {:else if horasRestantes < 24} -
- Em {horasRestantes}h {minutosRestantes}min -
- {/if} - {/if} -
- {#if status === 'agendado'} - Agendado - {:else if status === 'enviado'} - Enviado - {:else} - Cancelado - {/if} - - {#if agendamento.tipo === 'email'} - {#if agendamento.dados.templateInfo} -
- {agendamento.dados.templateInfo.nome} -
- {:else if agendamento.dados.templateId} -
Template removido
- {:else} -
-
- {/if} - {:else} -
-
- {/if} -
- {#if podeCancelar} - - {:else} - - - {/if} -
-
- {/if} -
-
+ {#if agendamentosFiltrados.length === 0} +
+ + + +

+ Nenhum agendamento encontrado +

+

+ Os agendamentos aparecerão aqui quando você agendar envios. +

+
+ {:else} + +
+ + + + + + + + + + + + + {#each agendamentosFiltrados as agendamento} + {@const status = obterStatusAgendamento(agendamento)} + {@const nomeDestinatario = obterNomeDestinatario(agendamento)} + {@const dataFormatada = formatarDataAgendamento(agendamento)} + {@const podeCancelar = status === "agendado"} + {@const templateNome = + agendamento.tipo === "email" && agendamento.dados.templateInfo + ? agendamento.dados.templateInfo.nome + : agendamento.tipo === "email" && + agendamento.dados.templateId + ? "Template removido" + : "-"} + + + + + + + + + {/each} + +
TipoDestinatárioData/HoraStatusTemplateAções
+
+ {#if agendamento.tipo === "email"} + + + + Email + {:else} + + + + Chat + {/if} +
+
+
{nomeDestinatario}
+ {#if agendamento.tipo === "email"} +
+ {agendamento.dados.destinatario} +
+ {/if} +
+
{dataFormatada}
+ {#if podeCancelar} + {@const tempoRestante = + agendamento.tipo === "email" + ? (agendamento.dados.agendadaPara ?? 0) - Date.now() + : (agendamento.dados.agendadaPara ?? 0) - Date.now()} + {@const horasRestantes = Math.floor( + tempoRestante / (1000 * 60 * 60), + )} + {@const minutosRestantes = Math.floor( + (tempoRestante % (1000 * 60 * 60)) / (1000 * 60), + )} + {#if horasRestantes < 1 && minutosRestantes < 60} +
+ Em {minutosRestantes} min +
+ {:else if horasRestantes < 24} +
+ Em {horasRestantes}h {minutosRestantes}min +
+ {/if} + {/if} +
+ {#if status === "agendado"} + Agendado + {:else if status === "enviado"} + Enviado + {:else} + Cancelado + {/if} + + {#if agendamento.tipo === "email"} + {#if agendamento.dados.templateInfo} +
+ {agendamento.dados.templateInfo.nome} +
+ {:else if agendamento.dados.templateId} +
+ Template removido +
+ {:else} +
-
+ {/if} + {:else} +
-
+ {/if} +
+ {#if podeCancelar} + + {:else} + - + {/if} +
+
+ {/if} +
+
- -
- - - - Para enviar emails, certifique-se de configurar o SMTP em Configurações de Email. -
+ +
+ + + + Para enviar emails, certifique-se de configurar o SMTP em Configurações + de Email. +
{#if modalNovoTemplateAberto} - {/if} diff --git a/apps/web/src/routes/(dashboard)/ti/painel-permissoes/+page.svelte b/apps/web/src/routes/(dashboard)/ti/painel-permissoes/+page.svelte index 5592266..8424660 100644 --- a/apps/web/src/routes/(dashboard)/ti/painel-permissoes/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/painel-permissoes/+page.svelte @@ -1,799 +1,848 @@ - - -
+ + + - -
-
-
- - - -
-
-

- Gerenciar Perfis & Permissões de Acesso -

-

- Configure as permissões de acesso aos menus do sistema por função -

-
- - -
-
+ +
+
+
+ + + +
+
+

+ Gerenciar Perfis & Permissões de Acesso +

+

+ Configure as permissões de acesso aos menus do sistema por função +

+
+ + +
+
- - {#if mensagem} -
- {#if mensagem.tipo === 'success'} - - - - {:else} - - - - {/if} - {mensagem.texto} -
- {/if} + + {#if mensagem} +
+ {#if mensagem.tipo === "success"} + + + + {:else} + + + + {/if} + {mensagem.texto} +
+ {/if} - -
-
-
- -
- -
- - - - -
-
+ +
+
+
+ +
+ +
+ + + + +
+
- -
- - -
-
+ +
+ + +
+
- {#if busca || filtroRole} -
- Filtros ativos: - {#if busca} -
- Busca: {busca} - -
- {/if} - {#if filtroRole} -
- Perfil filtrado - -
- {/if} -
- {/if} -
-
+ {#if busca || filtroRole} +
+ Filtros ativos: + {#if busca} +
+ Busca: {busca} + +
+ {/if} + {#if filtroRole} +
+ Perfil filtrado + +
+ {/if} +
+ {/if} +
+
- -
- - - -
-

Como funciona o sistema de permissões:

-
-
-

Tipos de Permissão:

-
    -
  • - • Acessar: Visualizar menu e acessar página -
  • -
  • Consultar: Ver dados (requer "Acessar")
  • -
  • - • Gravar: Criar/editar/excluir (requer "Consultar") -
  • -
-
-
-

Perfis Especiais:

-
    -
  • Admin e TI: Acesso total automático
  • -
  • Dashboard: Público para todos
  • -
  • - • Perfil Customizado: Permissões personalizadas -
  • -
-
-
-
-
+ +
+ + + +
+

Como funciona o sistema de permissões:

+
+
+

Tipos de Permissão:

+
    +
  • + • Acessar: Visualizar menu e acessar página +
  • +
  • Consultar: Ver dados (requer "Acessar")
  • +
  • + • Gravar: Criar/editar/excluir (requer "Consultar") +
  • +
+
+
+

Perfis Especiais:

+
    +
  • Admin e TI: Acesso total automático
  • +
  • Dashboard: Público para todos
  • +
  • + • Perfil Customizado: Permissões personalizadas +
  • +
+
+
+
+
- - {#if rolesQuery.isLoading || catalogoQuery.isLoading} -
- -
- {:else if rolesQuery.error} -
- - - - Erro ao carregar perfis: {rolesQuery.error.message} -
- {:else if rolesQuery.data && catalogoQuery.data} - {#if rolesFiltradas.length === 0} -
-
- - - -

Nenhum resultado encontrado

-

- {busca - ? `Não foram encontrados perfis com "${busca}"` - : 'Nenhum perfil corresponde aos filtros aplicados'} -

- -
-
- {/if} + + {#if rolesQuery.isLoading || catalogoQuery.isLoading} +
+ +
+ {:else if rolesQuery.error} +
+ + + + Erro ao carregar perfis: {rolesQuery.error.message} +
+ {:else if rolesQuery.data && catalogoQuery.data} + {#if rolesFiltradas.length === 0} +
+
+ + + +

Nenhum resultado encontrado

+

+ {busca + ? `Não foram encontrados perfis com "${busca}"` + : "Nenhum perfil corresponde aos filtros aplicados"} +

+ +
+
+ {/if} - {#each rolesFiltradas as roleRow} - {@const roleId = roleRow._id} -
-
-
-
-
-

{roleRow.descricao}

-
- Nível {roleRow.nivel} -
- {#if roleRow.nivel <= 1} -
- - - - Acesso Total -
- {/if} -
-

- {roleRow.nome} -

-
-
- -
-
+ {#each rolesFiltradas as roleRow} + {@const roleId = roleRow._id} +
+
+
+
+
+

{roleRow.descricao}

+
+ Nível {roleRow.nivel} +
+ {#if roleRow.nivel <= 1} +
+ + + + Acesso Total +
+ {/if} +
+

+ {roleRow.nome} +

+
+
+ +
+
- {#if roleRow.nivel <= 1} -
- - - -
-

Perfil Administrativo

-
- Este perfil possui acesso total ao sistema automaticamente, sem necessidade de - configuração manual. -
-
-
- {:else if catalogoQuery.data} -
- {#each catalogoQuery.data as item} - {@const recursoExpandido = isRecursoExpandido(roleId, item.recurso)} -
- - + {#if roleRow.nivel <= 1} +
+ + + +
+

Perfil Administrativo

+
+ Este perfil possui acesso total ao sistema automaticamente, + sem necessidade de configuração manual. +
+
+
+ {:else if catalogoQuery.data} +
+ {#each catalogoQuery.data as item} + {@const recursoExpandido = isRecursoExpandido( + roleId, + item.recurso, + )} +
+ + - - {#if recursoExpandido} -
-
- {#each ['ver', 'listar', 'criar', 'editar', 'excluir'] as acao} - - {/each} -
-
- {/if} -
- {/each} -
- {/if} -
-
- {/each} - {/if} + + {#if recursoExpandido} +
+
+ {#each ["ver", "listar", "criar", "editar", "excluir"] as acao} + + {/each} +
+
+ {/if} +
+ {/each} +
+ {/if} +
+
+ {/each} + {/if} - - {#if modalGerenciarPerfisAberto} - - - - - {/if} +
+

+ Campos marcados com * são obrigatórios. +

+
+ + +
+
+
+ + + + {/if} diff --git a/apps/web/src/routes/(dashboard)/ti/perfis/+page.svelte b/apps/web/src/routes/(dashboard)/ti/perfis/+page.svelte index 7d3ab7d..6232f81 100644 --- a/apps/web/src/routes/(dashboard)/ti/perfis/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/perfis/+page.svelte @@ -1,786 +1,846 @@ - -
- -
-
-
- - - -
-
-

Gestão de Perfis

-

- Visualize e gerencie os perfis de acesso do sistema -

-
-
-
+ +
+ +
+
+
+ + + +
+
+

Gestão de Perfis

+

+ Visualize e gerencie os perfis de acesso do sistema +

+
+
+
- - {#if stats} -
- - - - - 0 - ? ((stats.comSetor / stats.total) * 100).toFixed(0) + '% do total' - : '0%'} - Icon={Building2} - color="secondary" - /> -
- {/if} + + {#if stats} +
+ + + + + 0 + ? ((stats.comSetor / stats.total) * 100).toFixed(0) + "% do total" + : "0%"} + Icon={Building2} + color="secondary" + /> +
+ {/if} - - {#if !carregando && roles.length > 0} -
-
-
-
- - - -

Filtros de Busca

-
- {#if temFiltrosAtivos} - - {/if} -
+ + {#if !carregando && roles.length > 0} +
+
+
+
+ + + +

Filtros de Busca

+
+ {#if temFiltrosAtivos} + + {/if} +
-
- -
- -
- - - - -
-
+
+ +
+ +
+ + + + +
+
- -
- - -
+ +
+ + +
- -
- - -
-
+ +
+ + +
+
-
-
- {rolesFiltradas.length} - de - {roles.length} - perfil(is) - {#if temFiltrosAtivos} - Filtrado - {/if} -
-
-
-
- {/if} +
+
+ {rolesFiltradas.length} + de + {roles.length} + perfil(is) + {#if temFiltrosAtivos} + Filtrado + {/if} +
+
+
+
+ {/if} - - {#if carregando} -
- -
- {:else if roles.length === 0} -
- - - -

Nenhum perfil encontrado

-

Não há perfis cadastrados no sistema.

-
- {:else if rolesFiltradas.length === 0} -
-
-
- - - -

Nenhum perfil encontrado

-

- Nenhum perfil corresponde aos filtros aplicados. -

- {#if temFiltrosAtivos} - - {/if} -
-
-
- {:else} -
- {#each rolesFiltradas as role} -
abrirDetalhes(role)} - > -
-
-
-

{role.descricao}

-
- {obterTextoNivel(role.nivel)} -
-
-
- - - -
-
+ + {#if carregando} +
+ +
+ {:else if roles.length === 0} +
+ + + +

Nenhum perfil encontrado

+

+ Não há perfis cadastrados no sistema. +

+
+ {:else if rolesFiltradas.length === 0} +
+
+
+ + + +

Nenhum perfil encontrado

+

+ Nenhum perfil corresponde aos filtros aplicados. +

+ {#if temFiltrosAtivos} + + {/if} +
+
+
+ {:else} +
+ {#each rolesFiltradas as role} +
abrirDetalhes(role)} + > +
+
+
+

{role.descricao}

+
+ {obterTextoNivel(role.nivel)} +
+
+
+ + + +
+
-
-
- - - - Nome técnico: - {role.nome} -
+
+
+ + + + Nome técnico: + {role.nome} +
- {#if role.setor} -
- - - - Setor: - {role.setor} -
- {/if} + {#if role.setor} +
+ + + + Setor: + {role.setor} +
+ {/if} -
- - - - Nível: - {role.nivel} -
-
+
+ + + + Nível: + {role.nivel} +
+
-
- -
-
-
- {/each} -
- {/if} -
+
+ +
+
+
+ {/each} +
+ {/if} +
- - {#if modalDetalhesAberto && roleSelecionada} - + {/if}
diff --git a/apps/web/src/routes/(dashboard)/ti/personalizar-permissoes/+page.svelte b/apps/web/src/routes/(dashboard)/ti/personalizar-permissoes/+page.svelte index 5ec6985..8aaa195 100644 --- a/apps/web/src/routes/(dashboard)/ti/personalizar-permissoes/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/personalizar-permissoes/+page.svelte @@ -1,100 +1,107 @@ - - - + + + - -
-
-
- - - -
-
-

Funcionalidade descontinuada

-

- Agora as permissões são configuradas por ação em cada perfil no painel de permissões. -

-
- -
-
-
- - - - - A personalização por usuário foi substituída por permissões por ação - por perfil. Utilize o - Painel de Permissões para configurar. - -
+ +
+
+
+ + + +
+
+

+ Funcionalidade descontinuada +

+

+ Agora as permissões são configuradas por ação em cada perfil no painel + de permissões. +

+
+ +
+
+
+ + + + + A personalização por usuário foi substituída por permissões por ação + por perfil. Utilize o + Painel de Permissões para configurar. + +
diff --git a/apps/web/src/routes/(dashboard)/ti/solicitacoes-acesso/+page.svelte b/apps/web/src/routes/(dashboard)/ti/solicitacoes-acesso/+page.svelte index b63e18f..43dfb7f 100644 --- a/apps/web/src/routes/(dashboard)/ti/solicitacoes-acesso/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/solicitacoes-acesso/+page.svelte @@ -1,836 +1,694 @@ - -
- - {#if mensagem} -
- {#if mensagem.tipo === 'success'} - - - - {:else if mensagem.tipo === 'error'} - - - - {/if} - {mensagem.texto} -
- {/if} + +
+ + {#if mensagem} +
+ {#if mensagem.tipo === "success"} + + + + {:else if mensagem.tipo === "error"} + + + + {/if} + {mensagem.texto} +
+ {/if} - -
-
-
- - - -
-
-

Solicitações de Acesso

-

- Gerencie e analise solicitações de acesso ao sistema -

-
-
-
+ +
+
+
+ + + +
+
+

Solicitações de Acesso

+

Gerencie e analise solicitações de acesso ao sistema

+
+
+
- - {#if stats} -
- + + {#if stats} +
+ + + + + + + +
+ {:else} +
+ +
+ {/if} - 0 - ? ((stats.pendentes / stats.total) * 100).toFixed(1) + '% do total' - : '0% do total'} - Icon={Clock} - color="warning" - /> + +
+
+ +
+ + + + +
- 0 - ? ((stats.aprovadas / stats.total) * 100).toFixed(1) + '% do total' - : '0% do total'} - Icon={CheckCircle2} - color="success" - /> + +
+ +
+ + + + +
+
+
+
- 0 - ? ((stats.rejeitadas / stats.total) * 100).toFixed(1) + '% do total' - : '0% do total'} - Icon={XCircle} - color="error" - /> -
- {:else} -
- -
- {/if} + + {#if carregando} +
+ +
+ {:else if solicitacoesFiltradas.length === 0} +
+
+ + + +

Nenhuma solicitação encontrada

+

+ {#if busca.trim() || filtroStatus !== "todos"} + Tente ajustar os filtros ou a busca. + {:else} + Ainda não há solicitações de acesso cadastradas. + {/if} +

+
+
+ {:else} +
+ {#each solicitacoesFiltradas as solicitacao} +
+
+
+
+
+

{solicitacao.nome}

+ + {getStatusTexto(solicitacao.status)} + +
+ +
+
+ + + + Matrícula: + {solicitacao.matricula} +
+ +
+ + + + E-mail: + {solicitacao.email} +
+ +
+ + + + Telefone: + {solicitacao.telefone} +
+
+ +
+ Solicitado em: {formatarData(solicitacao.dataSolicitacao)} ({formatarDataRelativa(solicitacao.dataSolicitacao)}) + {#if solicitacao.dataResposta} + Processado em: {formatarData(solicitacao.dataResposta)} + {/if} +
+
+ +
+ + + {#if solicitacao.status === "pendente"} + + + + {/if} +
+
+
+
+ {/each} +
+ {/if} - -
-
- -
- - - - -
+ + {#if modalDetalhesAberto && solicitacaoSelecionada} + + + + + {/if} - -
- -
- - - - -
-
-
-
+ + {#if modalAprovarAberto && solicitacaoSelecionada} + + + + + {/if} - - {#if carregando} -
- -
- {:else if solicitacoesFiltradas.length === 0} -
-
- - - -

- Nenhuma solicitação encontrada -

-

- {#if busca.trim() || filtroStatus !== 'todos'} - Tente ajustar os filtros ou a busca. - {:else} - Ainda não há solicitações de acesso cadastradas. - {/if} -

-
-
- {:else} -
- {#each solicitacoesFiltradas as solicitacao} -
-
-
-
-
-

{solicitacao.nome}

- - {getStatusTexto(solicitacao.status)} - -
- -
-
- - - - Matrícula: - {solicitacao.matricula} -
- -
- - - - E-mail: - {solicitacao.email} -
- -
- - - - Telefone: - {solicitacao.telefone} -
-
- -
- Solicitado em: - {formatarData(solicitacao.dataSolicitacao)} ({formatarDataRelativa( - solicitacao.dataSolicitacao - )}) - {#if solicitacao.dataResposta} - Processado em: - {formatarData(solicitacao.dataResposta)} - {/if} -
-
- -
- - - {#if solicitacao.status === 'pendente'} - - - - {/if} -
-
-
-
- {/each} -
- {/if} - - - {#if modalDetalhesAberto && solicitacaoSelecionada} - - - - - {/if} - - - {#if modalAprovarAberto && solicitacaoSelecionada} - - - - - {/if} - - - {#if modalRejeitarAberto && solicitacaoSelecionada} - - - - - {/if} -
+ + {#if modalRejeitarAberto && solicitacaoSelecionada} + + + + + {/if} +
diff --git a/apps/web/src/routes/(dashboard)/ti/times/+page.svelte b/apps/web/src/routes/(dashboard)/ti/times/+page.svelte index 1cdc8bf..f342979 100644 --- a/apps/web/src/routes/(dashboard)/ti/times/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/times/+page.svelte @@ -1,811 +1,873 @@ - -
- - + +
+ + - -
-
-
-
- - - -
-
-

Gestão de Times

-

- Organize funcionários em equipes e defina gestores -

-
-
-
- - -
-
-
+ +
+
+
+
+ + + +
+
+

+ Gestão de Times +

+

+ Organize funcionários em equipes e defina gestores +

+
+
+
+ + +
+
+
- - {#if modoEdicao} -
-
-

- {timeEmEdicao ? 'Editar Time' : 'Novo Time'} -

+ + {#if modoEdicao} +
+
+

+ {timeEmEdicao ? "Editar Time" : "Novo Time"} +

-
-
- - -
+
+
+ + +
-
- - -
+
+ + +
-
- - -
+
+ + +
-
- -
- {#each coresDisponiveis as cor} - - {/each} -
-
-
+
+ +
+ {#each coresDisponiveis as cor} + + {/each} +
+
+
-
- - -
-
-
- {/if} +
+ + +
+
+
+ {/if} - - {#if carregando} -
- -
- {:else} -
- {#each times.filter((t: TimeComDetalhes) => t.ativo) as time} -
-
-
-
-
-

{time.nome}

-
- -
+ + {#if carregando} +
+ +
+ {:else} +
+ {#each times.filter((t: TimeComDetalhes) => t.ativo) as time} +
+
+
+
+
+

{time.nome}

+
+ +
-

- {time.descricao || 'Sem descrição'} -

+

+ {time.descricao || "Sem descrição"} +

-
+
-
-
- - - - Gestor: - {time.gestor?.nome || 'Não definido'} -
-
- - - - Membros: - {time.totalMembros || 0} -
-
+
+
+ + + + Gestor: + {time.gestor?.nome || "Não definido"} +
+
+ + + + Membros: + {time.totalMembros || 0} +
+
-
- -
-
-
- {/each} +
+ +
+
+
+ {/each} - {#if times.filter((t: TimeComDetalhes) => t.ativo).length === 0} -
-
- - - -

Nenhum time cadastrado

-

- Clique em "Novo Time" para criar seu primeiro time -

-
-
- {/if} -
- {/if} + {#if times.filter((t: TimeComDetalhes) => t.ativo).length === 0} +
+
+ + + +

Nenhum time cadastrado

+

+ Clique em "Novo Time" para criar seu primeiro time +

+
+
+ {/if} +
+ {/if} - - {#if mostrarModalMembros && timeParaMembros} - - + + + {/if} - - {#if mostrarConfirmacaoExclusao && timeParaExcluir} - - - - - {/if} -
+ + {#if mostrarConfirmacaoExclusao && timeParaExcluir} + + + + + {/if} +
diff --git a/apps/web/src/routes/(dashboard)/ti/usuarios/+page.svelte b/apps/web/src/routes/(dashboard)/ti/usuarios/+page.svelte index f93c768..c2974d8 100644 --- a/apps/web/src/routes/(dashboard)/ti/usuarios/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/usuarios/+page.svelte @@ -1,1310 +1,1403 @@ - -
- -
-
-
- - - -
-
-

Gestão de Usuários

-

Administre os usuários do sistema

-
-
- -
+ +
+ +
+
+
+ + + +
+
+

+ Gestão de Usuários +

+

+ Administre os usuários do sistema +

+
+
+ +
- - {#if !carregandoUsuarios && usuariosComProblemas.length > 0} -
- - - -
-

Atenção: Usuários com Problemas Detectados

-
-

- {usuariosComProblemas.length} usuário(s) possui(em) problemas que requerem atenção: -

-
    - {#each usuariosComProblemas.slice(0, 3) as usuario} -
  • - {usuario.nome} ({usuario.matricula}) - {#if usuario.avisos && usuario.avisos.length > 0} - - {usuario.avisos[0].mensagem} - {/if} -
  • - {/each} - {#if usuariosComProblemas.length > 3} -
  • - ... e mais {usuariosComProblemas.length - 3} usuário(s) -
  • - {/if} -
-

- Por favor, corrija os perfis desses usuários para garantir acesso adequado ao sistema. -

-
-
-
- {/if} + + {#if !carregandoUsuarios && usuariosComProblemas.length > 0} +
+ + + +
+

Atenção: Usuários com Problemas Detectados

+
+

+ {usuariosComProblemas.length} usuário(s) possui(em) problemas que requerem + atenção: +

+
    + {#each usuariosComProblemas.slice(0, 3) as usuario} +
  • + {usuario.nome} ({usuario.matricula}) + {#if usuario.avisos && usuario.avisos.length > 0} + - {usuario.avisos[0].mensagem} + {/if} +
  • + {/each} + {#if usuariosComProblemas.length > 3} +
  • + ... e mais {usuariosComProblemas.length - 3} usuário(s) +
  • + {/if} +
+

+ Por favor, corrija os perfis desses usuários para garantir acesso + adequado ao sistema. +

+
+
+
+ {/if} - - {#if mensagem} -
- {#if mensagem.tipo === 'success'} - - - - {:else if mensagem.tipo === 'error'} - - - - {:else} - - - - {/if} - {mensagem.texto} -
- {/if} + + {#if mensagem} +
+ {#if mensagem.tipo === "success"} + + + + {:else if mensagem.tipo === "error"} + + + + {:else} + + + + {/if} + {mensagem.texto} +
+ {/if} - - {#if !carregandoUsuarios && usuarios.length > 0} -
-
-
-

Filtros de Busca

- -
+ + {#if !carregandoUsuarios && usuarios.length > 0} +
+
+
+

Filtros de Busca

+ +
-
- -
- - -
+
+ +
+ + +
- -
- - -
+ +
+ + +
- -
- - -
+ +
+ + +
- -
- - -
+ +
+ + +
- -
- - -
+ +
+ + +
- -
- - -
+ +
+ + +
- -
- - -
+ +
+ + +
- -
- - -
-
+ +
+ + +
+
-
- Mostrando {usuariosFiltrados.length} de {usuarios.length} usuário(s) -
-
-
- {/if} +
+ Mostrando {usuariosFiltrados.length} de {usuarios.length} usuário(s) +
+
+
+ {/if} - - {#if carregandoUsuarios} -
- -

Carregando usuários...

-
- {:else if erroUsuarios} -
- - - -
-

Erro ao carregar usuários

-
{erroUsuarios}
-
- Por favor, recarregue a página ou entre em contato com o suporte técnico se o problema - persistir. -
-
-
- {:else if usuarios.length === 0} -
- - - -

Nenhum usuário encontrado

-

- Cadastre um usuário para começar a gestão de acessos. -

-
- {:else} -
-
-

Usuários ({usuarios.length})

+ + {#if carregandoUsuarios} +
+ +

Carregando usuários...

+
+ {:else if erroUsuarios} +
+ + + +
+

Erro ao carregar usuários

+
{erroUsuarios}
+
+ Por favor, recarregue a página ou entre em contato com o suporte + técnico se o problema persistir. +
+
+
+ {:else if usuarios.length === 0} +
+ + + +

Nenhum usuário encontrado

+

+ Cadastre um usuário para começar a gestão de acessos. +

+
+ {:else} +
+
+

Usuários ({usuarios.length})

-
- - - - - - - - - - - - - - - - - - {#each usuariosFiltrados as usuario} - - - - - - - - - - - - - - {/each} - -
MatrículaNomeEmailRole/PerfilSetorFuncionário VinculadoStatusPrimeiro AcessoÚltimo AcessoData de CriaçãoAções
{usuario.matricula}{usuario.nome}{usuario.email} -
- {#if usuario.role.erro} -
- - - - {usuario.role.descricao} -
- {#if usuario.avisos && usuario.avisos.length > 0} -
- -
- {/if} - {:else} -
- {usuario.role.nome} -
- {/if} -
-
{usuario.role.setor || '-'} - {#if usuario.funcionario} -
-
- - - - Associado -
-
- {usuario.funcionario.nome} -
- {#if usuario.funcionario.matricula} -
- Mat: {usuario.funcionario.matricula} -
- {/if} -
- {:else} -
- - - - Não associado -
- {/if} -
- - - {#if usuario.primeiroAcesso} -
Sim
- {:else} -
Não
- {/if} -
- {formatarData(usuario.ultimoAcesso)} - - {formatarData(usuario.criadoEm)} - - -
-
-
-
- {/if} -
+
+ + + + + + + + + + + + + + + + + + {#each usuariosFiltrados as usuario} + + + + + + + + + + + + + + {/each} + +
MatrículaNomeEmailRole/PerfilSetorFuncionário VinculadoStatusPrimeiro AcessoÚltimo AcessoData de CriaçãoAções
{usuario.matricula}{usuario.nome}{usuario.email} +
+ {#if usuario.role.erro} +
+ + + + {usuario.role.descricao} +
+ {#if usuario.avisos && usuario.avisos.length > 0} +
+ +
+ {/if} + {:else} +
+ {usuario.role.nome} +
+ {/if} +
+
{usuario.role.setor || "-"} + {#if usuario.funcionario} +
+
+ + + + Associado +
+
+ {usuario.funcionario.nome} +
+ {#if usuario.funcionario.matricula} +
+ Mat: {usuario.funcionario.matricula} +
+ {/if} +
+ {:else} +
+ + + + Não associado +
+ {/if} +
+ + + {#if usuario.primeiroAcesso} +
Sim
+ {:else} +
Não
+ {/if} +
+ {formatarData(usuario.ultimoAcesso)} + + {formatarData(usuario.criadoEm)} + + +
+
+
+
+ {/if} +
- - {#if modalAssociarAberto && usuarioSelecionado} - + {/if} - - {#if modalExcluirAberto && usuarioSelecionado} - + {/if}
diff --git a/apps/web/src/routes/(dashboard)/ti/usuarios/criar/+page.svelte b/apps/web/src/routes/(dashboard)/ti/usuarios/criar/+page.svelte index de91390..e36a233 100644 --- a/apps/web/src/routes/(dashboard)/ti/usuarios/criar/+page.svelte +++ b/apps/web/src/routes/(dashboard)/ti/usuarios/criar/+page.svelte @@ -1,540 +1,574 @@ - -
- -
-
-
-
- - - -
-
-

Criar Novo Usuário

-

Cadastre um novo usuário no sistema

-
-
- - - - - Voltar para Usuários - -
-
+ +
+ +
+
+
+
+ + + +
+
+

+ Criar Novo Usuário +

+

+ Cadastre um novo usuário no sistema +

+
+
+ + + + + Voltar para Usuários + +
+
- - + + - - {#if mensagem} -
- - {#if mensagem.tipo === 'success'} - - {:else} - - {/if} - - {mensagem.texto} -
- {/if} + + {#if mensagem} +
+ + {#if mensagem.tipo === "success"} + + {:else} + + {/if} + + {mensagem.texto} +
+ {/if} - -
-
-
-
- - - -
-

Informações do Usuário

-
+ +
+
+
+
+ + + +
+

Informações do Usuário

+
-
-
- -
- - -
- Ao selecionar, os campos serão preenchidos automaticamente -
-
+ +
+ +
+ + +
+ Ao selecionar, os campos serão preenchidos automaticamente +
+
- -
- - -
+ +
+ + +
- -
- - -
+ +
+ + +
- -
- - - {#if !roles?.data || !Array.isArray(roles.data)} -
- Carregando perfis disponíveis... -
- {/if} -
+ +
+ + + {#if !roles?.data || !Array.isArray(roles.data)} +
+ Carregando perfis disponíveis... +
+ {/if} +
-
-
- - - - Senha Inicial -
-
+
+
+ + + + Senha Inicial +
+
- -
- - -
- Mínimo 8 caracteres -
-
+ +
+ + +
+ Mínimo 8 caracteres +
+
- -
- - -
+ +
+ + +
- -
- + +
+ - {#if mostrarSenha && senhaGerada} -
- - - -
-

Senha Gerada:

-
- - {senhaGerada} - - -
-

- ⚠️ IMPORTANTE: Anote esta senha! Você precisará repassá-la manualmente - ao usuário até que o SMTP seja configurado. -

-
-
- {/if} -
-
+ {#if mostrarSenha && senhaGerada} +
+ + + +
+

Senha Gerada:

+
+ + {senhaGerada} + + +
+

+ ⚠️ IMPORTANTE: Anote esta senha! Você precisará + repassá-la manualmente ao usuário até que o SMTP seja configurado. +

+
+
+ {/if} +
+
-
- - - -
-

Informações Importantes

-
    -
  • O usuário deverá alterar a senha no primeiro acesso
  • -
  • As credenciais devem ser repassadas manualmente (por enquanto)
  • -
  • - Configure o SMTP em Configurações de Email para envio automático -
  • -
-
-
+
+ + + +
+

Informações Importantes

+
    +
  • O usuário deverá alterar a senha no primeiro acesso
  • +
  • + As credenciais devem ser repassadas manualmente (por enquanto) +
  • +
  • + Configure o SMTP em Configurações de Email para envio automático +
  • +
+
+
-
- - - - - Cancelar - - -
-
-
-
-
+
+ + + + + Cancelar + + +
+ +
+
+
diff --git a/bun.lock b/bun.lock index 452768f..0b14041 100644 --- a/bun.lock +++ b/bun.lock @@ -1,6 +1,5 @@ { "lockfileVersion": 1, - "configVersion": 1, "workspaces": { "": { "name": "sgse-app", @@ -42,7 +41,7 @@ "@types/papaparse": "^5.3.14", "better-auth": "catalog:", "convex": "catalog:", - "convex-svelte": "^0.0.12", + "convex-svelte": "^0.0.11", "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.2", + "convex": "^1.28.0", "eslint": "^9.39.1", "typescript": "^5.9.2", }, @@ -133,55 +132,55 @@ "@aws-crypto/util": ["@aws-crypto/util@5.2.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], - "@aws-sdk/client-sesv2": ["@aws-sdk/client-sesv2@3.928.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.928.0", "@aws-sdk/credential-provider-node": "3.928.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.928.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/signature-v4-multi-region": "3.928.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.928.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-6wSrQRA+nT1ksZncvCyXo8a7/UIGuVEYnoubLKlJ/7j9MzHfSkDebL5YHBt03mmR7fJ+IRew+9xqsLzAbT0yUQ=="], + "@aws-sdk/client-sesv2": ["@aws-sdk/client-sesv2@3.921.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.921.0", "@aws-sdk/credential-provider-node": "3.921.0", "@aws-sdk/middleware-host-header": "3.921.0", "@aws-sdk/middleware-logger": "3.921.0", "@aws-sdk/middleware-recursion-detection": "3.921.0", "@aws-sdk/middleware-user-agent": "3.921.0", "@aws-sdk/region-config-resolver": "3.921.0", "@aws-sdk/signature-v4-multi-region": "3.921.0", "@aws-sdk/types": "3.921.0", "@aws-sdk/util-endpoints": "3.921.0", "@aws-sdk/util-user-agent-browser": "3.921.0", "@aws-sdk/util-user-agent-node": "3.921.0", "@smithy/config-resolver": "^4.4.1", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.7", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-SokAr3tgHo+M+U/nrqidZNiuhA8//l/L6A6R9e8lNEQZtI3tFB0SQcKFYQCy8H96/cNZhnYIqkxsUysEl0bNdw=="], - "@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.928.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.928.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.928.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.928.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-Efenb8zV2fJJDXmp2NE4xj8Ymhp4gVJCkQ6ixhdrpfQXgd2PODO7a20C2+BhFM6aGmN3m6XWYJ64ZyhXF4pAyQ=="], + "@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.921.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.921.0", "@aws-sdk/middleware-host-header": "3.921.0", "@aws-sdk/middleware-logger": "3.921.0", "@aws-sdk/middleware-recursion-detection": "3.921.0", "@aws-sdk/middleware-user-agent": "3.921.0", "@aws-sdk/region-config-resolver": "3.921.0", "@aws-sdk/types": "3.921.0", "@aws-sdk/util-endpoints": "3.921.0", "@aws-sdk/util-user-agent-browser": "3.921.0", "@aws-sdk/util-user-agent-node": "3.921.0", "@smithy/config-resolver": "^4.4.1", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.7", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-qWyT7WikdkPRAMuWidZ2l8jcQAPwNjvLcFZ/8K+oCAaMLt0LKLd7qeTwZ5tZFNqRNPXKfE8MkvAjyqSpE3i2yg=="], - "@aws-sdk/core": ["@aws-sdk/core@3.928.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@aws-sdk/xml-builder": "3.921.0", "@smithy/core": "^3.17.2", "@smithy/node-config-provider": "^4.3.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/signature-v4": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-e28J2uKjy2uub4u41dNnmzAu0AN3FGB+LRcLN2Qnwl9Oq3kIcByl5sM8ZD+vWpNG+SFUrUasBCq8cMnHxwXZ4w=="], + "@aws-sdk/core": ["@aws-sdk/core@3.921.0", "", { "dependencies": { "@aws-sdk/types": "3.921.0", "@aws-sdk/xml-builder": "3.921.0", "@smithy/core": "^3.17.2", "@smithy/node-config-provider": "^4.3.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/signature-v4": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-1eiD9ZO9cvEHdQUn/pwJVGN9LXg6D0O7knGVA0TA/v7nFSYy0n8RYG8vdnlcoYYnV1BcHgaf4KmRVMOszafNZQ=="], - "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.928.0", "", { "dependencies": { "@aws-sdk/core": "3.928.0", "@aws-sdk/types": "3.922.0", "@smithy/property-provider": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-tB8F9Ti0/NFyFVQX8UQtgRik88evtHpyT6WfXOB4bAY6lEnEHA0ubJZmk9y+aUeoE+OsGLx70dC3JUsiiCPJkQ=="], + "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.921.0", "", { "dependencies": { "@aws-sdk/core": "3.921.0", "@aws-sdk/types": "3.921.0", "@smithy/property-provider": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-RGG+zZdOYGJBQ8+L7BI6v41opoF8knErMtBZAUGcD3gvWEhjatc7lSbIpBeYWbTaWPPLHQU+ZVbmQ/jRLBgefw=="], - "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.928.0", "", { "dependencies": { "@aws-sdk/core": "3.928.0", "@aws-sdk/types": "3.922.0", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-67ynC/8UW9Y8Gn1ZZtC3OgcQDGWrJelHmkbgpmmxYUrzVhp+NINtz3wiTzrrBFhPH/8Uy6BxvhMfXhn0ptcMEQ=="], + "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.921.0", "", { "dependencies": { "@aws-sdk/core": "3.921.0", "@aws-sdk/types": "3.921.0", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/property-provider": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-TAv08Ow0oF/olV4DTLoPDj46KMk35bL1IUCfToESDrWk1TOSur7d4sCL0p/7dUsAxS244cEgeyIIijKNtxj2AA=="], - "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.928.0", "", { "dependencies": { "@aws-sdk/core": "3.928.0", "@aws-sdk/credential-provider-env": "3.928.0", "@aws-sdk/credential-provider-http": "3.928.0", "@aws-sdk/credential-provider-process": "3.928.0", "@aws-sdk/credential-provider-sso": "3.928.0", "@aws-sdk/credential-provider-web-identity": "3.928.0", "@aws-sdk/nested-clients": "3.928.0", "@aws-sdk/types": "3.922.0", "@smithy/credential-provider-imds": "^4.2.4", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-WVWYyj+jox6mhKYp11mu8x1B6Xa2sLbXFHAv5K3Jg8CHvXYpePgTcYlCljq3d4XHC4Jl4nCcsdMtBahSpU9bAA=="], + "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.921.0", "", { "dependencies": { "@aws-sdk/core": "3.921.0", "@aws-sdk/credential-provider-env": "3.921.0", "@aws-sdk/credential-provider-http": "3.921.0", "@aws-sdk/credential-provider-process": "3.921.0", "@aws-sdk/credential-provider-sso": "3.921.0", "@aws-sdk/credential-provider-web-identity": "3.921.0", "@aws-sdk/nested-clients": "3.921.0", "@aws-sdk/types": "3.921.0", "@smithy/credential-provider-imds": "^4.2.4", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-MUSRYGiMRq5NRGPRgJ7Nuh7GqXzE9iteAwdbzMJ4pnImgr7CjeWDihCIGk+gKLSG+NoRVVJM0V9PA4rxFir0Pg=="], - "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.928.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.928.0", "@aws-sdk/credential-provider-http": "3.928.0", "@aws-sdk/credential-provider-ini": "3.928.0", "@aws-sdk/credential-provider-process": "3.928.0", "@aws-sdk/credential-provider-sso": "3.928.0", "@aws-sdk/credential-provider-web-identity": "3.928.0", "@aws-sdk/types": "3.922.0", "@smithy/credential-provider-imds": "^4.2.4", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-SdXVjxZOIXefIR/NJx+lyXOrn4m0ScTAU2JXpLsFCkW2Cafo6vTqHUghyO8vak/XQ8PpPqpLXVpGbAYFuIPW6Q=="], + "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.921.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.921.0", "@aws-sdk/credential-provider-http": "3.921.0", "@aws-sdk/credential-provider-ini": "3.921.0", "@aws-sdk/credential-provider-process": "3.921.0", "@aws-sdk/credential-provider-sso": "3.921.0", "@aws-sdk/credential-provider-web-identity": "3.921.0", "@aws-sdk/types": "3.921.0", "@smithy/credential-provider-imds": "^4.2.4", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-bxUAqRyo49WzKWn/XS0d8QXT9GydY/ew5m58PYfSMwYfmwBZXx1GLSWe3tZnefm6santFiqmIWfMmeRWdygKmQ=="], - "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.928.0", "", { "dependencies": { "@aws-sdk/core": "3.928.0", "@aws-sdk/types": "3.922.0", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-XL0juran8yhqwn0mreV+NJeHJOkcRBaExsvVn9fXWW37A4gLh4esSJxM2KbSNh0t+/Bk3ehBI5sL9xad+yRDuw=="], + "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.921.0", "", { "dependencies": { "@aws-sdk/core": "3.921.0", "@aws-sdk/types": "3.921.0", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-DM62ooWI/aZ+ENBcLszuKmOkiICf6p4vYO2HgA3Cy2OEsTsjb67NEcntksxpZkD3mSIrCy/Qi4Z7tc77gle2Nw=="], - "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.928.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.928.0", "@aws-sdk/core": "3.928.0", "@aws-sdk/token-providers": "3.928.0", "@aws-sdk/types": "3.922.0", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-md/y+ePDsO1zqPJrsOyPs4ciKmdpqLL7B0dln1NhqZPnKIS5IBfTqZJ5tJ9eTezqc7Tn4Dbg6HiuemcGvZTeFA=="], + "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.921.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.921.0", "@aws-sdk/core": "3.921.0", "@aws-sdk/token-providers": "3.921.0", "@aws-sdk/types": "3.921.0", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Nh5jPJ6Y6nu3cHzZnq394lGXE5YO8Szke5zlATbNI7Tl0QJR65GE0IZsBcjzRMGpYX6ENCqPDK8FmklkmCYyVQ=="], - "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.928.0", "", { "dependencies": { "@aws-sdk/core": "3.928.0", "@aws-sdk/nested-clients": "3.928.0", "@aws-sdk/types": "3.922.0", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-rd97nLY5e/nGOr73ZfsXD+H44iZ9wyGZTKt/2QkiBN3hot/idhgT9+XHsWhRi+o/dThQbpL8RkpAnpF+0ZGthw=="], + "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.921.0", "", { "dependencies": { "@aws-sdk/core": "3.921.0", "@aws-sdk/nested-clients": "3.921.0", "@aws-sdk/types": "3.921.0", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VWcbgB2/shPPK674roHV4s8biCtvn0P/05EbTqy9WeyM5Oblx291gRGccyDhQbJbOL/6diRPBM08tlKPlBKNfw=="], - "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-HPquFgBnq/KqKRVkiuCt97PmWbKtxQ5iUNLEc6FIviqOoZTmaYG3EDsIbuFBz9C4RHJU4FKLmHL2bL3FEId6AA=="], + "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.921.0", "", { "dependencies": { "@aws-sdk/types": "3.921.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-eX1Ka29XzuEcXG4YABTwyLtPLchjmcjSjaq4irKJTFkxSYzX7gjoKt18rh/ZzOWOSqi23+cpjvBacL4VBKvE2Q=="], - "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-AkvYO6b80FBm5/kk2E636zNNcNgjztNNUxpqVx+huyGn9ZqGTzS4kLqW2hO6CBe5APzVtPCtiQsXL24nzuOlAg=="], + "@aws-sdk/middleware-logger": ["@aws-sdk/middleware-logger@3.921.0", "", { "dependencies": { "@aws-sdk/types": "3.921.0", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-14Qqp8wisKGj/2Y22OfO5jTBG5Xez+p3Zr2piAtz7AcbY8vBEoZbd6f+9lwwVFC73Aobkau223wzKbGT8HYQMw=="], - "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@aws/lambda-invoke-store": "^0.1.1", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-TtSCEDonV/9R0VhVlCpxZbp/9sxQvTTRKzIf8LxW3uXpby6Wl8IxEciBJlxmSkoqxh542WRcko7NYODlvL/gDA=="], + "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.921.0", "", { "dependencies": { "@aws-sdk/types": "3.921.0", "@aws/lambda-invoke-store": "^0.1.1", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-MYU5oI2b97M7u1dC1nt7SiGEvvLrQDlzV6hq9CB5TYX2glgbyvkaS//1Tjm87VF6qVSf5jYfwFDPeFGd8O1NrQ=="], - "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.928.0", "", { "dependencies": { "@aws-sdk/core": "3.928.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-arn-parser": "3.893.0", "@smithy/core": "^3.17.2", "@smithy/node-config-provider": "^4.3.4", "@smithy/protocol-http": "^5.3.4", "@smithy/signature-v4": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-stream": "^4.5.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-LTkjS6cpJ2PEtsottTKq7JxZV0oH+QJ12P/dGNPZL4URayjEMBVR/dp4zh835X/FPXzijga3sdotlIKzuFy9FA=="], + "@aws-sdk/middleware-sdk-s3": ["@aws-sdk/middleware-sdk-s3@3.921.0", "", { "dependencies": { "@aws-sdk/core": "3.921.0", "@aws-sdk/types": "3.921.0", "@aws-sdk/util-arn-parser": "3.893.0", "@smithy/core": "^3.17.2", "@smithy/node-config-provider": "^4.3.4", "@smithy/protocol-http": "^5.3.4", "@smithy/signature-v4": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-stream": "^4.5.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-u4fkE6sn5KWojhPUeDIqRx0BJlQug60PzAnLPlxeIvy2+ZeTSY64WYwF6V7wIZCf1RIstiBA/hQUsX07LfbvNg=="], - "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.928.0", "", { "dependencies": { "@aws-sdk/core": "3.928.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@smithy/core": "^3.17.2", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-ESvcfLx5PtpdUM3ptCwb80toBTd3y5I4w5jaeOPHihiZr7jkRLE/nsaCKzlqscPs6UQ8xI0maav04JUiTskcHw=="], + "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.921.0", "", { "dependencies": { "@aws-sdk/core": "3.921.0", "@aws-sdk/types": "3.921.0", "@aws-sdk/util-endpoints": "3.921.0", "@smithy/core": "^3.17.2", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-gXgokMBTPZAbQMm1+JOxItqA81aSFK6n7V2mAwxdmHjzCUZacX5RzkVPNbSaPPgDkroYnIzK09EusIpM6dLaqw=="], - "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.928.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.928.0", "@aws-sdk/middleware-host-header": "3.922.0", "@aws-sdk/middleware-logger": "3.922.0", "@aws-sdk/middleware-recursion-detection": "3.922.0", "@aws-sdk/middleware-user-agent": "3.928.0", "@aws-sdk/region-config-resolver": "3.925.0", "@aws-sdk/types": "3.922.0", "@aws-sdk/util-endpoints": "3.922.0", "@aws-sdk/util-user-agent-browser": "3.922.0", "@aws-sdk/util-user-agent-node": "3.928.0", "@smithy/config-resolver": "^4.4.2", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.8", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kXzfJkq2cD65KAHDe4hZCsnxcGGEWD5pjHqcZplwG4VFMa/iVn/mWrUY9QdadD2GBpXFNQbgOiKG3U2NkKu+4Q=="], + "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.921.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.921.0", "@aws-sdk/middleware-host-header": "3.921.0", "@aws-sdk/middleware-logger": "3.921.0", "@aws-sdk/middleware-recursion-detection": "3.921.0", "@aws-sdk/middleware-user-agent": "3.921.0", "@aws-sdk/region-config-resolver": "3.921.0", "@aws-sdk/types": "3.921.0", "@aws-sdk/util-endpoints": "3.921.0", "@aws-sdk/util-user-agent-browser": "3.921.0", "@aws-sdk/util-user-agent-node": "3.921.0", "@smithy/config-resolver": "^4.4.1", "@smithy/core": "^3.17.2", "@smithy/fetch-http-handler": "^5.3.5", "@smithy/hash-node": "^4.2.4", "@smithy/invalid-dependency": "^4.2.4", "@smithy/middleware-content-length": "^4.2.4", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-retry": "^4.4.6", "@smithy/middleware-serde": "^4.2.4", "@smithy/middleware-stack": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/node-http-handler": "^4.4.4", "@smithy/protocol-http": "^5.3.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.5", "@smithy/util-defaults-mode-node": "^4.2.7", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GV9aV8WqH/EWo4x3T5BrYb2ph1yfYuzUXZc0hhvxbFbDKD8m2fX9menao3Mgm7E5C68Su392u+MD9SGmGCmfKQ=="], - "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.925.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/config-resolver": "^4.4.2", "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-FOthcdF9oDb1pfQBRCfWPZhJZT5wqpvdAS5aJzB1WDZ+6EuaAhLzLH/fW1slDunIqq1PSQGG3uSnVglVVOvPHQ=="], + "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.921.0", "", { "dependencies": { "@aws-sdk/types": "3.921.0", "@smithy/config-resolver": "^4.4.1", "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-cSycw4wXcvsrssUdcEaeYQhQcZYVsBwHtgATh9HcIm01PrMV0lV71vcoyZ+9vUhwHwchRT6dItAyTHSQxwjvjg=="], - "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.928.0", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "3.928.0", "@aws-sdk/types": "3.922.0", "@smithy/protocol-http": "^5.3.4", "@smithy/signature-v4": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-1+Ic8+MyqQy+OE6QDoQKVCIcSZO+ETmLLLpVS5yu0fihBU85B5HHU7iaKX1qX7lEaGPMpSN/mbHW0VpyQ0Xqaw=="], + "@aws-sdk/signature-v4-multi-region": ["@aws-sdk/signature-v4-multi-region@3.921.0", "", { "dependencies": { "@aws-sdk/middleware-sdk-s3": "3.921.0", "@aws-sdk/types": "3.921.0", "@smithy/protocol-http": "^5.3.4", "@smithy/signature-v4": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-pFtJXtrf8cOsCgEb2OoPwQP4BKrnwIq69FuLowvWrXllFntAoAdEYaj9wNxPyl4pGqvo/9zO9CtkMb53PNxmWQ=="], - "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.928.0", "", { "dependencies": { "@aws-sdk/core": "3.928.0", "@aws-sdk/nested-clients": "3.928.0", "@aws-sdk/types": "3.922.0", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-533NpTdUJNDi98zBwRp4ZpZoqULrAVfc0YgIy+8AZHzk0v7N+v59O0d2Du3YO6zN4VU8HU8766DgKiyEag6Dzg=="], + "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.921.0", "", { "dependencies": { "@aws-sdk/core": "3.921.0", "@aws-sdk/nested-clients": "3.921.0", "@aws-sdk/types": "3.921.0", "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-d+w6X7ykqXirFBF+dYyK5Ntw0KmO2sgMj+JLR/vAe1vaR8/Fuqs3yOAFU7yNEzpcnbLJmMznxKpht03CSEMh4Q=="], - "@aws-sdk/types": ["@aws-sdk/types@3.922.0", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-eLA6XjVobAUAMivvM7DBL79mnHyrm+32TkXNWZua5mnxF+6kQCfblKKJvxMZLGosO53/Ex46ogim8IY5Nbqv2w=="], + "@aws-sdk/types": ["@aws-sdk/types@3.921.0", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-mqEG8+vFh5w0ZZC+R8VCOdSk998Hy93pIDuwYpfMAWgYwVhFaIMOLn1fZw0w2DhTs5+ONHHwMJ6uVXtuuqOLQQ=="], "@aws-sdk/util-arn-parser": ["@aws-sdk/util-arn-parser@3.893.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-u8H4f2Zsi19DGnwj5FSZzDMhytYF/bCh37vAtBsn3cNDL3YG578X5oc+wSX54pM3tOxS+NY7tvOAo52SW7koUA=="], - "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-endpoints": "^3.2.4", "tslib": "^2.6.2" } }, "sha512-4ZdQCSuNMY8HMlR1YN4MRDdXuKd+uQTeKIr5/pIM+g3TjInZoj8imvXudjcrFGA63UF3t92YVTkBq88mg58RXQ=="], + "@aws-sdk/util-endpoints": ["@aws-sdk/util-endpoints@3.921.0", "", { "dependencies": { "@aws-sdk/types": "3.921.0", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-endpoints": "^3.2.4", "tslib": "^2.6.2" } }, "sha512-kuJYRqug6V8gOg401BuK4w4IAVO3575VDR8iYiFw0gPwNIfOXvdlChfsJQoREqwJfif45J4eSmUsFtMfx87BQg=="], "@aws-sdk/util-locate-window": ["@aws-sdk/util-locate-window@3.893.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-T89pFfgat6c8nMmpI8eKjBcDcgJq36+m9oiXbcUzeU55MP9ZuGgBomGjGnHaEyF36jenW9gmg3NfZDm0AO2XPg=="], - "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.922.0", "", { "dependencies": { "@aws-sdk/types": "3.922.0", "@smithy/types": "^4.8.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-qOJAERZ3Plj1st7M4Q5henl5FRpE30uLm6L9edZqZXGR6c7ry9jzexWamWVpQ4H4xVAVmiO9dIEBAfbq4mduOA=="], + "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.921.0", "", { "dependencies": { "@aws-sdk/types": "3.921.0", "@smithy/types": "^4.8.1", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-buhv/ICWr4Nt8bquHOejCiVikBsfEYw4/HSc9U050QebRXIakt50zKYaWDQw4iCMeeqCiwE9mElEaXJAysythg=="], - "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.928.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.928.0", "@aws-sdk/types": "3.922.0", "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-s0jP67nQLLWVWfBtqTkZUkSWK5e6OI+rs+wFya2h9VLyWBFir17XSDI891s8HZKIVCEl8eBrup+hhywm4nsIAA=="], + "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.921.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.921.0", "@aws-sdk/types": "3.921.0", "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-Ilftai6AMAU1cEaUqIiTxkyj1NupLhP9Eq8HRfVuIH8489J2wLCcOyiLklAgSzBNmrxW+fagxkY+Dg0lFwmcVA=="], "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.921.0", "", { "dependencies": { "@smithy/types": "^4.8.1", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-LVHg0jgjyicKKvpNIEMXIMr1EBViESxcPkqfOlT+X1FkmUMTNZEEVF18tOJg4m4hV5vxtkWcqtr4IEeWa1C41Q=="], @@ -263,57 +262,57 @@ "@dicebear/thumbs": ["@dicebear/thumbs@9.2.4", "", { "peerDependencies": { "@dicebear/core": "^9.0.0" } }, "sha512-EL4sMqv9p2+1Xy3d8e8UxyeKZV2+cgt3X2x2RTRzEOIIhobtkL8u6lJxmJbiGbpVtVALmrt5e7gjmwqpryYDpg=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.12", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA=="], + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.11", "", { "os": "aix", "cpu": "ppc64" }, "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg=="], - "@esbuild/android-arm": ["@esbuild/android-arm@0.25.12", "", { "os": "android", "cpu": "arm" }, "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg=="], + "@esbuild/android-arm": ["@esbuild/android-arm@0.25.11", "", { "os": "android", "cpu": "arm" }, "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg=="], - "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.12", "", { "os": "android", "cpu": "arm64" }, "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg=="], + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.25.11", "", { "os": "android", "cpu": "arm64" }, "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ=="], - "@esbuild/android-x64": ["@esbuild/android-x64@0.25.12", "", { "os": "android", "cpu": "x64" }, "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg=="], + "@esbuild/android-x64": ["@esbuild/android-x64@0.25.11", "", { "os": "android", "cpu": "x64" }, "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g=="], - "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg=="], + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.25.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w=="], - "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA=="], + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.25.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ=="], - "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.12", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg=="], + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.25.11", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA=="], - "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.12", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ=="], + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.25.11", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw=="], - "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.12", "", { "os": "linux", "cpu": "arm" }, "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw=="], + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.25.11", "", { "os": "linux", "cpu": "arm" }, "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw=="], - "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ=="], + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.25.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA=="], - "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.12", "", { "os": "linux", "cpu": "ia32" }, "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA=="], + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.25.11", "", { "os": "linux", "cpu": "ia32" }, "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw=="], - "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng=="], + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.25.11", "", { "os": "linux", "cpu": "none" }, "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw=="], - "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw=="], + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.25.11", "", { "os": "linux", "cpu": "none" }, "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ=="], - "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.12", "", { "os": "linux", "cpu": "ppc64" }, "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA=="], + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.25.11", "", { "os": "linux", "cpu": "ppc64" }, "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw=="], - "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.12", "", { "os": "linux", "cpu": "none" }, "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w=="], + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.25.11", "", { "os": "linux", "cpu": "none" }, "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww=="], - "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.12", "", { "os": "linux", "cpu": "s390x" }, "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg=="], + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.25.11", "", { "os": "linux", "cpu": "s390x" }, "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw=="], - "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.12", "", { "os": "linux", "cpu": "x64" }, "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw=="], + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.25.11", "", { "os": "linux", "cpu": "x64" }, "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ=="], - "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg=="], + "@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.25.11", "", { "os": "none", "cpu": "arm64" }, "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg=="], - "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.12", "", { "os": "none", "cpu": "x64" }, "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ=="], + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.25.11", "", { "os": "none", "cpu": "x64" }, "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A=="], - "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.12", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A=="], + "@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.25.11", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg=="], - "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.12", "", { "os": "openbsd", "cpu": "x64" }, "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw=="], + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.25.11", "", { "os": "openbsd", "cpu": "x64" }, "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw=="], - "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.12", "", { "os": "none", "cpu": "arm64" }, "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg=="], + "@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.25.11", "", { "os": "none", "cpu": "arm64" }, "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ=="], - "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.12", "", { "os": "sunos", "cpu": "x64" }, "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w=="], + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.25.11", "", { "os": "sunos", "cpu": "x64" }, "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA=="], - "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg=="], + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.25.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q=="], - "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.12", "", { "os": "win32", "cpu": "ia32" }, "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ=="], + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.25.11", "", { "os": "win32", "cpu": "ia32" }, "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA=="], - "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="], + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.11", "", { "os": "win32", "cpu": "x64" }, "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA=="], "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="], @@ -369,7 +368,7 @@ "@levischuck/tiny-cbor": ["@levischuck/tiny-cbor@0.2.11", "", {}, "sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow=="], - "@mmailaender/convex-better-auth-svelte": ["@mmailaender/convex-better-auth-svelte@0.2.1", "", { "dependencies": { "is-network-error": "^1.1.0" }, "peerDependencies": { "@convex-dev/better-auth": "^0.9.0", "better-auth": "^1.3.27", "convex": "^1.27.0", "convex-svelte": ">=0.0.12", "svelte": "^5.0.0" } }, "sha512-vcQ0Jc7LdR2Kx8p1s3OaBB29kH31/5uKPIh7ejIS3UqfRYa9/zbaBy6OwEVifKDcQy/3begUCRbQsD9eF7+PnA=="], + "@mmailaender/convex-better-auth-svelte": ["@mmailaender/convex-better-auth-svelte@0.2.0", "", { "dependencies": { "is-network-error": "^1.1.0" }, "peerDependencies": { "@convex-dev/better-auth": "^0.9.0", "better-auth": "^1.3.27", "convex": "^1.27.0", "convex-svelte": "^0.0.11", "svelte": "^5.0.0" } }, "sha512-qzahOJg30xErb4ZW+aeszQw4ydhCmKFXn8CeRSA77YxR/dDMgZl+vdWLE4EKsDN0Jd748ecWMnk1fDNNUdgDcg=="], "@next/eslint-plugin-next": ["@next/eslint-plugin-next@15.5.6", "", { "dependencies": { "fast-glob": "3.3.1" } }, "sha512-YxDvsT2fwy1j5gMqk3ppXlsgDopHnkM4BoxSVASbvvgh5zgsK8lvWerDzPip8k3WVzsTZ1O7A7si1KNfN4OZfQ=="], @@ -409,49 +408,49 @@ "@polka/url": ["@polka/url@1.0.0-next.29", "", {}, "sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.53.2", "", { "os": "android", "cpu": "arm" }, "sha512-yDPzwsgiFO26RJA4nZo8I+xqzh7sJTZIWQOxn+/XOdPE31lAvLIYCKqjV+lNH/vxE2L2iH3plKxDCRK6i+CwhA=="], + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.52.5", "", { "os": "android", "cpu": "arm" }, "sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ=="], - "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.53.2", "", { "os": "android", "cpu": "arm64" }, "sha512-k8FontTxIE7b0/OGKeSN5B6j25EuppBcWM33Z19JoVT7UTXFSo3D9CdU39wGTeb29NO3XxpMNauh09B+Ibw+9g=="], + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.52.5", "", { "os": "android", "cpu": "arm64" }, "sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA=="], - "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.53.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-A6s4gJpomNBtJ2yioj8bflM2oogDwzUiMl2yNJ2v9E7++sHrSrsQ29fOfn5DM/iCzpWcebNYEdXpaK4tr2RhfQ=="], + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.52.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA=="], - "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.53.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-e6XqVmXlHrBlG56obu9gDRPW3O3hLxpwHpLsBJvuI8qqnsrtSZ9ERoWUXtPOkY8c78WghyPHZdmPhHLWNdAGEw=="], + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.52.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA=="], - "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.53.2", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-v0E9lJW8VsrwPux5Qe5CwmH/CF/2mQs6xU1MF3nmUxmZUCHazCjLgYvToOk+YuuUqLQBio1qkkREhxhc656ViA=="], + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.52.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA=="], - "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.53.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-ClAmAPx3ZCHtp6ysl4XEhWU69GUB1D+s7G9YjHGhIGCSrsg00nEGRRZHmINYxkdoJehde8VIsDC5t9C0gb6yqA=="], + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.52.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ=="], - "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.53.2", "", { "os": "linux", "cpu": "arm" }, "sha512-EPlb95nUsz6Dd9Qy13fI5kUPXNSljaG9FiJ4YUGU1O/Q77i5DYFW5KR8g1OzTcdZUqQQ1KdDqsTohdFVwCwjqg=="], + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.52.5", "", { "os": "linux", "cpu": "arm" }, "sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ=="], - "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.53.2", "", { "os": "linux", "cpu": "arm" }, "sha512-BOmnVW+khAUX+YZvNfa0tGTEMVVEerOxN0pDk2E6N6DsEIa2Ctj48FOMfNDdrwinocKaC7YXUZ1pHlKpnkja/Q=="], + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.52.5", "", { "os": "linux", "cpu": "arm" }, "sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ=="], - "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.53.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-Xt2byDZ+6OVNuREgBXr4+CZDJtrVso5woFtpKdGPhpTPHcNG7D8YXeQzpNbFRxzTVqJf7kvPMCub/pcGUWgBjA=="], + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.52.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg=="], - "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.53.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-+LdZSldy/I9N8+klim/Y1HsKbJ3BbInHav5qE9Iy77dtHC/pibw1SR/fXlWyAk0ThnpRKoODwnAuSjqxFRDHUQ=="], + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.52.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q=="], - "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.53.2", "", { "os": "linux", "cpu": "none" }, "sha512-8ms8sjmyc1jWJS6WdNSA23rEfdjWB30LH8Wqj0Cqvv7qSHnvw6kgMMXRdop6hkmGPlyYBdRPkjJnj3KCUHV/uQ=="], + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.52.5", "", { "os": "linux", "cpu": "none" }, "sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA=="], - "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.53.2", "", { "os": "linux", "cpu": "ppc64" }, "sha512-3HRQLUQbpBDMmzoxPJYd3W6vrVHOo2cVW8RUo87Xz0JPJcBLBr5kZ1pGcQAhdZgX9VV7NbGNipah1omKKe23/g=="], + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.52.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw=="], - "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.53.2", "", { "os": "linux", "cpu": "none" }, "sha512-fMjKi+ojnmIvhk34gZP94vjogXNNUKMEYs+EDaB/5TG/wUkoeua7p7VCHnE6T2Tx+iaghAqQX8teQzcvrYpaQA=="], + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.52.5", "", { "os": "linux", "cpu": "none" }, "sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw=="], - "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.53.2", "", { "os": "linux", "cpu": "none" }, "sha512-XuGFGU+VwUUV5kLvoAdi0Wz5Xbh2SrjIxCtZj6Wq8MDp4bflb/+ThZsVxokM7n0pcbkEr2h5/pzqzDYI7cCgLQ=="], + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.52.5", "", { "os": "linux", "cpu": "none" }, "sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg=="], - "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.53.2", "", { "os": "linux", "cpu": "s390x" }, "sha512-w6yjZF0P+NGzWR3AXWX9zc0DNEGdtvykB03uhonSHMRa+oWA6novflo2WaJr6JZakG2ucsyb+rvhrKac6NIy+w=="], + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.52.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ=="], - "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.53.2", "", { "os": "linux", "cpu": "x64" }, "sha512-yo8d6tdfdeBArzC7T/PnHd7OypfI9cbuZzPnzLJIyKYFhAQ8SvlkKtKBMbXDxe1h03Rcr7u++nFS7tqXz87Gtw=="], + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.52.5", "", { "os": "linux", "cpu": "x64" }, "sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q=="], - "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.53.2", "", { "os": "linux", "cpu": "x64" }, "sha512-ah59c1YkCxKExPP8O9PwOvs+XRLKwh/mV+3YdKqQ5AMQ0r4M4ZDuOrpWkUaqO7fzAHdINzV9tEVu8vNw48z0lA=="], + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.52.5", "", { "os": "linux", "cpu": "x64" }, "sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg=="], - "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.53.2", "", { "os": "none", "cpu": "arm64" }, "sha512-4VEd19Wmhr+Zy7hbUsFZ6YXEiP48hE//KPLCSVNY5RMGX2/7HZ+QkN55a3atM1C/BZCGIgqN+xrVgtdak2S9+A=="], + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.52.5", "", { "os": "none", "cpu": "arm64" }, "sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw=="], - "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.53.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-IlbHFYc/pQCgew/d5fslcy1KEaYVCJ44G8pajugd8VoOEI8ODhtb/j8XMhLpwHCMB3yk2J07ctup10gpw2nyMA=="], + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.52.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w=="], - "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.53.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-lNlPEGgdUfSzdCWU176ku/dQRnA7W+Gp8d+cWv73jYrb8uT7HTVVxq62DUYxjbaByuf1Yk0RIIAbDzp+CnOTFg=="], + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.52.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg=="], - "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.53.2", "", { "os": "win32", "cpu": "x64" }, "sha512-S6YojNVrHybQis2lYov1sd+uj7K0Q05NxHcGktuMMdIQ2VixGwAfbJ23NnlvvVV1bdpR2m5MsNBViHJKcA4ADw=="], + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.52.5", "", { "os": "win32", "cpu": "x64" }, "sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ=="], - "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.53.2", "", { "os": "win32", "cpu": "x64" }, "sha512-k+/Rkcyx//P6fetPoLMb8pBeqJBNGx81uuf7iljX9++yNBVRDQgD04L+SVXmXmh5ZP4/WOp4mWF0kmi06PW2tA=="], + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.52.5", "", { "os": "win32", "cpu": "x64" }, "sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg=="], "@sgse-app/backend": ["@sgse-app/backend@workspace:packages/backend"], @@ -461,55 +460,55 @@ "@simplewebauthn/server": ["@simplewebauthn/server@13.2.2", "", { "dependencies": { "@hexagon/base64": "^1.1.27", "@levischuck/tiny-cbor": "^0.2.2", "@peculiar/asn1-android": "^2.3.10", "@peculiar/asn1-ecc": "^2.3.8", "@peculiar/asn1-rsa": "^2.3.8", "@peculiar/asn1-schema": "^2.3.8", "@peculiar/asn1-x509": "^2.3.8", "@peculiar/x509": "^1.13.0" } }, "sha512-HcWLW28yTMGXpwE9VLx9J+N2KEUaELadLrkPEEI9tpI5la70xNEVEsu/C+m3u7uoq4FulLqZQhgBCzR9IZhFpA=="], - "@smithy/abort-controller": ["@smithy/abort-controller@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA=="], + "@smithy/abort-controller": ["@smithy/abort-controller@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Z4DUr/AkgyFf1bOThW2HwzREagee0sB5ycl+hDiSZOfRLW8ZgrOjDi6g8mHH19yyU5E2A/64W3z6SMIf5XiUSQ=="], - "@smithy/config-resolver": ["@smithy/config-resolver@4.4.3", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "tslib": "^2.6.2" } }, "sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw=="], + "@smithy/config-resolver": ["@smithy/config-resolver@4.4.1", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-BciDJ5hkyYEGBBKMbjGB1A/Zq8bYZ41Zo9BMnGdKF6QD1fY4zIkYx6zui/0CHaVGnv6h0iy8y4rnPX9CPCAPyQ=="], - "@smithy/core": ["@smithy/core@3.18.0", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-stream": "^4.5.6", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-vGSDXOJFZgOPTatSI1ly7Gwyy/d/R9zh2TO3y0JZ0uut5qQ88p9IaWaZYIWSSqtdekNM4CGok/JppxbAff4KcQ=="], + "@smithy/core": ["@smithy/core@3.17.2", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-stream": "^4.5.5", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-n3g4Nl1Te+qGPDbNFAYf+smkRVB+JhFsGy9uJXXZQEufoP4u0r+WLh6KvTDolCswaagysDc/afS1yvb2jnj1gQ=="], - "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.5", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "tslib": "^2.6.2" } }, "sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ=="], + "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/property-provider": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-YVNMjhdz2pVto5bRdux7GMs0x1m0Afz3OcQy/4Yf9DH4fWOtroGH7uLvs7ZmDyoBJzLdegtIPpXrpJOZWvUXdw=="], - "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.6", "", { "dependencies": { "@smithy/protocol-http": "^5.3.5", "@smithy/querystring-builder": "^4.2.5", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg=="], + "@smithy/fetch-http-handler": ["@smithy/fetch-http-handler@5.3.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" } }, "sha512-mg83SM3FLI8Sa2ooTJbsh5MFfyMTyNRwxqpKHmE0ICRIa66Aodv80DMsTQI02xBLVJ0hckwqTRr5IGAbbWuFLQ=="], - "@smithy/hash-node": ["@smithy/hash-node@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA=="], + "@smithy/hash-node": ["@smithy/hash-node@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-kKU0gVhx/ppVMntvUOZE7WRMFW86HuaxLwvqileBEjL7PoILI8/djoILw3gPQloGVE6O0oOzqafxeNi2KbnUJw=="], - "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A=="], + "@smithy/invalid-dependency": ["@smithy/invalid-dependency@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-z6aDLGiHzsMhbS2MjetlIWopWz//K+mCoPXjW6aLr0mypF+Y7qdEh5TyJ20Onf9FbWHiWl4eC+rITdizpnXqOw=="], "@smithy/is-array-buffer": ["@smithy/is-array-buffer@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ=="], - "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A=="], + "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-hJRZuFS9UsElX4DJSJfoX4M1qXRH+VFiLMUnhsWvtOOUWRNvvOfDaUSdlNbjwv1IkpVjj/Rd/O59Jl3nhAcxow=="], - "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.7", "", { "dependencies": { "@smithy/core": "^3.18.0", "@smithy/middleware-serde": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-middleware": "^4.2.5", "tslib": "^2.6.2" } }, "sha512-i8Mi8OuY6Yi82Foe3iu7/yhBj1HBRoOQwBSsUNYglJTNSFaWYTNM2NauBBs/7pq2sqkLRqeUXA3Ogi2utzpUlQ=="], + "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.6", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-serde": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "@smithy/url-parser": "^4.2.4", "@smithy/util-middleware": "^4.2.4", "tslib": "^2.6.2" } }, "sha512-PXehXofGMFpDqr933rxD8RGOcZ0QBAWtuzTgYRAHAL2BnKawHDEdf/TnGpcmfPJGwonhginaaeJIKluEojiF/w=="], - "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.7", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.5", "@smithy/protocol-http": "^5.3.5", "@smithy/service-error-classification": "^4.2.5", "@smithy/smithy-client": "^4.9.3", "@smithy/types": "^4.9.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-E7Vc6WHCHlzDRTx1W0jZ6J1L6ziEV0PIWcUdmfL4y+c8r7WYr6I+LkQudaD8Nfb7C5c4P3SQ972OmXHtv6m/OA=="], + "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.6", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/protocol-http": "^5.3.4", "@smithy/service-error-classification": "^4.2.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "@smithy/util-middleware": "^4.2.4", "@smithy/util-retry": "^4.2.4", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-OhLx131znrEDxZPAvH/OYufR9d1nB2CQADyYFN4C3V/NQS7Mg4V6uvxHC/Dr96ZQW8IlHJTJ+vAhKt6oxWRndA=="], - "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-La1ldWTJTZ5NqQyPqnCNeH9B+zjFhrNoQIL1jTh4zuqXRlmXhxYHhMtI1/92OlnoAtp6JoN7kzuwhWoXrBwPqg=="], + "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.4", "", { "dependencies": { "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-jUr3x2CDhV15TOX2/Uoz4gfgeqLrRoTQbYAuhLS7lcVKNev7FeYSJ1ebEfjk+l9kbb7k7LfzIR/irgxys5ZTOg=="], - "@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-bYrutc+neOyWxtZdbB2USbQttZN0mXaOyYLIsaTbJhFsfpXyGWUxJpEuO1rJ8IIJm2qH4+xJT0mxUSsEDTYwdQ=="], + "@smithy/middleware-stack": ["@smithy/middleware-stack@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-Gy3TKCOnm9JwpFooldwAboazw+EFYlC+Bb+1QBsSi5xI0W5lX81j/P5+CXvD/9ZjtYKRgxq+kkqd/KOHflzvgA=="], - "@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.5", "", { "dependencies": { "@smithy/property-provider": "^4.2.5", "@smithy/shared-ini-file-loader": "^4.4.0", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-UTurh1C4qkVCtqggI36DGbLB2Kv8UlcFdMXDcWMbqVY2uRg0XmT9Pb4Vj6oSQ34eizO1fvR0RnFV4Axw4IrrAg=="], + "@smithy/node-config-provider": ["@smithy/node-config-provider@4.3.4", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/shared-ini-file-loader": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3X3w7qzmo4XNNdPKNS4nbJcGSwiEMsNsRSunMA92S4DJLLIrH5g1AyuOA2XKM9PAPi8mIWfqC+fnfKNsI4KvHw=="], - "@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.5", "", { "dependencies": { "@smithy/abort-controller": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/querystring-builder": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-CMnzM9R2WqlqXQGtIlsHMEZfXKJVTIrqCNoSd/QpAyp+Dw0a1Vps13l6ma1fH8g7zSPNsA59B/kWgeylFuA/lw=="], + "@smithy/node-http-handler": ["@smithy/node-http-handler@4.4.4", "", { "dependencies": { "@smithy/abort-controller": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/querystring-builder": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-VXHGfzCXLZeKnFp6QXjAdy+U8JF9etfpUXD1FAbzY1GzsFJiDQRQIt2CnMUvUdz3/YaHNqT3RphVWMUpXTIODA=="], - "@smithy/property-provider": ["@smithy/property-provider@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-8iLN1XSE1rl4MuxvQ+5OSk/Zb5El7NJZ1td6Tn+8dQQHIjp59Lwl6bd0+nzw6SKm2wSSriH2v/I9LPzUic7EOg=="], + "@smithy/property-provider": ["@smithy/property-provider@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-g2DHo08IhxV5GdY3Cpt/jr0mkTlAD39EJKN27Jb5N8Fb5qt8KG39wVKTXiTRCmHHou7lbXR8nKVU14/aRUf86w=="], - "@smithy/protocol-http": ["@smithy/protocol-http@5.3.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-RlaL+sA0LNMp03bf7XPbFmT5gN+w3besXSWMkA8rcmxLSVfiEXElQi4O2IWwPfxzcHkxqrwBFMbngB8yx/RvaQ=="], + "@smithy/protocol-http": ["@smithy/protocol-http@5.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-3sfFd2MAzVt0Q/klOmjFi3oIkxczHs0avbwrfn1aBqtc23WqQSmjvk77MBw9WkEQcwbOYIX5/2z4ULj8DuxSsw=="], - "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-y98otMI1saoajeik2kLfGyRp11e5U/iJYH/wLCh3aTV/XutbGT9nziKGkgCaMD1ghK7p6htHMm6b6scl9JRUWg=="], + "@smithy/querystring-builder": ["@smithy/querystring-builder@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-KQ1gFXXC+WsbPFnk7pzskzOpn4s+KheWgO3dzkIEmnb6NskAIGp/dGdbKisTPJdtov28qNDohQrgDUKzXZBLig=="], - "@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-031WCTdPYgiQRYNPXznHXof2YM0GwL6SeaSyTH/P72M1Vz73TvCNH2Nq8Iu2IEPq9QP2yx0/nrw5YmSeAi/AjQ=="], + "@smithy/querystring-parser": ["@smithy/querystring-parser@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-aHb5cqXZocdzEkZ/CvhVjdw5l4r1aU/9iMEyoKzH4eXMowT6M0YjBpp7W/+XjkBnY8Xh0kVd55GKjnPKlCwinQ=="], - "@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0" } }, "sha512-8fEvK+WPE3wUAcDvqDQG1Vk3ANLR8Px979te96m84CbKAjBVf25rPYSzb4xU4hlTyho7VhOGnh5i62D/JVF0JQ=="], + "@smithy/service-error-classification": ["@smithy/service-error-classification@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1" } }, "sha512-fdWuhEx4+jHLGeew9/IvqVU/fxT/ot70tpRGuOLxE3HzZOyKeTQfYeV1oaBXpzi93WOk668hjMuuagJ2/Qs7ng=="], - "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.4.0", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-5WmZ5+kJgJDjwXXIzr1vDTG+RhF9wzSODQBfkrQ2VVkYALKGvZX1lgVSxEkgicSAFnFhPj5rudJV0zoinqS0bA=="], + "@smithy/shared-ini-file-loader": ["@smithy/shared-ini-file-loader@4.3.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-y5ozxeQ9omVjbnJo9dtTsdXj9BEvGx2X8xvRgKnV+/7wLBuYJQL6dOa/qMY6omyHi7yjt1OA97jZLoVRYi8lxA=="], - "@smithy/signature-v4": ["@smithy/signature-v4@5.3.5", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.5", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w=="], + "@smithy/signature-v4": ["@smithy/signature-v4@5.3.4", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.4", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-ScDCpasxH7w1HXHYbtk3jcivjvdA1VICyAdgvVqKhKKwxi+MTwZEqFw0minE+oZ7F07oF25xh4FGJxgqgShz0A=="], - "@smithy/smithy-client": ["@smithy/smithy-client@4.9.3", "", { "dependencies": { "@smithy/core": "^3.18.0", "@smithy/middleware-endpoint": "^4.3.7", "@smithy/middleware-stack": "^4.2.5", "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "@smithy/util-stream": "^4.5.6", "tslib": "^2.6.2" } }, "sha512-8tlueuTgV5n7inQCkhyptrB3jo2AO80uGrps/XTYZivv5MFQKKBj3CIWIGMI2fRY5LEduIiazOhAWdFknY1O9w=="], + "@smithy/smithy-client": ["@smithy/smithy-client@4.9.2", "", { "dependencies": { "@smithy/core": "^3.17.2", "@smithy/middleware-endpoint": "^4.3.6", "@smithy/middleware-stack": "^4.2.4", "@smithy/protocol-http": "^5.3.4", "@smithy/types": "^4.8.1", "@smithy/util-stream": "^4.5.5", "tslib": "^2.6.2" } }, "sha512-gZU4uAFcdrSi3io8U99Qs/FvVdRxPvIMToi+MFfsy/DN9UqtknJ1ais+2M9yR8e0ASQpNmFYEKeIKVcMjQg3rg=="], - "@smithy/types": ["@smithy/types@4.9.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA=="], + "@smithy/types": ["@smithy/types@4.8.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-N0Zn0OT1zc+NA+UVfkYqQzviRh5ucWwO7mBV3TmHHprMnfcJNfhlPicDkBHi0ewbh+y3evR6cNAW0Raxvb01NA=="], - "@smithy/url-parser": ["@smithy/url-parser@4.2.5", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-VaxMGsilqFnK1CeBX+LXnSuaMx4sTL/6znSZh2829txWieazdVxr54HmiyTsIbpOTLcf5nYpq9lpzmwRdxj6rQ=="], + "@smithy/url-parser": ["@smithy/url-parser@4.2.4", "", { "dependencies": { "@smithy/querystring-parser": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-w/N/Iw0/PTwJ36PDqU9PzAwVElo4qXxCC0eCTlUtIz/Z5V/2j/cViMHi0hPukSBHp4DVwvUlUhLgCzqSJ6plrg=="], "@smithy/util-base64": ["@smithy/util-base64@4.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ=="], @@ -521,19 +520,19 @@ "@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="], - "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.6", "", { "dependencies": { "@smithy/property-provider": "^4.2.5", "@smithy/smithy-client": "^4.9.3", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-kbpuXbEf2YQ9zEE6eeVnUCQWO0e1BjMnKrXL8rfXgiWA0m8/E0leU4oSNzxP04WfCmW8vjEqaDeXWxwE4tpOjQ=="], + "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.5", "", { "dependencies": { "@smithy/property-provider": "^4.2.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-GwaGjv/QLuL/QHQaqhf/maM7+MnRFQQs7Bsl6FlaeK6lm6U7mV5AAnVabw68cIoMl5FQFyKK62u7RWRzWL25OQ=="], - "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.9", "", { "dependencies": { "@smithy/config-resolver": "^4.4.3", "@smithy/credential-provider-imds": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/property-provider": "^4.2.5", "@smithy/smithy-client": "^4.9.3", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-dgyribrVWN5qE5usYJ0m5M93mVM3L3TyBPZWe1Xl6uZlH2gzfQx3dz+ZCdW93lWqdedJRkOecnvbnoEEXRZ5VQ=="], + "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.7", "", { "dependencies": { "@smithy/config-resolver": "^4.4.1", "@smithy/credential-provider-imds": "^4.2.4", "@smithy/node-config-provider": "^4.3.4", "@smithy/property-provider": "^4.2.4", "@smithy/smithy-client": "^4.9.2", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-6hinjVqec0WYGsqN7h9hL/ywfULmJJNXGXnNZW7jrIn/cFuC/aVlVaiDfBIJEvKcOrmN8/EgsW69eY0gXABeHw=="], - "@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.5", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A=="], + "@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.4", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-f+nBDhgYRCmUEDKEQb6q0aCcOTXRDqH5wWaFHJxt4anB4pKHlgGoYP3xtioKXH64e37ANUkzWf6p4Mnv1M5/Vg=="], "@smithy/util-hex-encoding": ["@smithy/util-hex-encoding@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw=="], - "@smithy/util-middleware": ["@smithy/util-middleware@4.2.5", "", { "dependencies": { "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-6Y3+rvBF7+PZOc40ybeZMcGln6xJGVeY60E7jy9Mv5iKpMJpHgRE6dKy9ScsVxvfAYuEX4Q9a65DQX90KaQ3bA=="], + "@smithy/util-middleware": ["@smithy/util-middleware@4.2.4", "", { "dependencies": { "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-fKGQAPAn8sgV0plRikRVo6g6aR0KyKvgzNrPuM74RZKy/wWVzx3BMk+ZWEueyN3L5v5EDg+P582mKU+sH5OAsg=="], - "@smithy/util-retry": ["@smithy/util-retry@4.2.5", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-GBj3+EZBbN4NAqJ/7pAhsXdfzdlznOh8PydUijy6FpNIMnHPSMO2/rP4HKu+UFeikJxShERk528oy7GT79YiJg=="], + "@smithy/util-retry": ["@smithy/util-retry@4.2.4", "", { "dependencies": { "@smithy/service-error-classification": "^4.2.4", "@smithy/types": "^4.8.1", "tslib": "^2.6.2" } }, "sha512-yQncJmj4dtv/isTXxRb4AamZHy4QFr4ew8GxS6XLWt7sCIxkPxPzINWd7WLISEFPsIan14zrKgvyAF+/yzfwoA=="], - "@smithy/util-stream": ["@smithy/util-stream@4.5.6", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.6", "@smithy/node-http-handler": "^4.4.5", "@smithy/types": "^4.9.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-qWw/UM59TiaFrPevefOZ8CNBKbYEP6wBAIlLqxn3VAIo9rgnTNc4ASbVrqDmhuwI87usnjhdQrxodzAGFFzbRQ=="], + "@smithy/util-stream": ["@smithy/util-stream@4.5.5", "", { "dependencies": { "@smithy/fetch-http-handler": "^5.3.5", "@smithy/node-http-handler": "^4.4.4", "@smithy/types": "^4.8.1", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-7M5aVFjT+HPilPOKbOmQfCIPchZe4DSBc1wf1+NvHvSoFTiFtauZzT+onZvCj70xhXd0AEmYnZYmdJIuwxOo4w=="], "@smithy/util-uri-escape": ["@smithy/util-uri-escape@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA=="], @@ -547,7 +546,7 @@ "@sveltejs/adapter-auto": ["@sveltejs/adapter-auto@6.1.1", "", { "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "sha512-cBNt4jgH4KuaNO5gRSB2CZKkGtz+OCZ8lPjRQGjhvVUD4akotnj2weUia6imLl2v07K3IgsQRyM36909miSwoQ=="], - "@sveltejs/kit": ["@sveltejs/kit@2.48.4", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", "devalue": "^5.3.2", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["@opentelemetry/api"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-TGFX1pZUt9qqY20Cv5NyYvy0iLWHf2jXi8s+eCGsig7jQMdwZWKUFMR6TbvFNhfDSUpc1sH/Y5EHv20g3HHA3g=="], + "@sveltejs/kit": ["@sveltejs/kit@2.48.3", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/cookie": "^0.6.0", "acorn": "^8.14.1", "cookie": "^0.6.0", "devalue": "^5.3.2", "esm-env": "^1.2.2", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", "sade": "^1.8.1", "set-cookie-parser": "^2.6.0", "sirv": "^3.0.0" }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", "@sveltejs/vite-plugin-svelte": "^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0", "svelte": "^4.0.0 || ^5.0.0-next.0", "vite": "^5.0.3 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["@opentelemetry/api"], "bin": { "svelte-kit": "svelte-kit.js" } }, "sha512-jf8mx3yctRXE9hvixgcqqK94YI2hDnbxI/12Upkz99XFMvxnJKCMzvz0j7lmbXSyBSNEycWO5xHvi7b73y9qkQ=="], "@sveltejs/vite-plugin-svelte": ["@sveltejs/vite-plugin-svelte@6.2.1", "", { "dependencies": { "@sveltejs/vite-plugin-svelte-inspector": "^5.0.0", "debug": "^4.4.1", "deepmerge": "^4.3.1", "magic-string": "^0.30.17", "vitefu": "^1.1.1" }, "peerDependencies": { "svelte": "^5.0.0", "vite": "^6.3.0 || ^7.0.0" } }, "sha512-YZs/OSKOQAQCnJvM/P+F1URotNnYNeU3P2s4oIpzm1uFaqUEqRxUB0g5ejMjEb5Gjb9/PiBI5Ktrq4rUUF8UVQ=="], @@ -555,35 +554,35 @@ "@swc/helpers": ["@swc/helpers@0.5.17", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A=="], - "@tailwindcss/node": ["@tailwindcss/node@4.1.17", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.17" } }, "sha512-csIkHIgLb3JisEFQ0vxr2Y57GUNYh447C8xzwj89U/8fdW8LhProdxvnVH6U8M2Y73QKiTIH+LWbK3V2BBZsAg=="], + "@tailwindcss/node": ["@tailwindcss/node@4.1.16", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.19", "source-map-js": "^1.2.1", "tailwindcss": "4.1.16" } }, "sha512-BX5iaSsloNuvKNHRN3k2RcCuTEgASTo77mofW0vmeHkfrDWaoFAFvNHpEgtu0eqyypcyiBkDWzSMxJhp3AUVcw=="], - "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.17", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.17", "@tailwindcss/oxide-darwin-arm64": "4.1.17", "@tailwindcss/oxide-darwin-x64": "4.1.17", "@tailwindcss/oxide-freebsd-x64": "4.1.17", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.17", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.17", "@tailwindcss/oxide-linux-arm64-musl": "4.1.17", "@tailwindcss/oxide-linux-x64-gnu": "4.1.17", "@tailwindcss/oxide-linux-x64-musl": "4.1.17", "@tailwindcss/oxide-wasm32-wasi": "4.1.17", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.17", "@tailwindcss/oxide-win32-x64-msvc": "4.1.17" } }, "sha512-F0F7d01fmkQhsTjXezGBLdrl1KresJTcI3DB8EkScCldyKp3Msz4hub4uyYaVnk88BAS1g5DQjjF6F5qczheLA=="], + "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.16", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.16", "@tailwindcss/oxide-darwin-arm64": "4.1.16", "@tailwindcss/oxide-darwin-x64": "4.1.16", "@tailwindcss/oxide-freebsd-x64": "4.1.16", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.16", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.16", "@tailwindcss/oxide-linux-arm64-musl": "4.1.16", "@tailwindcss/oxide-linux-x64-gnu": "4.1.16", "@tailwindcss/oxide-linux-x64-musl": "4.1.16", "@tailwindcss/oxide-wasm32-wasi": "4.1.16", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.16", "@tailwindcss/oxide-win32-x64-msvc": "4.1.16" } }, "sha512-2OSv52FRuhdlgyOQqgtQHuCgXnS8nFSYRp2tJ+4WZXKgTxqPy7SMSls8c3mPT5pkZ17SBToGM5LHEJBO7miEdg=="], - "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.17", "", { "os": "android", "cpu": "arm64" }, "sha512-BMqpkJHgOZ5z78qqiGE6ZIRExyaHyuxjgrJ6eBO5+hfrfGkuya0lYfw8fRHG77gdTjWkNWEEm+qeG2cDMxArLQ=="], + "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.16", "", { "os": "android", "cpu": "arm64" }, "sha512-8+ctzkjHgwDJ5caq9IqRSgsP70xhdhJvm+oueS/yhD5ixLhqTw9fSL1OurzMUhBwE5zK26FXLCz2f/RtkISqHA=="], - "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.17", "", { "os": "darwin", "cpu": "arm64" }, "sha512-EquyumkQweUBNk1zGEU/wfZo2qkp/nQKRZM8bUYO0J+Lums5+wl2CcG1f9BgAjn/u9pJzdYddHWBiFXJTcxmOg=="], + "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.16", "", { "os": "darwin", "cpu": "arm64" }, "sha512-C3oZy5042v2FOALBZtY0JTDnGNdS6w7DxL/odvSny17ORUnaRKhyTse8xYi3yKGyfnTUOdavRCdmc8QqJYwFKA=="], - "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.17", "", { "os": "darwin", "cpu": "x64" }, "sha512-gdhEPLzke2Pog8s12oADwYu0IAw04Y2tlmgVzIN0+046ytcgx8uZmCzEg4VcQh+AHKiS7xaL8kGo/QTiNEGRog=="], + "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.16", "", { "os": "darwin", "cpu": "x64" }, "sha512-vjrl/1Ub9+JwU6BP0emgipGjowzYZMjbWCDqwA2Z4vCa+HBSpP4v6U2ddejcHsolsYxwL5r4bPNoamlV0xDdLg=="], - "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.17", "", { "os": "freebsd", "cpu": "x64" }, "sha512-hxGS81KskMxML9DXsaXT1H0DyA+ZBIbyG/sSAjWNe2EDl7TkPOBI42GBV3u38itzGUOmFfCzk1iAjDXds8Oh0g=="], + "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.16", "", { "os": "freebsd", "cpu": "x64" }, "sha512-TSMpPYpQLm+aR1wW5rKuUuEruc/oOX3C7H0BTnPDn7W/eMw8W+MRMpiypKMkXZfwH8wqPIRKppuZoedTtNj2tg=="], - "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.17", "", { "os": "linux", "cpu": "arm" }, "sha512-k7jWk5E3ldAdw0cNglhjSgv501u7yrMf8oeZ0cElhxU6Y2o7f8yqelOp3fhf7evjIS6ujTI3U8pKUXV2I4iXHQ=="], + "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.16", "", { "os": "linux", "cpu": "arm" }, "sha512-p0GGfRg/w0sdsFKBjMYvvKIiKy/LNWLWgV/plR4lUgrsxFAoQBFrXkZ4C0w8IOXfslB9vHK/JGASWD2IefIpvw=="], - "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HVDOm/mxK6+TbARwdW17WrgDYEGzmoYayrCgmLEw7FxTPLcp/glBisuyWkFz/jb7ZfiAXAXUACfyItn+nTgsdQ=="], + "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-DoixyMmTNO19rwRPdqviTrG1rYzpxgyYJl8RgQvdAQUzxC1ToLRqtNJpU/ATURSKgIg6uerPw2feW0aS8SNr/w=="], - "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.17", "", { "os": "linux", "cpu": "arm64" }, "sha512-HvZLfGr42i5anKtIeQzxdkw/wPqIbpeZqe7vd3V9vI3RQxe3xU1fLjss0TjyhxWcBaipk7NYwSrwTwK1hJARMg=="], + "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.16", "", { "os": "linux", "cpu": "arm64" }, "sha512-H81UXMa9hJhWhaAUca6bU2wm5RRFpuHImrwXBUvPbYb+3jo32I9VIwpOX6hms0fPmA6f2pGVlybO6qU8pF4fzQ=="], - "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-M3XZuORCGB7VPOEDH+nzpJ21XPvK5PyjlkSFkFziNHGLc5d6g3di2McAAblmaSUNl8IOmzYwLx9NsE7bplNkwQ=="], + "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-ZGHQxDtFC2/ruo7t99Qo2TTIvOERULPl5l0K1g0oK6b5PGqjYMga+FcY1wIUnrUxY56h28FxybtDEla+ICOyew=="], - "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.17", "", { "os": "linux", "cpu": "x64" }, "sha512-k7f+pf9eXLEey4pBlw+8dgfJHY4PZ5qOUFDyNf7SI6lHjQ9Zt7+NcscjpwdCEbYi6FI5c2KDTDWyf2iHcCSyyQ=="], + "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.16", "", { "os": "linux", "cpu": "x64" }, "sha512-Oi1tAaa0rcKf1Og9MzKeINZzMLPbhxvm7rno5/zuP1WYmpiG0bEHq4AcRUiG2165/WUzvxkW4XDYCscZWbTLZw=="], - "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.17", "", { "dependencies": { "@emnapi/core": "^1.6.0", "@emnapi/runtime": "^1.6.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.7", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-cEytGqSSoy7zK4JRWiTCx43FsKP/zGr0CsuMawhH67ONlH+T79VteQeJQRO/X7L0juEUA8ZyuYikcRBf0vsxhg=="], + "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.16", "", { "dependencies": { "@emnapi/core": "^1.5.0", "@emnapi/runtime": "^1.5.0", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.0.7", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-B01u/b8LteGRwucIBmCQ07FVXLzImWESAIMcUU6nvFt/tYsQ6IHz8DmZ5KtvmwxD+iTYBtM1xwoGXswnlu9v0Q=="], - "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.17", "", { "os": "win32", "cpu": "arm64" }, "sha512-JU5AHr7gKbZlOGvMdb4722/0aYbU+tN6lv1kONx0JK2cGsh7g148zVWLM0IKR3NeKLv+L90chBVYcJ8uJWbC9A=="], + "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.16", "", { "os": "win32", "cpu": "arm64" }, "sha512-zX+Q8sSkGj6HKRTMJXuPvOcP8XfYON24zJBRPlszcH1Np7xuHXhWn8qfFjIujVzvH3BHU+16jBXwgpl20i+v9A=="], - "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.17", "", { "os": "win32", "cpu": "x64" }, "sha512-SKWM4waLuqx0IH+FMDUw6R66Hu4OuTALFgnleKbqhgGU30DY20NORZMZUKgLRjQXNN2TLzKvh48QXTig4h4bGw=="], + "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.16", "", { "os": "win32", "cpu": "x64" }, "sha512-m5dDFJUEejbFqP+UXVstd4W/wnxA4F61q8SoL+mqTypId2T2ZpuxosNSgowiCnLp2+Z+rivdU0AqpfgiD7yCBg=="], - "@tailwindcss/vite": ["@tailwindcss/vite@4.1.17", "", { "dependencies": { "@tailwindcss/node": "4.1.17", "@tailwindcss/oxide": "4.1.17", "tailwindcss": "4.1.17" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-4+9w8ZHOiGnpcGI6z1TVVfWaX/koK7fKeSYF3qlYg2xpBtbteP2ddBxiarL+HVgfSJGeK5RIxRQmKm4rTJJAwA=="], + "@tailwindcss/vite": ["@tailwindcss/vite@4.1.16", "", { "dependencies": { "@tailwindcss/node": "4.1.16", "@tailwindcss/oxide": "4.1.16", "tailwindcss": "4.1.16" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-bbguNBcDxsRmi9nnlWJxhfDWamY3lmcyACHcdO1crxfzuLpOhHLLtEIN/nCbbAtj5rchUgQD17QVAKi1f7IsKg=="], "@tanstack/devtools-event-client": ["@tanstack/devtools-event-client@0.3.4", "", {}, "sha512-eq+PpuutUyubXu+ycC1GIiVwBs86NF/8yYJJAKSpPcJLWl6R/761F1H4F/9ziX6zKezltFUH1ah3Cz8Ah+KJrw=="], @@ -603,37 +602,37 @@ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], - "@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="], + "@types/node": ["@types/node@24.9.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA=="], "@types/nodemailer": ["@types/nodemailer@7.0.3", "", { "dependencies": { "@aws-sdk/client-sesv2": "^3.839.0", "@types/node": "*" } }, "sha512-fC8w49YQ868IuPWRXqPfLf+MuTRex5Z1qxMoG8rr70riqqbOp2F5xgOKE9fODEBPzpnvjkJXFgK6IL2xgMSTnA=="], "@types/pako": ["@types/pako@2.0.4", "", {}, "sha512-VWDCbrLeVXJM9fihYodcLiIv0ku+AlOa/TQ1SvYOaBuyrSKgEcro95LJyIsJ4vSo6BXIxOKxiJAat04CmST9Fw=="], - "@types/papaparse": ["@types/papaparse@5.5.0", "", { "dependencies": { "@types/node": "*" } }, "sha512-GVs5iMQmUr54BAZYYkByv8zPofFxmyxUpISPb2oh8sayR3+1zbxasrOvoKiHJ/nnoq/uULuPsu1Lze1EkagVFg=="], + "@types/papaparse": ["@types/papaparse@5.3.16", "", { "dependencies": { "@types/node": "*" } }, "sha512-T3VuKMC2H0lgsjI9buTB3uuKj3EMD2eap1MOuEQuBQ44EnDx/IkGhU6EwiTf9zG3za4SKlmwKAImdDKdNnCsXg=="], "@types/raf": ["@types/raf@3.4.3", "", {}, "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw=="], "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], - "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.46.4", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.46.4", "@typescript-eslint/type-utils": "8.46.4", "@typescript-eslint/utils": "8.46.4", "@typescript-eslint/visitor-keys": "8.46.4", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.46.4", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-R48VhmTJqplNyDxCyqqVkFSZIx1qX6PzwqgcXn1olLrzxcSBDlOsbtcnQuQhNtnNiJ4Xe5gREI1foajYaYU2Vg=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.46.3", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.46.3", "@typescript-eslint/type-utils": "8.46.3", "@typescript-eslint/utils": "8.46.3", "@typescript-eslint/visitor-keys": "8.46.3", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.46.3", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-sbaQ27XBUopBkRiuY/P9sWGOWUW4rl8fDoHIUmLpZd8uldsTyB4/Zg6bWTegPoTLnKj9Hqgn3QD6cjPNB32Odw=="], - "@typescript-eslint/parser": ["@typescript-eslint/parser@8.46.4", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.46.4", "@typescript-eslint/types": "8.46.4", "@typescript-eslint/typescript-estree": "8.46.4", "@typescript-eslint/visitor-keys": "8.46.4", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w=="], + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.46.3", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.46.3", "@typescript-eslint/types": "8.46.3", "@typescript-eslint/typescript-estree": "8.46.3", "@typescript-eslint/visitor-keys": "8.46.3", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg=="], - "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.46.4", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.46.4", "@typescript-eslint/types": "^8.46.4", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-nPiRSKuvtTN+no/2N1kt2tUh/HoFzeEgOm9fQ6XQk4/ApGqjx0zFIIaLJ6wooR1HIoozvj2j6vTi/1fgAz7UYQ=="], + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.46.3", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.46.3", "@typescript-eslint/types": "^8.46.3", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Fz8yFXsp2wDFeUElO88S9n4w1I4CWDTXDqDr9gYvZgUpwXQqmZBr9+NTTql5R3J7+hrJZPdpiWaB9VNhAKYLuQ=="], - "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.4", "", { "dependencies": { "@typescript-eslint/types": "8.46.4", "@typescript-eslint/visitor-keys": "8.46.4" } }, "sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA=="], + "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.3", "", { "dependencies": { "@typescript-eslint/types": "8.46.3", "@typescript-eslint/visitor-keys": "8.46.3" } }, "sha512-FCi7Y1zgrmxp3DfWfr+3m9ansUUFoy8dkEdeQSgA9gbm8DaHYvZCdkFRQrtKiedFf3Ha6VmoqoAaP68+i+22kg=="], - "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.46.4", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A=="], + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.46.3", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA=="], - "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.46.4", "", { "dependencies": { "@typescript-eslint/types": "8.46.4", "@typescript-eslint/typescript-estree": "8.46.4", "@typescript-eslint/utils": "8.46.4", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-V4QC8h3fdT5Wro6vANk6eojqfbv5bpwHuMsBcJUJkqs2z5XnYhJzyz9Y02eUmF9u3PgXEUiOt4w4KHR3P+z0PQ=="], + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.46.3", "", { "dependencies": { "@typescript-eslint/types": "8.46.3", "@typescript-eslint/typescript-estree": "8.46.3", "@typescript-eslint/utils": "8.46.3", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ZPCADbr+qfz3aiTTYNNkCbUt+cjNwI/5McyANNrFBpVxPt7GqpEYz5ZfdwuFyGUnJ9FdDXbGODUu6iRCI6XRXw=="], - "@typescript-eslint/types": ["@typescript-eslint/types@8.46.4", "", {}, "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w=="], + "@typescript-eslint/types": ["@typescript-eslint/types@8.46.3", "", {}, "sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA=="], - "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.46.4", "", { "dependencies": { "@typescript-eslint/project-service": "8.46.4", "@typescript-eslint/tsconfig-utils": "8.46.4", "@typescript-eslint/types": "8.46.4", "@typescript-eslint/visitor-keys": "8.46.4", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-7oV2qEOr1d4NWNmpXLR35LvCfOkTNymY9oyW+lUHkmCno7aOmIf/hMaydnJBUTBMRCOGZh8YjkFOc8dadEoNGA=="], + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.46.3", "", { "dependencies": { "@typescript-eslint/project-service": "8.46.3", "@typescript-eslint/tsconfig-utils": "8.46.3", "@typescript-eslint/types": "8.46.3", "@typescript-eslint/visitor-keys": "8.46.3", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-f/NvtRjOm80BtNM5OQtlaBdM5BRFUv7gf381j9wygDNL+qOYSNOgtQ/DCndiYi80iIOv76QqaTmp4fa9hwI0OA=="], - "@typescript-eslint/utils": ["@typescript-eslint/utils@8.46.4", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.4", "@typescript-eslint/types": "8.46.4", "@typescript-eslint/typescript-estree": "8.46.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-AbSv11fklGXV6T28dp2Me04Uw90R2iJ30g2bgLz529Koehrmkbs1r7paFqr1vPCZi7hHwYxYtxfyQMRC8QaVSg=="], + "@typescript-eslint/utils": ["@typescript-eslint/utils@8.46.3", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.3", "@typescript-eslint/types": "8.46.3", "@typescript-eslint/typescript-estree": "8.46.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-VXw7qmdkucEx9WkmR3ld/u6VhRyKeiF1uxWwCy/iuNfokjJ7VhsgLSOTjsol8BunSw190zABzpwdNsze2Kpo4g=="], - "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.4", "", { "dependencies": { "@typescript-eslint/types": "8.46.4", "eslint-visitor-keys": "^4.2.1" } }, "sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw=="], + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.3", "", { "dependencies": { "@typescript-eslint/types": "8.46.3", "eslint-visitor-keys": "^4.2.1" } }, "sha512-uk574k8IU0rOF/AjniX8qbLSGURJVUCeM5e4MIMKBFFi8weeiLrG1fyQejyLXQpRZbU/1BuQasleV/RfHC3hHg=="], "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], @@ -665,7 +664,7 @@ "async-function": ["async-function@1.0.0", "", {}, "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA=="], - "autoprefixer": ["autoprefixer@10.4.22", "", { "dependencies": { "browserslist": "^4.27.0", "caniuse-lite": "^1.0.30001754", "fraction.js": "^5.3.4", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-ARe0v/t9gO28Bznv6GgqARmVqcWOV3mfgUPn9becPHMiD3o9BwlRgaeccZnwTpZ7Zwqrm+c1sUSsMxIzQzc8Xg=="], + "autoprefixer": ["autoprefixer@10.4.21", "", { "dependencies": { "browserslist": "^4.24.4", "caniuse-lite": "^1.0.30001702", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ=="], "available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="], @@ -675,7 +674,7 @@ "base64-arraybuffer": ["base64-arraybuffer@1.0.2", "", {}, "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.8.26", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-73lC1ugzwoaWCLJ1LvOgrR5xsMLTqSKIEoMHVtL9E/HNk0PXtTM76ZIm84856/SF7Nv8mPZxKoBsgpm0tR1u1Q=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.8.21", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q=="], "better-auth": ["better-auth@1.3.27", "", { "dependencies": { "@better-auth/core": "1.3.27", "@better-auth/utils": "0.3.0", "@better-fetch/fetch": "1.1.18", "@noble/ciphers": "^2.0.0", "@noble/hashes": "^2.0.0", "@simplewebauthn/browser": "^13.1.2", "@simplewebauthn/server": "^13.1.2", "better-call": "1.0.19", "defu": "^6.1.4", "jose": "^6.1.0", "kysely": "^0.28.5", "nanostores": "^1.0.1", "zod": "^4.1.5" } }, "sha512-SwiGAJ7yU6dBhNg0NdV1h5M8T5sa7/AszZVc4vBfMDrLLmvUfbt9JoJ0uRUJUEdKRAAxTyl9yA+F3+GhtAD80w=="], @@ -687,7 +686,7 @@ "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], - "browserslist": ["browserslist@4.28.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.25", "caniuse-lite": "^1.0.30001754", "electron-to-chromium": "^1.5.249", "node-releases": "^2.0.27", "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" } }, "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ=="], + "browserslist": ["browserslist@4.27.0", "", { "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", "electron-to-chromium": "^1.5.238", "node-releases": "^2.0.26", "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" } }, "sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw=="], "call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="], @@ -697,7 +696,7 @@ "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], - "caniuse-lite": ["caniuse-lite@1.0.30001754", "", {}, "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg=="], + "caniuse-lite": ["caniuse-lite@1.0.30001751", "", {}, "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw=="], "canvg": ["canvg@3.0.11", "", { "dependencies": { "@babel/runtime": "^7.12.5", "@types/raf": "^3.4.0", "core-js": "^3.8.3", "raf": "^3.4.1", "regenerator-runtime": "^0.13.7", "rgbcolor": "^1.0.1", "stackblur-canvas": "^2.0.0", "svg-pathdata": "^6.0.3" } }, "sha512-5ON+q7jCTgMp9cjpu4Jo6XbvfYwSB2Ow3kzHKfIyJfaCAOHLbdKPQqGKgfED/R5B+3TFFfe8pegYA+b423SRyA=="], @@ -717,11 +716,11 @@ "concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="], - "convex": ["convex@1.28.2", "", { "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-KzNsLbcVXb1OhpVQ+vHMgu+hjrsQ1ks5BZwJ2lR8O+nfbeJXE6tHbvsg1H17+ooUDvIDBSMT3vXS+AlodDhTnQ=="], + "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-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.12", "", { "dependencies": { "esm-env": "^1.2.2", "runed": "^0.31.1" }, "peerDependencies": { "convex": "^1.10.0", "svelte": "^5.0.0" } }, "sha512-sUZoYp4ZsokyvKlbbg1dWYB7MkAjZn4nNG9DnADEt9L6KTKuhhnEIt6fdLj+3GnVBUGDTssm17+7ppzFc4y7Gg=="], + "convex-svelte": ["convex-svelte@0.0.11", "", { "peerDependencies": { "convex": "^1.10.0", "svelte": "^5.0.0" } }, "sha512-N/29gg5Zqy72vKL4xHSLk3jGwXVKIWXPs6xzq6KxGL84y/D6hG85pG2CPOzn08EzMmByts5FTkJ5p3var6yDng=="], "cookie": ["cookie@1.0.2", "", {}, "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA=="], @@ -733,7 +732,7 @@ "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], - "daisyui": ["daisyui@5.5.0", "", {}, "sha512-lfeimNM3U1FzjfBotV3iTrxNfBEncHs7kMP62lTLghmO99v7HVZ/lbcOLr/y0Q3JB6Lx7XEi2yC5RQ8BBxdKPA=="], + "daisyui": ["daisyui@5.3.10", "", {}, "sha512-vmjyPmm0hvFhA95KB6uiGmWakziB2pBv6CUcs5Ka/3iMBMn9S+C3SZYx9G9l2JrgTZ1EFn61F/HrPcwaUm2kLQ=="], "data-view-buffer": ["data-view-buffer@1.0.2", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-data-view": "^1.0.2" } }, "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ=="], @@ -767,7 +766,7 @@ "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], - "electron-to-chromium": ["electron-to-chromium@1.5.250", "", {}, "sha512-/5UMj9IiGDMOFBnN4i7/Ry5onJrAGSbOGo3s9FEKmwobGq6xw832ccET0CE3CkkMBZ8GJSlUIesZofpyurqDXw=="], + "electron-to-chromium": ["electron-to-chromium@1.5.243", "", {}, "sha512-ZCphxFW3Q1TVhcgS9blfut1PX8lusVi2SvXQgmEEnK4TCmE1JhH2JkjJN+DNt0pJJwfBri5AROBnz2b/C+YU9g=="], "emoji-picker-element": ["emoji-picker-element@1.27.0", "", {}, "sha512-CeN9g5/kq41+BfYPDpAbE2ejZRHbs1faFDmU9+E9wGA4JWLkok9zo1hwcAFnUhV4lPR3ZuLHiJxNG1mpjoF4TQ=="], @@ -789,7 +788,7 @@ "es-to-primitive": ["es-to-primitive@1.3.0", "", { "dependencies": { "is-callable": "^1.2.7", "is-date-object": "^1.0.5", "is-symbol": "^1.0.4" } }, "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g=="], - "esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="], + "esbuild": ["esbuild@0.25.11", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.11", "@esbuild/android-arm": "0.25.11", "@esbuild/android-arm64": "0.25.11", "@esbuild/android-x64": "0.25.11", "@esbuild/darwin-arm64": "0.25.11", "@esbuild/darwin-x64": "0.25.11", "@esbuild/freebsd-arm64": "0.25.11", "@esbuild/freebsd-x64": "0.25.11", "@esbuild/linux-arm": "0.25.11", "@esbuild/linux-arm64": "0.25.11", "@esbuild/linux-ia32": "0.25.11", "@esbuild/linux-loong64": "0.25.11", "@esbuild/linux-mips64el": "0.25.11", "@esbuild/linux-ppc64": "0.25.11", "@esbuild/linux-riscv64": "0.25.11", "@esbuild/linux-s390x": "0.25.11", "@esbuild/linux-x64": "0.25.11", "@esbuild/netbsd-arm64": "0.25.11", "@esbuild/netbsd-x64": "0.25.11", "@esbuild/openbsd-arm64": "0.25.11", "@esbuild/openbsd-x64": "0.25.11", "@esbuild/openharmony-arm64": "0.25.11", "@esbuild/sunos-x64": "0.25.11", "@esbuild/win32-arm64": "0.25.11", "@esbuild/win32-ia32": "0.25.11", "@esbuild/win32-x64": "0.25.11" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q=="], "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="], @@ -807,7 +806,7 @@ "eslint-plugin-svelte": ["eslint-plugin-svelte@3.13.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.6.1", "@jridgewell/sourcemap-codec": "^1.5.0", "esutils": "^2.0.3", "globals": "^16.0.0", "known-css-properties": "^0.37.0", "postcss": "^8.4.49", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^7.0.0", "semver": "^7.6.3", "svelte-eslint-parser": "^1.4.0" }, "peerDependencies": { "eslint": "^8.57.1 || ^9.0.0", "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-2ohCCQJJTNbIpQCSDSTWj+FN0OVfPmSO03lmSNT7ytqMaWF6kpT86LdzDqtm4sh7TVPl/OEWJ/d7R87bXP2Vjg=="], - "eslint-plugin-turbo": ["eslint-plugin-turbo@2.6.1", "", { "dependencies": { "dotenv": "16.0.3" }, "peerDependencies": { "eslint": ">6.6.0", "turbo": ">2.0.0" } }, "sha512-nxwJD6ReZTxEmq/ZNJXI/Mfa3aXctTpQpJrQZESDC1bxjXXcz4i040P7wG6RsRRsQ+9eYB9D+KdCqERpwNZGzw=="], + "eslint-plugin-turbo": ["eslint-plugin-turbo@2.6.0", "", { "dependencies": { "dotenv": "16.0.3" }, "peerDependencies": { "eslint": ">6.6.0", "turbo": ">2.0.0" } }, "sha512-04TohZhq6YQVXBZVRvrn8ZTj1sUQYZmjUWsfwgFAlaM5Kbk5Fdh5mLBKfhGGzekB55E+Ut9qNzAGh+JW4rjiuA=="], "eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="], @@ -857,7 +856,7 @@ "for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="], - "fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="], + "fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="], "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], @@ -975,7 +974,7 @@ "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], - "jose": ["jose@6.1.1", "", {}, "sha512-GWSqjfOPf4cWOkBzw5THBjtGPhXKqYnfRBzh4Ni+ArTrQQ9unvmsA3oFLqaYKoKe5sjWmGu5wVKg9Ft1i+LQfg=="], + "jose": ["jose@6.1.0", "", {}, "sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], @@ -1169,7 +1168,7 @@ "rgbcolor": ["rgbcolor@1.0.1", "", {}, "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw=="], - "rollup": ["rollup@4.53.2", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.53.2", "@rollup/rollup-android-arm64": "4.53.2", "@rollup/rollup-darwin-arm64": "4.53.2", "@rollup/rollup-darwin-x64": "4.53.2", "@rollup/rollup-freebsd-arm64": "4.53.2", "@rollup/rollup-freebsd-x64": "4.53.2", "@rollup/rollup-linux-arm-gnueabihf": "4.53.2", "@rollup/rollup-linux-arm-musleabihf": "4.53.2", "@rollup/rollup-linux-arm64-gnu": "4.53.2", "@rollup/rollup-linux-arm64-musl": "4.53.2", "@rollup/rollup-linux-loong64-gnu": "4.53.2", "@rollup/rollup-linux-ppc64-gnu": "4.53.2", "@rollup/rollup-linux-riscv64-gnu": "4.53.2", "@rollup/rollup-linux-riscv64-musl": "4.53.2", "@rollup/rollup-linux-s390x-gnu": "4.53.2", "@rollup/rollup-linux-x64-gnu": "4.53.2", "@rollup/rollup-linux-x64-musl": "4.53.2", "@rollup/rollup-openharmony-arm64": "4.53.2", "@rollup/rollup-win32-arm64-msvc": "4.53.2", "@rollup/rollup-win32-ia32-msvc": "4.53.2", "@rollup/rollup-win32-x64-gnu": "4.53.2", "@rollup/rollup-win32-x64-msvc": "4.53.2", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-MHngMYwGJVi6Fmnk6ISmnk7JAHRNF0UkuucA0CUW3N3a4KnONPEZz+vUanQP/ZC/iY1Qkf3bwPWzyY84wEks1g=="], + "rollup": ["rollup@4.52.5", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.52.5", "@rollup/rollup-android-arm64": "4.52.5", "@rollup/rollup-darwin-arm64": "4.52.5", "@rollup/rollup-darwin-x64": "4.52.5", "@rollup/rollup-freebsd-arm64": "4.52.5", "@rollup/rollup-freebsd-x64": "4.52.5", "@rollup/rollup-linux-arm-gnueabihf": "4.52.5", "@rollup/rollup-linux-arm-musleabihf": "4.52.5", "@rollup/rollup-linux-arm64-gnu": "4.52.5", "@rollup/rollup-linux-arm64-musl": "4.52.5", "@rollup/rollup-linux-loong64-gnu": "4.52.5", "@rollup/rollup-linux-ppc64-gnu": "4.52.5", "@rollup/rollup-linux-riscv64-gnu": "4.52.5", "@rollup/rollup-linux-riscv64-musl": "4.52.5", "@rollup/rollup-linux-s390x-gnu": "4.52.5", "@rollup/rollup-linux-x64-gnu": "4.52.5", "@rollup/rollup-linux-x64-musl": "4.52.5", "@rollup/rollup-openharmony-arm64": "4.52.5", "@rollup/rollup-win32-arm64-msvc": "4.52.5", "@rollup/rollup-win32-ia32-msvc": "4.52.5", "@rollup/rollup-win32-x64-gnu": "4.52.5", "@rollup/rollup-win32-x64-msvc": "4.52.5", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw=="], "rou3": ["rou3@0.5.1", "", {}, "sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ=="], @@ -1235,19 +1234,19 @@ "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], - "svelte": ["svelte@5.43.6", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^2.1.0", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-RnyO9VXI85Bmsf4b8AuQFBKFYL3LKUl+ZrifOjvlrQoboAROj5IITVLK1yOXBjwUWUn2BI5cfmurktgCzuZ5QA=="], + "svelte": ["svelte@5.43.2", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "@jridgewell/sourcemap-codec": "^1.5.0", "@sveltejs/acorn-typescript": "^1.0.5", "@types/estree": "^1.0.5", "acorn": "^8.12.1", "aria-query": "^5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", "esm-env": "^1.2.1", "esrap": "^2.1.0", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", "zimmerframe": "^1.1.2" } }, "sha512-ro1umEzX8rT5JpCmlf0PPv7ncD8MdVob9e18bhwqTKNoLjS8kDvhVpaoYVPc+qMwDAOfcwJtyY7ZFSDbOaNPgA=="], "svelte-chartjs": ["svelte-chartjs@3.1.5", "", { "peerDependencies": { "chart.js": "^3.5.0 || ^4.0.0", "svelte": "^4.0.0" } }, "sha512-ka2zh7v5FiwfAX1oMflZ0HkNkgjHjFqANgRyC+vNYXfxtx2ku68Zo+2KgbKeBH2nS1ThDqkIACPzGxy4T0UaoA=="], - "svelte-check": ["svelte-check@4.3.4", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-DVWvxhBrDsd+0hHWKfjP99lsSXASeOhHJYyuKOFYJcP7ThfSCKgjVarE8XfuMWpS5JV3AlDf+iK1YGGo2TACdw=="], + "svelte-check": ["svelte-check@4.3.3", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.25", "chokidar": "^4.0.1", "fdir": "^6.2.0", "picocolors": "^1.0.0", "sade": "^1.7.4" }, "peerDependencies": { "svelte": "^4.0.0 || ^5.0.0-next.0", "typescript": ">=5.0.0" }, "bin": { "svelte-check": "bin/svelte-check" } }, "sha512-RYP0bEwenDXzfv0P1sKAwjZSlaRyqBn0Fz1TVni58lqyEiqgwztTpmodJrGzP6ZT2aHl4MbTvWP6gbmQ3FOnBg=="], "svelte-eslint-parser": ["svelte-eslint-parser@1.4.0", "", { "dependencies": { "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.0.0", "espree": "^10.0.0", "postcss": "^8.4.49", "postcss-scss": "^4.0.9", "postcss-selector-parser": "^7.0.0" }, "peerDependencies": { "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0" }, "optionalPeers": ["svelte"] }, "sha512-fjPzOfipR5S7gQ/JvI9r2H8y9gMGXO3JtmrylHLLyahEMquXI0lrebcjT+9/hNgDej0H7abTyox5HpHmW1PSWA=="], - "svelte-sonner": ["svelte-sonner@1.0.6", "", { "dependencies": { "runed": "^0.28.0" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-cOB6fKVPnJ/wuqHV4dqoTJ/l/g7n3V8goUHqnhIV2wyv55DdoCI1D3VQSBIs7Iy8pkH5ZaNPB8T53jFfXE/6og=="], + "svelte-sonner": ["svelte-sonner@1.0.5", "", { "dependencies": { "runed": "^0.28.0" }, "peerDependencies": { "svelte": "^5.0.0" } }, "sha512-9dpGPFqKb/QWudYqGnEz93vuY+NgCEvyNvxoCLMVGw6sDN/3oVeKV1xiEirW2E1N3vJEyj5imSBNOGltQHA7mg=="], "svg-pathdata": ["svg-pathdata@6.0.3", "", {}, "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw=="], - "tailwindcss": ["tailwindcss@4.1.17", "", {}, "sha512-j9Ee2YjuQqYT9bbRTfTZht9W/ytp5H+jJpZKiYdP/bpnXARAuELt9ofP0lPnmHjbga7SNQIxdTAXCmtKVYjN+Q=="], + "tailwindcss": ["tailwindcss@4.1.16", "", {}, "sha512-pONL5awpaQX4LN5eiv7moSiSPd/DLDzKVRJz8Q9PgzmAdd1R4307GQS2ZpfiN7ZmekdQrfhZZiSE5jkLR4WNaA=="], "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="], @@ -1265,19 +1264,19 @@ "tsyringe": ["tsyringe@4.10.0", "", { "dependencies": { "tslib": "^1.9.3" } }, "sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw=="], - "turbo": ["turbo@2.6.1", "", { "optionalDependencies": { "turbo-darwin-64": "2.6.1", "turbo-darwin-arm64": "2.6.1", "turbo-linux-64": "2.6.1", "turbo-linux-arm64": "2.6.1", "turbo-windows-64": "2.6.1", "turbo-windows-arm64": "2.6.1" }, "bin": { "turbo": "bin/turbo" } }, "sha512-qBwXXuDT3rA53kbNafGbT5r++BrhRgx3sAo0cHoDAeG9g1ItTmUMgltz3Hy7Hazy1ODqNpR+C7QwqL6DYB52yA=="], + "turbo": ["turbo@2.5.8", "", { "optionalDependencies": { "turbo-darwin-64": "2.5.8", "turbo-darwin-arm64": "2.5.8", "turbo-linux-64": "2.5.8", "turbo-linux-arm64": "2.5.8", "turbo-windows-64": "2.5.8", "turbo-windows-arm64": "2.5.8" }, "bin": { "turbo": "bin/turbo" } }, "sha512-5c9Fdsr9qfpT3hA0EyYSFRZj1dVVsb6KIWubA9JBYZ/9ZEAijgUEae0BBR/Xl/wekt4w65/lYLTFaP3JmwSO8w=="], - "turbo-darwin-64": ["turbo-darwin-64@2.6.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-Dm0HwhyZF4J0uLqkhUyCVJvKM9Rw7M03v3J9A7drHDQW0qAbIGBrUijQ8g4Q9Cciw/BXRRd8Uzkc3oue+qn+ZQ=="], + "turbo-darwin-64": ["turbo-darwin-64@2.5.8", "", { "os": "darwin", "cpu": "x64" }, "sha512-Dh5bCACiHO8rUXZLpKw+m3FiHtAp2CkanSyJre+SInEvEr5kIxjGvCK/8MFX8SFRjQuhjtvpIvYYZJB4AGCxNQ=="], - "turbo-darwin-arm64": ["turbo-darwin-arm64@2.6.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-U0PIPTPyxdLsrC3jN7jaJUwgzX5sVUBsKLO7+6AL+OASaa1NbT1pPdiZoTkblBAALLP76FM0LlnsVQOnmjYhyw=="], + "turbo-darwin-arm64": ["turbo-darwin-arm64@2.5.8", "", { "os": "darwin", "cpu": "arm64" }, "sha512-f1H/tQC9px7+hmXn6Kx/w8Jd/FneIUnvLlcI/7RGHunxfOkKJKvsoiNzySkoHQ8uq1pJnhJ0xNGTlYM48ZaJOQ=="], - "turbo-linux-64": ["turbo-linux-64@2.6.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eM1uLWgzv89bxlK29qwQEr9xYWBhmO/EGiH22UGfq+uXr+QW1OvNKKMogSN65Ry8lElMH4LZh0aX2DEc7eC0Mw=="], + "turbo-linux-64": ["turbo-linux-64@2.5.8", "", { "os": "linux", "cpu": "x64" }, "sha512-hMyvc7w7yadBlZBGl/bnR6O+dJTx3XkTeyTTH4zEjERO6ChEs0SrN8jTFj1lueNXKIHh1SnALmy6VctKMGnWfw=="], - "turbo-linux-arm64": ["turbo-linux-arm64@2.6.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-MFFh7AxAQAycXKuZDrbeutfWM5Ep0CEZ9u7zs4Hn2FvOViTCzIfEhmuJou3/a5+q5VX1zTxQrKGy+4Lf5cdpsA=="], + "turbo-linux-arm64": ["turbo-linux-arm64@2.5.8", "", { "os": "linux", "cpu": "arm64" }, "sha512-LQELGa7bAqV2f+3rTMRPnj5G/OHAe2U+0N9BwsZvfMvHSUbsQ3bBMWdSQaYNicok7wOZcHjz2TkESn1hYK6xIQ=="], - "turbo-windows-64": ["turbo-windows-64@2.6.1", "", { "os": "win32", "cpu": "x64" }, "sha512-buq7/VAN7KOjMYi4tSZT5m+jpqyhbRU2EUTTvp6V0Ii8dAkY2tAAjQN1q5q2ByflYWKecbQNTqxmVploE0LVwQ=="], + "turbo-windows-64": ["turbo-windows-64@2.5.8", "", { "os": "win32", "cpu": "x64" }, "sha512-3YdcaW34TrN1AWwqgYL9gUqmZsMT4T7g8Y5Azz+uwwEJW+4sgcJkIi9pYFyU4ZBSjBvkfuPZkGgfStir5BBDJQ=="], - "turbo-windows-arm64": ["turbo-windows-arm64@2.6.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-7w+AD5vJp3R+FB0YOj1YJcNcOOvBior7bcHTodqp90S3x3bLgpr7tE6xOea1e8JkP7GK6ciKVUpQvV7psiwU5Q=="], + "turbo-windows-arm64": ["turbo-windows-arm64@2.5.8", "", { "os": "win32", "cpu": "arm64" }, "sha512-eFC5XzLmgXJfnAK3UMTmVECCwuBcORrWdewoiXBnUm934DY6QN8YowC/srhNnROMpaKaqNeRpoB5FxCww3eteQ=="], "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], @@ -1293,7 +1292,7 @@ "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], - "typescript-eslint": ["typescript-eslint@8.46.4", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.46.4", "@typescript-eslint/parser": "8.46.4", "@typescript-eslint/typescript-estree": "8.46.4", "@typescript-eslint/utils": "8.46.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-KALyxkpYV5Ix7UhvjTwJXZv76VWsHG+NjNlt/z+a17SOQSiOcBdUXdbJdyXi7RPxrBFECtFOiPwUJQusJuCqrg=="], + "typescript-eslint": ["typescript-eslint@8.46.3", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.46.3", "@typescript-eslint/parser": "8.46.3", "@typescript-eslint/typescript-estree": "8.46.3", "@typescript-eslint/utils": "8.46.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-bAfgMavTuGo+8n6/QQDVQz4tZ4f7Soqg53RbrlZQEoAltYop/XR4RAts/I0BrO3TTClTSTFJ0wYbla+P8cEWJA=="], "unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="], @@ -1309,7 +1308,7 @@ "utrie": ["utrie@1.0.2", "", { "dependencies": { "base64-arraybuffer": "^1.0.2" } }, "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw=="], - "vite": ["vite@7.2.2", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ=="], + "vite": ["vite@7.1.12", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug=="], "vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="], @@ -1351,9 +1350,9 @@ "@sveltejs/kit/cookie": ["cookie@0.6.0", "", {}, "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.6.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg=="], - "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.6.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="], @@ -1371,8 +1370,6 @@ "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=="], @@ -1461,9 +1458,9 @@ "@convex-dev/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], - "@convex-dev/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/project-service/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.46.4", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-+/XqaZPIAk6Cjg7NWgSGe27X4zMGqrFqZ8atJsX3CWxH/jACqWnrWI68h7nHQld0y+k9eTTjb9r+KU4twLoo9A=="], + "@convex-dev/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/project-service/@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.46.3", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA=="], - "@convex-dev/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/project-service/@typescript-eslint/types": ["@typescript-eslint/types@8.46.4", "", {}, "sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w=="], + "@convex-dev/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/project-service/@typescript-eslint/types": ["@typescript-eslint/types@8.46.3", "", {}, "sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA=="], "@convex-dev/eslint-plugin/@typescript-eslint/utils/@typescript-eslint/typescript-estree/fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], diff --git a/package.json b/package.json index ecd66ec..0146ab7 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "packages/*" ], "catalog": { - "convex": "1.28.2", + "convex": "^1.28.0", "typescript": "^5.9.2", "better-auth": "1.3.27", "eslint": "^9.39.1", diff --git a/packages/backend/convex/auth.ts b/packages/backend/convex/auth.ts index bcd63a8..a360005 100644 --- a/packages/backend/convex/auth.ts +++ b/packages/backend/convex/auth.ts @@ -1,10 +1,10 @@ -import { createClient, type GenericCtx } from '@convex-dev/better-auth'; -import { convex } from '@convex-dev/better-auth/plugins'; -import { components } from './_generated/api'; -import { type DataModel } from './_generated/dataModel'; -import { mutation, MutationCtx, query, QueryCtx } from './_generated/server'; -import { betterAuth } from 'better-auth'; -import { v } from 'convex/values'; +import { createClient, type GenericCtx } from "@convex-dev/better-auth"; +import { convex } from "@convex-dev/better-auth/plugins"; +import { components } from "./_generated/api"; +import { type DataModel } from "./_generated/dataModel"; +import { mutation, MutationCtx, query, QueryCtx } from "./_generated/server"; +import { betterAuth } from "better-auth"; +import { v } from "convex/values"; const siteUrl = process.env.SITE_URL!; @@ -13,111 +13,106 @@ const siteUrl = process.env.SITE_URL!; export const authComponent = createClient(components.betterAuth); export const createAuth = ( - ctx: GenericCtx, - { optionsOnly } = { optionsOnly: false } + ctx: GenericCtx, + { optionsOnly } = { optionsOnly: false } ) => { - return betterAuth({ - // disable logging when createAuth is called just to generate options. - // this is not required, but there's a lot of noise in logs without it. - logger: { - disabled: optionsOnly - }, - baseURL: siteUrl, - database: authComponent.adapter(ctx), - // Configure simple, non-verified email/password to get started - emailAndPassword: { - enabled: true, - requireEmailVerification: false - }, - plugins: [ - // The Convex plugin is required for Convex compatibility - convex() - ] - }); + return betterAuth({ + // disable logging when createAuth is called just to generate options. + // this is not required, but there's a lot of noise in logs without it. + logger: { + disabled: optionsOnly, + }, + baseURL: siteUrl, + database: authComponent.adapter(ctx), + // Configure simple, non-verified email/password to get started + emailAndPassword: { + enabled: true, + requireEmailVerification: false, + }, + plugins: [ + // The Convex plugin is required for Convex compatibility + convex(), + ], + }); }; // Example function for getting the current user // Feel free to edit, omit, etc. export const getCurrentUser = query({ - args: {}, - handler: async (ctx) => { - const authUser = await authComponent.safeGetAuthUser(ctx as any); - if (!authUser) { - return; - } + args: {}, + handler: async (ctx) => { + const authUser = await authComponent.safeGetAuthUser(ctx as any); + if (!authUser) { + return; + } - const user = await ctx.db - .query('usuarios') - .withIndex('authId', (q) => q.eq('authId', authUser._id)) - .unique(); + const user = await ctx.db + .query("usuarios") + .withIndex("authId", (q) => q.eq("authId", authUser._id)) + .unique(); - if (!user) { - return; - } + if (!user) { + return; + } - let fotoPerfilUrl = null; - if (user.fotoPerfil) { - fotoPerfilUrl = await ctx.storage.getUrl(user.fotoPerfil); - } + if (!user.roleId) { + return { ...user, role: null }; + } - if (!user.roleId) { - return { ...user, role: null, fotoPerfilUrl }; - } + const role = await ctx.db + .query("roles") + .withIndex("by_id", (q) => q.eq("_id", user.roleId)) + .unique(); - const role = await ctx.db - .query('roles') - .withIndex('by_id', (q) => q.eq('_id', user.roleId)) - .unique(); - - return { ...user, role, fotoPerfilUrl }; - } + return { ...user, role }; + }, }); export const getCurrentUserFunction = async (ctx: QueryCtx | MutationCtx) => { - const authUser = await authComponent.safeGetAuthUser(ctx as any); - if (!authUser) { - return; - } + const authUser = await authComponent.safeGetAuthUser(ctx as any); + if (!authUser) { + return; + } - const user = await ctx.db - .query('usuarios') - .withIndex('authId', (q) => q.eq('authId', authUser._id)) - .unique(); - if (!user) { - return; - } - return user; + const user = await ctx.db + .query("usuarios") + .withIndex("authId", (q) => q.eq("authId", authUser._id)) + .unique(); + if (!user) { + return; + } + return user; }; export const createAuthUser = async ( - ctx: MutationCtx, - args: { nome: string; email: string; password: string } + ctx: MutationCtx, + args: { nome: string; email: string; password: string } ) => { - const { auth, headers } = await authComponent.getAuth(createAuth, ctx as any); + const { auth, headers } = await authComponent.getAuth(createAuth, ctx as any); - const result = await auth.api.signUpEmail({ - headers, - body: { - name: args.nome, - email: args.email, - password: args.password - } - }); + const result = await auth.api.signUpEmail({ + headers, + body: { + name: args.nome, + email: args.email, + password: args.password, + }, + }); - return result.user.id; + return result.user.id; }; export const updatePassword = async ( - ctx: MutationCtx, - args: { newPassword: string; currentPassword: string } + ctx: MutationCtx, + args: { newPassword: string; currentPassword: string } ) => { - const { auth, headers } = await authComponent.getAuth(createAuth, ctx as any); + const { auth, headers } = await authComponent.getAuth(createAuth, ctx as any); - await auth.api.changePassword({ - headers, - body: { - currentPassword: args.currentPassword, - newPassword: args.newPassword - } - }); + await auth.api.changePassword({ + headers, + body: { + currentPassword: args.currentPassword, + newPassword: args.newPassword, + }, + }); }; diff --git a/packages/backend/convex/funcionarios.ts b/packages/backend/convex/funcionarios.ts index 91d075f..c85e216 100644 --- a/packages/backend/convex/funcionarios.ts +++ b/packages/backend/convex/funcionarios.ts @@ -1,38 +1,39 @@ -import { v } from 'convex/values'; -import { query, mutation } from './_generated/server'; -import { internal } from './_generated/api'; -import { simboloTipo } from './schema'; -import { getCurrentUserFunction } from './auth'; +import { v } from "convex/values"; +import { query, mutation } from "./_generated/server"; +import { internal } from "./_generated/api"; +import { simboloTipo } from "./schema"; // Validadores para campos opcionais const sexoValidator = v.optional( - v.union(v.literal('masculino'), v.literal('feminino'), v.literal('outro')) + v.union(v.literal("masculino"), v.literal("feminino"), v.literal("outro")) ); const estadoCivilValidator = v.optional( - v.union( - v.literal('solteiro'), - v.literal('casado'), - v.literal('divorciado'), - v.literal('viuvo'), - v.literal('uniao_estavel') - ) + v.union( + v.literal("solteiro"), + v.literal("casado"), + v.literal("divorciado"), + v.literal("viuvo"), + v.literal("uniao_estavel") + ) ); const grauInstrucaoValidator = v.optional( - v.union( - v.literal('fundamental'), - v.literal('medio'), - v.literal('superior'), - v.literal('pos_graduacao'), - v.literal('mestrado'), - v.literal('doutorado') - ) + v.union( + v.literal("fundamental"), + v.literal("medio"), + v.literal("superior"), + v.literal("pos_graduacao"), + v.literal("mestrado"), + v.literal("doutorado") + ) ); const grupoSanguineoValidator = v.optional( - v.union(v.literal('A'), v.literal('B'), v.literal('AB'), v.literal('O')) + v.union(v.literal("A"), v.literal("B"), v.literal("AB"), v.literal("O")) +); +const fatorRHValidator = v.optional( + v.union(v.literal("positivo"), v.literal("negativo")) ); -const fatorRHValidator = v.optional(v.union(v.literal('positivo'), v.literal('negativo'))); const aposentadoValidator = v.optional( - v.union(v.literal('nao'), v.literal('funape_ipsep'), v.literal('inss')) + v.union(v.literal("nao"), v.literal("funape_ipsep"), v.literal("inss")) ); const regimeTrabalhoValidator = v.optional( @@ -45,256 +46,245 @@ const regimeTrabalhoValidator = v.optional( ); export const getAll = query({ - args: {}, - handler: async (ctx) => { - // Autorização: listar funcionários - await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { - recurso: 'funcionarios', - acao: 'listar' - }); - const funcionarios = await ctx.db.query('funcionarios').collect(); - // Retornar apenas os campos necessários para listagem - return funcionarios.map((f) => ({ - _id: f._id, - nome: f.nome, - matricula: f.matricula, - cpf: f.cpf, - rg: f.rg, - nascimento: f.nascimento, - email: f.email, - telefone: f.telefone, - endereco: f.endereco, - cep: f.cep, - cidade: f.cidade, - uf: f.uf, - simboloId: f.simboloId, - simboloTipo: f.simboloTipo, - admissaoData: f.admissaoData, - desligamentoData: f.desligamentoData, - descricaoCargo: f.descricaoCargo - })); - } + args: {}, + handler: async (ctx) => { + // Autorização: listar funcionários + await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { + recurso: "funcionarios", + acao: "listar", + }); + const funcionarios = await ctx.db.query("funcionarios").collect(); + // Retornar apenas os campos necessários para listagem + return funcionarios.map((f) => ({ + _id: f._id, + nome: f.nome, + matricula: f.matricula, + cpf: f.cpf, + rg: f.rg, + nascimento: f.nascimento, + email: f.email, + telefone: f.telefone, + endereco: f.endereco, + cep: f.cep, + cidade: f.cidade, + uf: f.uf, + simboloId: f.simboloId, + simboloTipo: f.simboloTipo, + admissaoData: f.admissaoData, + desligamentoData: f.desligamentoData, + descricaoCargo: f.descricaoCargo, + })); + }, }); export const getById = query({ - args: { id: v.id('funcionarios') }, - // Tipo inferido automaticamente pelo Convex - handler: async (ctx, args) => { - // Autorização: ver funcionário - // await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { - // recurso: "funcionarios", - // acao: "ver", - // }); - return await ctx.db.get(args.id); - } -}); - -export const getCurrent = query({ - args: {}, - handler: async (ctx) => { - const usuarioAtual = await getCurrentUserFunction(ctx); - if (!usuarioAtual) throw new Error('Usuário não encontrado'); - if (!usuarioAtual.funcionarioId) throw new Error('Usuário não é funcionário'); - - return await ctx.db.get(usuarioAtual.funcionarioId); - } + args: { id: v.id("funcionarios") }, + // Tipo inferido automaticamente pelo Convex + handler: async (ctx, args) => { + // Autorização: ver funcionário + await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { + recurso: "funcionarios", + acao: "ver", + }); + return await ctx.db.get(args.id); + }, }); export const create = mutation({ - args: { - // Campos obrigatórios - nome: v.string(), - matricula: v.optional(v.string()), - simboloId: v.id('simbolos'), - nascimento: v.string(), - rg: v.string(), - cpf: v.string(), - endereco: v.string(), - cep: v.string(), - cidade: v.string(), - uf: v.string(), - telefone: v.string(), - email: v.string(), - admissaoData: v.optional(v.string()), - desligamentoData: v.optional(v.string()), - simboloTipo: simboloTipo, + args: { + // Campos obrigatórios + nome: v.string(), + matricula: v.optional(v.string()), + simboloId: v.id("simbolos"), + nascimento: v.string(), + rg: v.string(), + cpf: v.string(), + endereco: v.string(), + cep: v.string(), + cidade: v.string(), + uf: v.string(), + telefone: v.string(), + email: v.string(), + admissaoData: v.optional(v.string()), + desligamentoData: v.optional(v.string()), + simboloTipo: simboloTipo, - // Dados Pessoais Adicionais - nomePai: v.optional(v.string()), - nomeMae: v.optional(v.string()), - naturalidade: v.optional(v.string()), - naturalidadeUF: v.optional(v.string()), - sexo: sexoValidator, - estadoCivil: estadoCivilValidator, - nacionalidade: v.optional(v.string()), + // Dados Pessoais Adicionais + nomePai: v.optional(v.string()), + nomeMae: v.optional(v.string()), + naturalidade: v.optional(v.string()), + naturalidadeUF: v.optional(v.string()), + sexo: sexoValidator, + estadoCivil: estadoCivilValidator, + nacionalidade: v.optional(v.string()), - // Documentos Pessoais - rgOrgaoExpedidor: v.optional(v.string()), - rgDataEmissao: v.optional(v.string()), - carteiraProfissionalNumero: v.optional(v.string()), - carteiraProfissionalSerie: v.optional(v.string()), - carteiraProfissionalDataEmissao: v.optional(v.string()), - reservistaNumero: v.optional(v.string()), - reservistaSerie: v.optional(v.string()), - tituloEleitorNumero: v.optional(v.string()), - tituloEleitorZona: v.optional(v.string()), - tituloEleitorSecao: v.optional(v.string()), - pisNumero: v.optional(v.string()), + // Documentos Pessoais + rgOrgaoExpedidor: v.optional(v.string()), + rgDataEmissao: v.optional(v.string()), + carteiraProfissionalNumero: v.optional(v.string()), + carteiraProfissionalSerie: v.optional(v.string()), + carteiraProfissionalDataEmissao: v.optional(v.string()), + reservistaNumero: v.optional(v.string()), + reservistaSerie: v.optional(v.string()), + tituloEleitorNumero: v.optional(v.string()), + tituloEleitorZona: v.optional(v.string()), + tituloEleitorSecao: v.optional(v.string()), + pisNumero: v.optional(v.string()), - // Formação e Saúde - grauInstrucao: grauInstrucaoValidator, - formacao: v.optional(v.string()), - formacaoRegistro: v.optional(v.string()), - grupoSanguineo: grupoSanguineoValidator, - fatorRH: fatorRHValidator, + // Formação e Saúde + grauInstrucao: grauInstrucaoValidator, + formacao: v.optional(v.string()), + formacaoRegistro: v.optional(v.string()), + grupoSanguineo: grupoSanguineoValidator, + fatorRH: fatorRHValidator, - // Cargo e Vínculo - descricaoCargo: v.optional(v.string()), - nomeacaoPortaria: v.optional(v.string()), - nomeacaoData: v.optional(v.string()), - nomeacaoDOE: v.optional(v.string()), - pertenceOrgaoPublico: v.optional(v.boolean()), - orgaoOrigem: v.optional(v.string()), - aposentado: aposentadoValidator, + // Cargo e Vínculo + descricaoCargo: v.optional(v.string()), + nomeacaoPortaria: v.optional(v.string()), + nomeacaoData: v.optional(v.string()), + nomeacaoDOE: v.optional(v.string()), + pertenceOrgaoPublico: v.optional(v.boolean()), + orgaoOrigem: v.optional(v.string()), + aposentado: aposentadoValidator, - // Dados Bancários - contaBradescoNumero: v.optional(v.string()), - contaBradescoDV: v.optional(v.string()), - contaBradescoAgencia: v.optional(v.string()), + // Dados Bancários + contaBradescoNumero: v.optional(v.string()), + contaBradescoDV: v.optional(v.string()), + contaBradescoAgencia: v.optional(v.string()), - // Documentos Anexos (Storage IDs) - certidaoAntecedentesPF: v.optional(v.id('_storage')), - certidaoAntecedentesJFPE: v.optional(v.id('_storage')), - certidaoAntecedentesSDS: v.optional(v.id('_storage')), - certidaoAntecedentesTJPE: v.optional(v.id('_storage')), - certidaoImprobidade: v.optional(v.id('_storage')), - rgFrente: v.optional(v.id('_storage')), - rgVerso: v.optional(v.id('_storage')), - cpfFrente: v.optional(v.id('_storage')), - cpfVerso: v.optional(v.id('_storage')), - situacaoCadastralCPF: v.optional(v.id('_storage')), - tituloEleitorFrente: v.optional(v.id('_storage')), - tituloEleitorVerso: v.optional(v.id('_storage')), - comprovanteVotacao: v.optional(v.id('_storage')), - carteiraProfissionalFrente: v.optional(v.id('_storage')), - carteiraProfissionalVerso: v.optional(v.id('_storage')), - comprovantePIS: v.optional(v.id('_storage')), - certidaoRegistroCivil: v.optional(v.id('_storage')), - certidaoNascimentoDependentes: v.optional(v.id('_storage')), - cpfDependentes: v.optional(v.id('_storage')), - reservistaDoc: v.optional(v.id('_storage')), - comprovanteEscolaridade: v.optional(v.id('_storage')), - comprovanteResidencia: v.optional(v.id('_storage')), - comprovanteContaBradesco: v.optional(v.id('_storage')), + // Documentos Anexos (Storage IDs) + certidaoAntecedentesPF: v.optional(v.id("_storage")), + certidaoAntecedentesJFPE: v.optional(v.id("_storage")), + certidaoAntecedentesSDS: v.optional(v.id("_storage")), + certidaoAntecedentesTJPE: v.optional(v.id("_storage")), + certidaoImprobidade: v.optional(v.id("_storage")), + rgFrente: v.optional(v.id("_storage")), + rgVerso: v.optional(v.id("_storage")), + cpfFrente: v.optional(v.id("_storage")), + cpfVerso: v.optional(v.id("_storage")), + situacaoCadastralCPF: v.optional(v.id("_storage")), + tituloEleitorFrente: v.optional(v.id("_storage")), + tituloEleitorVerso: v.optional(v.id("_storage")), + comprovanteVotacao: v.optional(v.id("_storage")), + carteiraProfissionalFrente: v.optional(v.id("_storage")), + carteiraProfissionalVerso: v.optional(v.id("_storage")), + comprovantePIS: v.optional(v.id("_storage")), + certidaoRegistroCivil: v.optional(v.id("_storage")), + certidaoNascimentoDependentes: v.optional(v.id("_storage")), + cpfDependentes: v.optional(v.id("_storage")), + reservistaDoc: v.optional(v.id("_storage")), + comprovanteEscolaridade: v.optional(v.id("_storage")), + comprovanteResidencia: v.optional(v.id("_storage")), + comprovanteContaBradesco: v.optional(v.id("_storage")), - // Declarações (Storage IDs) - declaracaoAcumulacaoCargo: v.optional(v.id('_storage')), - declaracaoDependentesIR: v.optional(v.id('_storage')), - declaracaoIdoneidade: v.optional(v.id('_storage')), - termoNepotismo: v.optional(v.id('_storage')), - termoOpcaoRemuneracao: v.optional(v.id('_storage')), - // Dependentes (opcional) - dependentes: v.optional( - v.array( - v.object({ - parentesco: v.union( - v.literal('filho'), - v.literal('filha'), - v.literal('conjuge'), - v.literal('outro') - ), - nome: v.string(), - cpf: v.string(), - nascimento: v.string(), - documentoId: v.optional(v.id('_storage')), - salarioFamilia: v.optional(v.boolean()), - impostoRenda: v.optional(v.boolean()) - }) - ) - ) - }, - returns: v.id('funcionarios'), - handler: async (ctx, args) => { - // Autorização: criar - await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { - recurso: 'funcionarios', - acao: 'criar' - }); - // Unicidade: CPF - const cpfExists = await ctx.db - .query('funcionarios') - .withIndex('by_cpf', (q) => q.eq('cpf', args.cpf)) - .unique(); - if (cpfExists) { - throw new Error('CPF já cadastrado'); - } + // Declarações (Storage IDs) + declaracaoAcumulacaoCargo: v.optional(v.id("_storage")), + declaracaoDependentesIR: v.optional(v.id("_storage")), + declaracaoIdoneidade: v.optional(v.id("_storage")), + termoNepotismo: v.optional(v.id("_storage")), + termoOpcaoRemuneracao: v.optional(v.id("_storage")), + // Dependentes (opcional) + dependentes: v.optional( + v.array( + v.object({ + parentesco: v.union( + v.literal("filho"), + v.literal("filha"), + v.literal("conjuge"), + v.literal("outro") + ), + nome: v.string(), + cpf: v.string(), + nascimento: v.string(), + documentoId: v.optional(v.id("_storage")), + salarioFamilia: v.optional(v.boolean()), + impostoRenda: v.optional(v.boolean()), + }) + ) + ), + }, + returns: v.id("funcionarios"), + handler: async (ctx, args) => { + // Autorização: criar + await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { + recurso: "funcionarios", + acao: "criar", + }); + // Unicidade: CPF + const cpfExists = await ctx.db + .query("funcionarios") + .withIndex("by_cpf", (q) => q.eq("cpf", args.cpf)) + .unique(); + if (cpfExists) { + throw new Error("CPF já cadastrado"); + } - // Unicidade: Matrícula (apenas se fornecida) - if (args.matricula) { - const matriculaExists = await ctx.db - .query('funcionarios') - .withIndex('by_matricula', (q) => q.eq('matricula', args.matricula)) - .unique(); - if (matriculaExists) { - throw new Error( - 'Já existe um funcionário com esta matrícula. Por favor, use outra ou deixe em branco.' - ); - } - } + // Unicidade: Matrícula (apenas se fornecida) + if (args.matricula) { + const matriculaExists = await ctx.db + .query("funcionarios") + .withIndex("by_matricula", (q) => q.eq("matricula", args.matricula)) + .unique(); + if (matriculaExists) { + throw new Error( + "Já existe um funcionário com esta matrícula. Por favor, use outra ou deixe em branco." + ); + } + } - const novoFuncionarioId = await ctx.db.insert('funcionarios', args); - return novoFuncionarioId; - } + const novoFuncionarioId = await ctx.db.insert("funcionarios", args); + return novoFuncionarioId; + }, }); export const update = mutation({ - args: { - id: v.id('funcionarios'), - // Campos obrigatórios - nome: v.string(), - matricula: v.optional(v.string()), - simboloId: v.id('simbolos'), - nascimento: v.string(), - rg: v.string(), - cpf: v.string(), - endereco: v.string(), - cep: v.string(), - cidade: v.string(), - uf: v.string(), - telefone: v.string(), - email: v.string(), - admissaoData: v.optional(v.string()), - desligamentoData: v.optional(v.string()), - simboloTipo: simboloTipo, + args: { + id: v.id("funcionarios"), + // Campos obrigatórios + nome: v.string(), + matricula: v.optional(v.string()), + simboloId: v.id("simbolos"), + nascimento: v.string(), + rg: v.string(), + cpf: v.string(), + endereco: v.string(), + cep: v.string(), + cidade: v.string(), + uf: v.string(), + telefone: v.string(), + email: v.string(), + admissaoData: v.optional(v.string()), + desligamentoData: v.optional(v.string()), + simboloTipo: simboloTipo, - // Dados Pessoais Adicionais - nomePai: v.optional(v.string()), - nomeMae: v.optional(v.string()), - naturalidade: v.optional(v.string()), - naturalidadeUF: v.optional(v.string()), - sexo: sexoValidator, - estadoCivil: estadoCivilValidator, - nacionalidade: v.optional(v.string()), + // Dados Pessoais Adicionais + nomePai: v.optional(v.string()), + nomeMae: v.optional(v.string()), + naturalidade: v.optional(v.string()), + naturalidadeUF: v.optional(v.string()), + sexo: sexoValidator, + estadoCivil: estadoCivilValidator, + nacionalidade: v.optional(v.string()), - // Documentos Pessoais - rgOrgaoExpedidor: v.optional(v.string()), - rgDataEmissao: v.optional(v.string()), - carteiraProfissionalNumero: v.optional(v.string()), - carteiraProfissionalSerie: v.optional(v.string()), - carteiraProfissionalDataEmissao: v.optional(v.string()), - reservistaNumero: v.optional(v.string()), - reservistaSerie: v.optional(v.string()), - tituloEleitorNumero: v.optional(v.string()), - tituloEleitorZona: v.optional(v.string()), - tituloEleitorSecao: v.optional(v.string()), - pisNumero: v.optional(v.string()), + // Documentos Pessoais + rgOrgaoExpedidor: v.optional(v.string()), + rgDataEmissao: v.optional(v.string()), + carteiraProfissionalNumero: v.optional(v.string()), + carteiraProfissionalSerie: v.optional(v.string()), + carteiraProfissionalDataEmissao: v.optional(v.string()), + reservistaNumero: v.optional(v.string()), + reservistaSerie: v.optional(v.string()), + tituloEleitorNumero: v.optional(v.string()), + tituloEleitorZona: v.optional(v.string()), + tituloEleitorSecao: v.optional(v.string()), + pisNumero: v.optional(v.string()), - // Formação e Saúde - grauInstrucao: grauInstrucaoValidator, - formacao: v.optional(v.string()), - formacaoRegistro: v.optional(v.string()), - grupoSanguineo: grupoSanguineoValidator, - fatorRH: fatorRHValidator, + // Formação e Saúde + grauInstrucao: grauInstrucaoValidator, + formacao: v.optional(v.string()), + formacaoRegistro: v.optional(v.string()), + grupoSanguineo: grupoSanguineoValidator, + fatorRH: fatorRHValidator, // Cargo e Vínculo descricaoCargo: v.optional(v.string()), @@ -306,188 +296,188 @@ export const update = mutation({ orgaoOrigem: v.optional(v.string()), aposentado: aposentadoValidator, - // Dados Bancários - contaBradescoNumero: v.optional(v.string()), - contaBradescoDV: v.optional(v.string()), - contaBradescoAgencia: v.optional(v.string()), + // Dados Bancários + contaBradescoNumero: v.optional(v.string()), + contaBradescoDV: v.optional(v.string()), + contaBradescoAgencia: v.optional(v.string()), - // Documentos Anexos (Storage IDs) - certidaoAntecedentesPF: v.optional(v.id('_storage')), - certidaoAntecedentesJFPE: v.optional(v.id('_storage')), - certidaoAntecedentesSDS: v.optional(v.id('_storage')), - certidaoAntecedentesTJPE: v.optional(v.id('_storage')), - certidaoImprobidade: v.optional(v.id('_storage')), - rgFrente: v.optional(v.id('_storage')), - rgVerso: v.optional(v.id('_storage')), - cpfFrente: v.optional(v.id('_storage')), - cpfVerso: v.optional(v.id('_storage')), - situacaoCadastralCPF: v.optional(v.id('_storage')), - tituloEleitorFrente: v.optional(v.id('_storage')), - tituloEleitorVerso: v.optional(v.id('_storage')), - comprovanteVotacao: v.optional(v.id('_storage')), - carteiraProfissionalFrente: v.optional(v.id('_storage')), - carteiraProfissionalVerso: v.optional(v.id('_storage')), - comprovantePIS: v.optional(v.id('_storage')), - certidaoRegistroCivil: v.optional(v.id('_storage')), - certidaoNascimentoDependentes: v.optional(v.id('_storage')), - cpfDependentes: v.optional(v.id('_storage')), - reservistaDoc: v.optional(v.id('_storage')), - comprovanteEscolaridade: v.optional(v.id('_storage')), - comprovanteResidencia: v.optional(v.id('_storage')), - comprovanteContaBradesco: v.optional(v.id('_storage')), + // Documentos Anexos (Storage IDs) + certidaoAntecedentesPF: v.optional(v.id("_storage")), + certidaoAntecedentesJFPE: v.optional(v.id("_storage")), + certidaoAntecedentesSDS: v.optional(v.id("_storage")), + certidaoAntecedentesTJPE: v.optional(v.id("_storage")), + certidaoImprobidade: v.optional(v.id("_storage")), + rgFrente: v.optional(v.id("_storage")), + rgVerso: v.optional(v.id("_storage")), + cpfFrente: v.optional(v.id("_storage")), + cpfVerso: v.optional(v.id("_storage")), + situacaoCadastralCPF: v.optional(v.id("_storage")), + tituloEleitorFrente: v.optional(v.id("_storage")), + tituloEleitorVerso: v.optional(v.id("_storage")), + comprovanteVotacao: v.optional(v.id("_storage")), + carteiraProfissionalFrente: v.optional(v.id("_storage")), + carteiraProfissionalVerso: v.optional(v.id("_storage")), + comprovantePIS: v.optional(v.id("_storage")), + certidaoRegistroCivil: v.optional(v.id("_storage")), + certidaoNascimentoDependentes: v.optional(v.id("_storage")), + cpfDependentes: v.optional(v.id("_storage")), + reservistaDoc: v.optional(v.id("_storage")), + comprovanteEscolaridade: v.optional(v.id("_storage")), + comprovanteResidencia: v.optional(v.id("_storage")), + comprovanteContaBradesco: v.optional(v.id("_storage")), - // Declarações (Storage IDs) - declaracaoAcumulacaoCargo: v.optional(v.id('_storage')), - declaracaoDependentesIR: v.optional(v.id('_storage')), - declaracaoIdoneidade: v.optional(v.id('_storage')), - termoNepotismo: v.optional(v.id('_storage')), - termoOpcaoRemuneracao: v.optional(v.id('_storage')), - // Dependentes (opcional) - dependentes: v.optional( - v.array( - v.object({ - parentesco: v.union( - v.literal('filho'), - v.literal('filha'), - v.literal('conjuge'), - v.literal('outro') - ), - nome: v.string(), - cpf: v.string(), - nascimento: v.string(), - documentoId: v.optional(v.id('_storage')), - salarioFamilia: v.optional(v.boolean()), - impostoRenda: v.optional(v.boolean()) - }) - ) - ) - }, - returns: v.null(), - handler: async (ctx, args) => { - // Autorização: editar - await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { - recurso: 'funcionarios', - acao: 'editar' - }); - // Unicidade: CPF (excluindo o próprio registro) - const cpfExists = await ctx.db - .query('funcionarios') - .withIndex('by_cpf', (q) => q.eq('cpf', args.cpf)) - .unique(); - if (cpfExists && cpfExists._id !== args.id) { - throw new Error('CPF já cadastrado'); - } + // Declarações (Storage IDs) + declaracaoAcumulacaoCargo: v.optional(v.id("_storage")), + declaracaoDependentesIR: v.optional(v.id("_storage")), + declaracaoIdoneidade: v.optional(v.id("_storage")), + termoNepotismo: v.optional(v.id("_storage")), + termoOpcaoRemuneracao: v.optional(v.id("_storage")), + // Dependentes (opcional) + dependentes: v.optional( + v.array( + v.object({ + parentesco: v.union( + v.literal("filho"), + v.literal("filha"), + v.literal("conjuge"), + v.literal("outro") + ), + nome: v.string(), + cpf: v.string(), + nascimento: v.string(), + documentoId: v.optional(v.id("_storage")), + salarioFamilia: v.optional(v.boolean()), + impostoRenda: v.optional(v.boolean()), + }) + ) + ), + }, + returns: v.null(), + handler: async (ctx, args) => { + // Autorização: editar + await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { + recurso: "funcionarios", + acao: "editar", + }); + // Unicidade: CPF (excluindo o próprio registro) + const cpfExists = await ctx.db + .query("funcionarios") + .withIndex("by_cpf", (q) => q.eq("cpf", args.cpf)) + .unique(); + if (cpfExists && cpfExists._id !== args.id) { + throw new Error("CPF já cadastrado"); + } - // Unicidade: Matrícula (apenas se fornecida, excluindo o próprio registro) - if (args.matricula) { - const matriculaExists = await ctx.db - .query('funcionarios') - .withIndex('by_matricula', (q) => q.eq('matricula', args.matricula)) - .unique(); - if (matriculaExists && matriculaExists._id !== args.id) { - throw new Error( - 'Já existe um funcionário com esta matrícula. Por favor, use outra ou deixe em branco.' - ); - } - } + // Unicidade: Matrícula (apenas se fornecida, excluindo o próprio registro) + if (args.matricula) { + const matriculaExists = await ctx.db + .query("funcionarios") + .withIndex("by_matricula", (q) => q.eq("matricula", args.matricula)) + .unique(); + if (matriculaExists && matriculaExists._id !== args.id) { + throw new Error( + "Já existe um funcionário com esta matrícula. Por favor, use outra ou deixe em branco." + ); + } + } - const usuarioExists = await ctx.db - .query('usuarios') - .withIndex('by_funcionarioId', (q) => q.eq('funcionarioId', args.id)) - .unique(); + const usuarioExists = await ctx.db + .query("usuarios") + .withIndex("by_funcionarioId", (q) => q.eq("funcionarioId", args.id)) + .unique(); - if (usuarioExists && usuarioExists.email !== args.email) { - await ctx.db.patch(usuarioExists._id, { - email: args.email - }); - } + if (usuarioExists && usuarioExists.email !== args.email) { + await ctx.db.patch(usuarioExists._id, { + email: args.email, + }); + } - const { id, ...updateData } = args; - await ctx.db.patch(id, updateData); - return null; - } + const { id, ...updateData } = args; + await ctx.db.patch(id, updateData); + return null; + }, }); export const remove = mutation({ - args: { id: v.id('funcionarios') }, - returns: v.null(), - handler: async (ctx, args) => { - // Autorização: excluir - await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { - recurso: 'funcionarios', - acao: 'excluir' - }); - // TODO: Talvez queiramos também remover os arquivos do storage - await ctx.db.delete(args.id); - return null; - } + args: { id: v.id("funcionarios") }, + returns: v.null(), + handler: async (ctx, args) => { + // Autorização: excluir + await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { + recurso: "funcionarios", + acao: "excluir", + }); + // TODO: Talvez queiramos também remover os arquivos do storage + await ctx.db.delete(args.id); + return null; + }, }); // Query para obter ficha completa para impressão export const getFichaCompleta = query({ - args: { id: v.id('funcionarios') }, - // Tipo inferido automaticamente pelo Convex - handler: async (ctx, args) => { - await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { - recurso: 'funcionarios', - acao: 'ver' - }); - const funcionario = await ctx.db.get(args.id); - if (!funcionario) { - return null; - } + args: { id: v.id("funcionarios") }, + // Tipo inferido automaticamente pelo Convex + handler: async (ctx, args) => { + await ctx.runQuery(internal.permissoesAcoes.assertPermissaoAcaoAtual, { + recurso: "funcionarios", + acao: "ver", + }); + const funcionario = await ctx.db.get(args.id); + if (!funcionario) { + return null; + } - // Buscar informações do símbolo - const simbolo = await ctx.db.get(funcionario.simboloId); + // Buscar informações do símbolo + const simbolo = await ctx.db.get(funcionario.simboloId); - // Buscar cursos do funcionário - const cursos = await ctx.db - .query('cursos') - .withIndex('by_funcionario', (q) => q.eq('funcionarioId', args.id)) - .collect(); + // Buscar cursos do funcionário + const cursos = await ctx.db + .query("cursos") + .withIndex("by_funcionario", (q) => q.eq("funcionarioId", args.id)) + .collect(); - // Buscar URLs dos certificados - const cursosComUrls = await Promise.all( - cursos.map(async (curso) => { - let certificadoUrl = null; - if (curso.certificadoId) { - certificadoUrl = await ctx.storage.getUrl(curso.certificadoId); - } - return { - ...curso, - certificadoUrl - }; - }) - ); + // Buscar URLs dos certificados + const cursosComUrls = await Promise.all( + cursos.map(async (curso) => { + let certificadoUrl = null; + if (curso.certificadoId) { + certificadoUrl = await ctx.storage.getUrl(curso.certificadoId); + } + return { + ...curso, + certificadoUrl, + }; + }) + ); - return { - ...funcionario, - simbolo: simbolo - ? { - nome: simbolo.nome, - descricao: simbolo.descricao, - tipo: simbolo.tipo, - vencValor: simbolo.vencValor, - repValor: simbolo.repValor, - valor: simbolo.valor - } - : null, - cursos: cursosComUrls - }; - } + return { + ...funcionario, + simbolo: simbolo + ? { + nome: simbolo.nome, + descricao: simbolo.descricao, + tipo: simbolo.tipo, + vencValor: simbolo.vencValor, + repValor: simbolo.repValor, + valor: simbolo.valor, + } + : null, + cursos: cursosComUrls, + }; + }, }); // Mutation: Configurar gestor (apenas para TI_MASTER) export const configurarGestor = mutation({ - args: { - funcionarioId: v.id('funcionarios'), - gestorId: v.optional(v.id('usuarios')) - }, - returns: v.null(), - handler: async (ctx, args) => { - await ctx.db.patch(args.funcionarioId, { - gestorId: args.gestorId - }); - return null; - } + args: { + funcionarioId: v.id("funcionarios"), + gestorId: v.optional(v.id("usuarios")), + }, + returns: v.null(), + handler: async (ctx, args) => { + await ctx.db.patch(args.funcionarioId, { + gestorId: args.gestorId, + }); + return null; + }, }); diff --git a/packages/backend/convex/monitoramento.ts b/packages/backend/convex/monitoramento.ts index 6189bed..3d32bc3 100644 --- a/packages/backend/convex/monitoramento.ts +++ b/packages/backend/convex/monitoramento.ts @@ -139,6 +139,25 @@ export const configurarAlerta = mutation({ */ export const listarAlertas = query({ args: {}, + returns: v.array( + v.object({ + _id: v.id('alertConfigurations'), + metricName: v.string(), + threshold: v.number(), + operator: v.union( + v.literal('>'), + v.literal('<'), + v.literal('>='), + v.literal('<='), + v.literal('==') + ), + enabled: v.boolean(), + notifyByEmail: v.boolean(), + notifyByChat: v.boolean(), + createdBy: v.id('usuarios'), + lastModified: v.number() + }) + ), handler: async (ctx) => { const alertas = await ctx.db.query('alertConfigurations').collect(); return alertas;