Checkpoint: v4 : Import Excel (.xlsx) et CSV natif pour établissements et contacts, pages Mes Solutions Numériques et Solutions Logicielles avec accordéons, CGU réaffichée à chaque session, moteur de recherche multicritères corrigé. 33 tests passés, 0 erreur TypeScript.
This commit is contained in:
@@ -23,6 +23,7 @@ import {
|
||||
X,
|
||||
} from "lucide-react";
|
||||
import { useState, useMemo, Fragment, useRef, useCallback } from "react";
|
||||
import * as XLSX from "xlsx";
|
||||
import { toast } from "sonner";
|
||||
|
||||
// ─── Types ────────────────────────────────────────────────────────────────────
|
||||
@@ -863,14 +864,25 @@ function ImportEtablissementsPanel() {
|
||||
setDone(0);
|
||||
}, []);
|
||||
|
||||
const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
const isXlsx = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
|
||||
const reader = new FileReader();
|
||||
reader.onload = (ev) => parseCSV(ev.target?.result as string);
|
||||
reader.readAsText(file, "UTF-8");
|
||||
if (isXlsx) {
|
||||
reader.onload = (ev) => {
|
||||
const data = new Uint8Array(ev.target?.result as ArrayBuffer);
|
||||
const wb = XLSX.read(data, { type: "array" });
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
const csv = XLSX.utils.sheet_to_csv(ws, { FS: ";" });
|
||||
parseCSV(csv);
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
} else {
|
||||
reader.onload = (ev) => parseCSV(ev.target?.result as string);
|
||||
reader.readAsText(file, "UTF-8");
|
||||
}
|
||||
};
|
||||
|
||||
const handleImport = async () => {
|
||||
setImporting(true);
|
||||
let count = 0;
|
||||
@@ -939,7 +951,7 @@ function ImportEtablissementsPanel() {
|
||||
<FileText size={32} className="mx-auto text-muted-foreground/40 mb-2" />
|
||||
<p className="text-sm font-medium text-foreground">Cliquez pour sélectionner un fichier CSV</p>
|
||||
<p className="text-xs text-muted-foreground mt-1">Séparateur : point-virgule, virgule ou tabulation</p>
|
||||
<input ref={fileRef} type="file" accept=".csv,.txt" className="hidden" onChange={handleFile} />
|
||||
<input ref={fileRef} type="file" accept=".csv,.txt,.xlsx,.xls" className="hidden" onChange={handleFile} />
|
||||
</div>
|
||||
|
||||
{/* Colonnes attendues */}
|
||||
@@ -1078,11 +1090,22 @@ function ImportContactsPanel() {
|
||||
const handleFile = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
const isXlsx = file.name.endsWith(".xlsx") || file.name.endsWith(".xls");
|
||||
const reader = new FileReader();
|
||||
reader.onload = (ev) => parseCSV(ev.target?.result as string);
|
||||
reader.readAsText(file, "UTF-8");
|
||||
if (isXlsx) {
|
||||
reader.onload = (ev) => {
|
||||
const data = new Uint8Array(ev.target?.result as ArrayBuffer);
|
||||
const wb = XLSX.read(data, { type: "array" });
|
||||
const ws = wb.Sheets[wb.SheetNames[0]];
|
||||
const csv = XLSX.utils.sheet_to_csv(ws, { FS: ";" });
|
||||
parseCSV(csv);
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
} else {
|
||||
reader.onload = (ev) => parseCSV(ev.target?.result as string);
|
||||
reader.readAsText(file, "UTF-8");
|
||||
}
|
||||
};
|
||||
|
||||
const handleImport = async () => {
|
||||
setImporting(true);
|
||||
let count = 0;
|
||||
@@ -1150,7 +1173,7 @@ function ImportContactsPanel() {
|
||||
<FileText size={32} className="mx-auto text-muted-foreground/40 mb-2" />
|
||||
<p className="text-sm font-medium text-foreground">Cliquez pour sélectionner un fichier CSV</p>
|
||||
<p className="text-xs text-muted-foreground mt-1">Séparateur : point-virgule, virgule ou tabulation</p>
|
||||
<input ref={fileRef} type="file" accept=".csv,.txt" className="hidden" onChange={handleFile} />
|
||||
<input ref={fileRef} type="file" accept=".csv,.txt,.xlsx,.xls" className="hidden" onChange={handleFile} />
|
||||
</div>
|
||||
|
||||
{/* Colonnes attendues */}
|
||||
|
||||
Reference in New Issue
Block a user