Refactor FileUpload component and improve type safety
- Rename imported File icon to FileIcon to avoid naming conflicts - Update onUpload type to use globalThis.File - Reformat loadExistingFile and related code for better readability - Add stricter typing for funcionarioId and related data in documentos and editar pages - Improve error handling and response validation in file upload logic - Add keyed each blocks for better Svelte list rendering stability - Fix minor formatting issues in breadcrumb links
This commit is contained in:
@@ -11,15 +11,16 @@
|
||||
categoriasDocumentos,
|
||||
getDocumentosByCategoria
|
||||
} from '$lib/utils/documentos';
|
||||
import type { Id, Doc } from '@sgse-app/backend/convex/_generated/dataModel';
|
||||
|
||||
const client = useConvexClient();
|
||||
|
||||
let funcionarioId = $derived($page.params.funcionarioId as string);
|
||||
let funcionarioId = $derived($page.params.funcionarioId as Id<'funcionarios'>);
|
||||
|
||||
let funcionario = $state<any>(null);
|
||||
let funcionario = $state<Doc<'funcionarios'> | null>(null);
|
||||
let documentosStorage = $state<Record<string, string | undefined>>({});
|
||||
let loading = $state(true);
|
||||
let filtro = $state<string>('todos'); // todos, enviados, pendentes
|
||||
let filtro = $state<'todos' | 'enviados' | 'pendentes'>('todos'); // todos, enviados, pendentes
|
||||
|
||||
async function load() {
|
||||
try {
|
||||
@@ -27,7 +28,7 @@
|
||||
|
||||
// Carregar dados do funcionário
|
||||
const data = await client.query(api.funcionarios.getById, {
|
||||
id: funcionarioId as any
|
||||
id: funcionarioId
|
||||
});
|
||||
|
||||
if (!data) {
|
||||
@@ -39,8 +40,10 @@
|
||||
|
||||
// Mapear storage IDs dos documentos
|
||||
documentos.forEach((doc) => {
|
||||
if ((data as any)[doc.campo]) {
|
||||
documentosStorage[doc.campo] = (data as any)[doc.campo];
|
||||
const campo = doc.campo as keyof Doc<'funcionarios'>;
|
||||
const valor = data[campo];
|
||||
if (typeof valor === 'string') {
|
||||
documentosStorage[doc.campo] = valor;
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
@@ -63,13 +66,23 @@
|
||||
body: file
|
||||
});
|
||||
|
||||
const { storageId } = await result.json();
|
||||
const uploadResponse = await result.json();
|
||||
if (
|
||||
!uploadResponse ||
|
||||
typeof uploadResponse !== 'object' ||
|
||||
!('storageId' in uploadResponse) ||
|
||||
typeof uploadResponse.storageId !== 'string'
|
||||
) {
|
||||
throw new Error('Resposta inválida ao fazer upload');
|
||||
}
|
||||
|
||||
const storageId = uploadResponse.storageId;
|
||||
|
||||
// Atualizar documento no funcionário
|
||||
await client.mutation(api.documentos.updateDocumento, {
|
||||
funcionarioId: funcionarioId as any,
|
||||
funcionarioId,
|
||||
campo,
|
||||
storageId: storageId as any
|
||||
storageId: storageId as Id<'_storage'>
|
||||
});
|
||||
|
||||
// Atualizar localmente
|
||||
@@ -77,8 +90,11 @@
|
||||
|
||||
// Recarregar
|
||||
await load();
|
||||
} catch (err: any) {
|
||||
throw new Error(err?.message || 'Erro ao fazer upload');
|
||||
} catch (err) {
|
||||
if (err instanceof Error && err.message) {
|
||||
throw err;
|
||||
}
|
||||
throw new Error('Erro ao fazer upload');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +102,7 @@
|
||||
try {
|
||||
// Atualizar documento no funcionário (set to null)
|
||||
await client.mutation(api.documentos.updateDocumento, {
|
||||
funcionarioId: funcionarioId as any,
|
||||
funcionarioId,
|
||||
campo,
|
||||
storageId: null
|
||||
});
|
||||
@@ -96,8 +112,10 @@
|
||||
|
||||
// Recarregar
|
||||
await load();
|
||||
} catch (err: any) {
|
||||
alert('Erro ao remover documento: ' + (err?.message || ''));
|
||||
} catch (err) {
|
||||
const mensagem =
|
||||
err instanceof Error && err.message ? err.message : 'Erro ao remover documento';
|
||||
alert('Erro ao remover documento: ' + mensagem);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +148,9 @@
|
||||
<div class="breadcrumbs mb-4 text-sm">
|
||||
<ul>
|
||||
<li>
|
||||
<a href={resolve('/recursos-humanos')} class="text-primary hover:underline">Recursos Humanos</a>
|
||||
<a href={resolve('/recursos-humanos')} class="text-primary hover:underline"
|
||||
>Recursos Humanos</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href={resolve('/recursos-humanos/funcionarios')} class="text-primary hover:underline"
|
||||
@@ -305,7 +325,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Documentos por Categoria -->
|
||||
{#each categoriasDocumentos as categoria}
|
||||
{#each categoriasDocumentos as categoria (categoria)}
|
||||
{@const docsCategoria = getDocumentosByCategoria(categoria).filter((doc) => {
|
||||
const temDocumento = !!documentosStorage[doc.campo];
|
||||
if (filtro === 'enviados') return temDocumento;
|
||||
@@ -322,7 +342,7 @@
|
||||
</h2>
|
||||
|
||||
<div class="grid grid-cols-1 gap-4 md:grid-cols-2">
|
||||
{#each docsCategoria as doc}
|
||||
{#each docsCategoria as doc (doc.campo)}
|
||||
<FileUpload
|
||||
label={doc.nome}
|
||||
helpUrl={doc.helpUrl}
|
||||
|
||||
@@ -483,7 +483,9 @@
|
||||
<div class="breadcrumbs mb-4 text-sm">
|
||||
<ul>
|
||||
<li>
|
||||
<a href={resolve('/recursos-humanos')} class="text-primary hover:underline">Recursos Humanos</a>
|
||||
<a href={resolve('/recursos-humanos')} class="text-primary hover:underline"
|
||||
>Recursos Humanos</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href={resolve('/recursos-humanos/funcionarios')} class="text-primary hover:underline"
|
||||
|
||||
Reference in New Issue
Block a user