feat: enhance file upload component and backend schema

- Updated the FileUpload component to improve file handling and state management, including better cancellation logic and input handling.
- Added a new alias in the Svelte configuration for easier backend access.
- Enhanced the backend schema to include a gestorSuperiorId for better team management and query capabilities.
- Refactored queries and mutations in the backend to support the new structure and improve data retrieval for subordinate teams.
This commit is contained in:
2025-11-14 22:11:06 -03:00
parent 731f95d0b5
commit 9b3b095c01
6 changed files with 278 additions and 161 deletions

View File

@@ -32,7 +32,7 @@
const client = useConvexClient();
let fileInput: HTMLInputElement;
let fileInput: HTMLInputElement | null = null;
let uploading = $state(false);
let error = $state<string | null>(null);
let fileName = $state<string>("");
@@ -50,31 +50,52 @@
// Buscar URL do arquivo quando houver um storageId
$effect(() => {
if (value && !fileName) {
// Tem storageId mas não é um upload recente
loadExistingFile(value);
if (!value || fileName) {
return;
}
let cancelled = false;
const storageId = value;
(async () => {
try {
const url = await client.storage.getUrl(storageId as any);
if (!url || cancelled) {
return;
}
fileUrl = url;
const path = url.split('?')[0] ?? '';
const nameFromUrl = path.split('/').pop() ?? 'arquivo';
fileName = decodeURIComponent(nameFromUrl);
const extension = fileName.toLowerCase().split('.').pop();
const isPdf =
extension === 'pdf' || url.includes('.pdf') || url.includes('application/pdf');
if (isPdf) {
fileType = 'application/pdf';
previewUrl = null;
} else {
fileType = 'image/jpeg';
previewUrl = url;
}
} catch (err) {
if (!cancelled) {
console.error('Erro ao carregar arquivo existente:', err);
}
}
})();
return () => {
cancelled = true;
};
});
async function loadExistingFile(storageId: string) {
try {
const url = await client.storage.getUrl(storageId as any);
if (url) {
async function handleFileSelect(event: Event) {
const target = event.target as HTMLInputElement;
const file = target.files?.[0];
// Detectar tipo pelo URL ou assumir PDF
if (url.includes('.pdf') || url.includes('application/pdf')) {
fileType = 'application/pdf';
} else {
fileType = 'image/jpeg';
previewUrl = url; // Para imagens, a URL serve como preview
}
}
} catch (err) {
console.error('Erro ao carregar arquivo existente:', err);
}
}
error = null;
@@ -144,6 +165,17 @@
function openFileDialog() {
fileInput?.click();
}
function setFileInput(node: HTMLInputElement) {
fileInput = node;
return {
destroy() {
if (fileInput === node) {
fileInput = null;
}
},
};
}
</script>
<div class="form-control w-full">
@@ -175,7 +207,7 @@
<input
id="file-upload-input"
type="file"
bind:this={fileInput}
use:setFileInput
onchange={handleFileSelect}
accept=".pdf,.jpg,.jpeg,.png"
class="hidden"
@@ -194,7 +226,7 @@
</div>
{:else}
<div class="bg-success/10 flex h-12 w-12 items-center justify-center rounded">
<File class="text-success h-6 w-6" strokeWidth={2} />
<FileIcon class="text-success h-6 w-6" strokeWidth={2} />
</div>
{/if}
</div>