import React, { useState } from 'react'; import { Checklist, ChecklistSection, ChecklistItem, ItemType } from '../types'; import { saveToStore } from '../db'; import { Plus, Trash2, Save, FileSpreadsheet, Upload } from 'lucide-react'; import * as XLSX from 'xlsx'; const generateId = (prefix: string) => `${prefix}_${Date.now().toString(36)}_${Math.random().toString(36).substring(2, 5)}`; interface ChecklistManagerProps { onSave: () => void; } const ChecklistManager: React.FC = ({ onSave }) => { const [name, setName] = useState(''); const [sections, setSections] = useState([ { id: generateId('sec'), title: 'Section Principale', items: [] } ]); const addSection = () => { setSections([...sections, { id: generateId('sec'), title: 'Nouvelle Section', items: [] }]); }; const removeSection = (id: string) => { setSections(sections.filter(s => s.id !== id)); }; const addItem = (sectionId: string) => { setSections(sections.map(s => s.id === sectionId ? { ...s, items: [...s.items, { id: generateId('item'), label: 'Nouveau point', type: ItemType.PassFail, required: true }] } : s)); }; const updateItem = (sectionId: string, itemId: string, updates: any) => { setSections(sections.map(s => s.id === sectionId ? { ...s, items: s.items.map(i => i.id === itemId ? { ...i, ...updates } : i) } : s)); }; const removeItem = (sectionId: string, itemId: string) => { setSections(sections.map(s => s.id === sectionId ? { ...s, items: s.items.filter(i => i.id !== itemId) } : s)); }; const handleSave = async () => { if (!name.trim()) return alert('Nom du modèle requis'); const now = Date.now(); const newChecklist: Checklist = { id: generateId('cl'), name, version: '1.0.0', sections, createdAt: now, lastModified: now }; await saveToStore('checklists', newChecklist); onSave(); }; const downloadExcelTemplate = () => { const data = [ ["Section", "Point de controle", "Type (PASS_FAIL, TEXT, NUMBER, DROPDOWN)", "Requis (OUI/NON)", "Options (si DROPDOWN, separer par ;)"], ["Zone Reception", "Etat des palettes", "PASS_FAIL", "OUI", ""], ["Zone Reception", "Temperature produit", "NUMBER", "OUI", ""], ["Hygiene", "Proprete des mains", "PASS_FAIL", "OUI", ""], ["Stockage", "Type de stockage", "DROPDOWN", "NON", "Frigo;Ambiant;Sec"] ]; const ws = XLSX.utils.aoa_to_sheet(data); const wb = XLSX.utils.book_new(); XLSX.utils.book_append_sheet(wb, ws, "Modele"); XLSX.writeFile(wb, "modele_audit.xlsx"); }; const handleImportExcel = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) return; const reader = new FileReader(); reader.onload = (event) => { const bstr = event.target?.result; const wb = XLSX.read(bstr, { type: 'binary' }); const wsname = wb.SheetNames[0]; const ws = wb.Sheets[wsname]; const data: any[] = XLSX.utils.sheet_to_json(ws); const sectionsMap = new Map(); data.forEach((row: any) => { const sectionName = row["Section"] || "Sans Titre"; const itemLabel = row["Point de controle"] || "Point sans nom"; let typeStr = (row["Type (PASS_FAIL, TEXT, NUMBER, DROPDOWN)"] || "PASS_FAIL").toUpperCase(); const required = (row["Requis (OUI/NON)"] || "OUI").toUpperCase() === "OUI"; const optionsStr = row["Options (si DROPDOWN, separer par ;)"] || ""; const type = Object.values(ItemType).includes(typeStr as ItemType) ? (typeStr as ItemType) : ItemType.PassFail; const newItem: ChecklistItem = { id: generateId('item'), label: itemLabel, type, required, options: optionsStr ? optionsStr.split(';').map((s: string) => s.trim()) : undefined }; if (!sectionsMap.has(sectionName)) { sectionsMap.set(sectionName, []); } sectionsMap.get(sectionName)?.push(newItem); }); const newSections: ChecklistSection[] = Array.from(sectionsMap.entries()).map(([title, items]) => ({ id: generateId('sec'), title, items })); if (newSections.length > 0) { setName(file.name.replace(/\.[^/.]+$/, "")); setSections(newSections); } }; reader.readAsBinaryString(file); }; return (

Éditeur de Modèle

setName(e.target.value)} placeholder="Ex: Audit Qualité Atelier" className="w-full text-2xl font-black border-none focus:ring-0 p-0 placeholder-slate-200 text-slate-800 transition-all" />
{sections.map((section, sIdx) => (
{ const newSections = [...sections]; newSections[sIdx].title = e.target.value; setSections(newSections); }} className="bg-transparent text-xl font-black text-indigo-900 border-none focus:ring-0 p-0" />
{section.items.map((item) => (
updateItem(section.id, item.id, { label: e.target.value })} className="w-full font-bold text-slate-700 border-none focus:ring-0 p-0 text-base" />
))}
))}
); }; export default ChecklistManager;