// @deno-types="https://cdn.sheetjs.com/xlsx-0.20.3/package/types/index.d.ts" import * as XLSX from "https://cdn.sheetjs.com/xlsx-0.20.3/package/xlsx.mjs"; import { useRef } from "preact/hooks"; import { useSignal } from "@preact/signals"; export default function ImportNotes() { const file = useSignal(null); const dragging = useSignal(false); const uploading = useSignal(false); const error = useSignal(null); const success = useSignal(null); const inputRef = useRef(null); function pickFile(f: File) { if (!f.name.match(/\.xlsx?$/i)) { error.value = "Fichier invalide — format attendu : .xlsx"; return; } file.value = f; error.value = null; success.value = null; } function onDragOver(e: DragEvent) { e.preventDefault(); dragging.value = true; } function onDragLeave() { dragging.value = false; } function onDrop(e: DragEvent) { e.preventDefault(); dragging.value = false; const f = e.dataTransfer?.files?.[0]; if (f) pickFile(f); } function onInputChange(e: Event) { const f = (e.target as HTMLInputElement).files?.[0]; if (f) pickFile(f); } async function doImport() { if (!file.value) return; uploading.value = true; error.value = null; success.value = null; try { const arrayBuffer = await file.value.arrayBuffer(); const workbook = XLSX.read(arrayBuffer, { type: "array" }); let imported = 0; let failed = 0; for (const sheetName of workbook.SheetNames) { const sheet = workbook.Sheets[sheetName]; const rows = XLSX.utils.sheet_to_json<{ numEtud: number; idModule: string; note: number; }>(sheet, { header: ["numEtud", "idModule", "note"], range: 1 }); for (const row of rows) { const res = await fetch("/notes/api/notes", { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(row), }); if (res.ok) imported++; else failed++; } } success.value = `Import terminé — ${imported} ajouté${imported !== 1 ? "s" : ""}${ failed > 0 ? `, ${failed} erreur${failed !== 1 ? "s" : ""}` : "" }`; } catch { error.value = "Erreur lors de la lecture du fichier."; } finally { uploading.value = false; } } function downloadTemplate() { const wb = XLSX.utils.book_new(); const ws = XLSX.utils.aoa_to_sheet([["numEtud", "idModule", "note"]]); XLSX.utils.book_append_sheet(wb, ws, "Notes"); XLSX.writeFile(wb, "modele_notes.xlsx"); } return (
inputRef.current?.click()} > {file.value ? {file.value.name} : ( <> Glisser le fichier .xlsx ici ou cliquer pour parcourir )}
{error.value &&

{error.value}

} {success.value && (

{success.value}

)}

Format : numEtud | idModule |{" "} note

); }