From 8b40bf867bbbef14ebca6378e85393505302e454 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sofia=20Reh=C3=A1kov=C3=A1?= <125893846+sofiarehakova@users.noreply.github.com> Date: Mon, 3 Nov 2025 16:40:07 +0100 Subject: [PATCH] vykaz firma --- frontend/app/pages/dashboard/company.vue | 345 ++++++++++++++++++++++- 1 file changed, 343 insertions(+), 2 deletions(-) diff --git a/frontend/app/pages/dashboard/company.vue b/frontend/app/pages/dashboard/company.vue index 6edc630..5811343 100644 --- a/frontend/app/pages/dashboard/company.vue +++ b/frontend/app/pages/dashboard/company.vue @@ -13,14 +13,355 @@ useSeoMeta({ }); const user = useSanctumUser(); + +type ExistingReport = { + fileName: string + size: number + uploadedBy: 'STUDENT' | 'FIRMA' + uploadedAt: string + url?: string +} + +type Decision = 'APPROVE' | 'REJECT' | null + +type Student = { + id: number | string + name: string + existingReport: ExistingReport | null + + // lokálny klientsky stav (front-only) + reportFile: File | null + localPreviewUrl?: string | null + decision: Decision + rejectNote: string + + // UI stav pre daného študenta + loading?: boolean + success?: boolean + error?: string | null + formRef?: any +} + +// zoznam studentov +const students = ref([ + { + id: 1, + name: 'Ján Novák', + existingReport: { + fileName: 'vykaz-jan-novak.pdf', + size: 356812, + uploadedBy: 'STUDENT', + uploadedAt: '2025-03-04T10:15:00Z', + url: '/api/mock-download/vykaz-jan-novak.pdf', + }, + reportFile: null, + localPreviewUrl: null, + decision: null, + rejectNote: '', + loading: false, + success: false, + error: null, + formRef: null, + }, + { + id: 2, + name: 'Petra Kováčová', + existingReport: null, + reportFile: null, + localPreviewUrl: null, + decision: null, + rejectNote: '', + loading: false, + success: false, + error: null, + formRef: null, + }, +]) + +// validačné pravidlá +const allowedMimes = ['application/pdf'] +const maxSizeBytes = 10 * 1024 * 1024 // 10 MB +const rules = { + reportRequiredIfMissing: (student: Student) => (file: File | null) => + !!student.existingReport || !!file || 'Výkaz je povinný, ak ešte neexistuje.', + isPdf: (file: File | null) => + !file || allowedMimes.includes(file.type) || 'Povolený je iba PDF súbor.', + maxSize: (file: File | null) => + !file || file.size <= maxSizeBytes || 'Maximálna veľkosť súboru je 10 MB.', + decisionRequired: (v: Decision) => !!v || 'Vyberte, či výkaz potvrdzujete alebo zamietate.', +} + +// helpers +function formatSize(bytes: number) { + if (bytes < 1024) return `${bytes} B` + if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(0)} KB` + return `${(bytes / (1024 * 1024)).toFixed(1)} MB` +} +function hasReport(s: Student) { + return !!s.existingReport +} +function onReportChange(s: Student, file: File | null) { + if (s.localPreviewUrl) { + URL.revokeObjectURL(s.localPreviewUrl) + s.localPreviewUrl = null + } + s.reportFile = file + if (file) s.localPreviewUrl = URL.createObjectURL(file) +} + +async function submitFor(s: Student) { + s.error = null + s.success = false + + // validácia + const ok = await s.formRef?.validate?.() + if (!ok?.valid) return + + s.loading = true + try { + const fd = new FormData() + if (s.reportFile) { + fd.append('report', s.reportFile) // nový/aktualizovaný výkaz + } else if (hasReport(s)) { + fd.append('report_exists', 'true') + // fd.append('report_id', '...') // neskôr z backendu + } + if (s.decision) fd.append('decision', s.decision) + if (s.rejectNote && s.decision === 'REJECT') fd.append('reject_note', s.rejectNote) + fd.append('student_id', String(s.id)) + + console.log('Submitting for student', s.name, Array.from(fd.entries())) + await new Promise((r) => setTimeout(r, 600)) + + s.success = true + if (s.localPreviewUrl) { + URL.revokeObjectURL(s.localPreviewUrl) + s.localPreviewUrl = null + } + s.reportFile = null + s.decision = null + s.rejectNote = '' + s.formRef?.resetValidation?.() + } catch (e: any) { + s.error = e?.message ?? 'Odoslanie zlyhalo. Skúste znova.' + } finally { + s.loading = false + } +} \ No newline at end of file + + + \ No newline at end of file