import React, { useState, useMemo, useCallback, memo } from "react"; import { useBuilder } from "../../contexts/builder/BuilderContext"; import { useIsMobile, useIsTablet } from "../../hooks/useResponsive"; import { ResponsiveContainer } from "../ui/Responsive"; import { NumericPropertyInput } from "../ui/NumericPropertyInput"; import { ProductTableProperties } from "./ProductTableProperties"; import { CustomerInfoProperties } from "./CustomerInfoProperties"; import { CompanyInfoProperties } from "./CompanyInfoProperties"; import { CompanyLogoProperties } from "./CompanyLogoProperties"; import { WoocommerceOrderDateProperties } from "./WoocommerceOrderDateProperties"; import { WoocommerceInvoiceNumberProperties } from "./WoocommerceInvoiceNumberProperties"; import { DynamicTextProperties } from "./DynamicTextProperties"; import { MentionsProperties } from "./MentionsProperties"; import { DocumentTypeProperties } from "./DocumentTypeProperties"; import { TextProperties } from "./TextProperties"; import { ShapeProperties } from "./ShapeProperties"; import { ImageProperties } from "./ImageProperties"; import { LineProperties } from "./LineProperties"; import { ElementProperties } from "./ElementProperties"; interface PropertiesPanelProps { className?: string; } // Éléments qui ont leurs propres composants de propriétés spécialisés const ELEMENTS_WITH_CUSTOM_PROPERTIES = new Set([ "product_table", "customer_info", "company_info", "company_logo", "woocommerce_order_date", "woocommerce_invoice_number", "document_type", "dynamic_text", "mentions", "text", "rectangle", "circle", "image", "line", ]); // Mapping des types d'éléments vers leurs composants de propriétés const ELEMENT_PROPERTY_COMPONENTS: Record< string, React.ComponentType<{ element: any; onChange: (elementId: string, property: string, value: unknown) => void; activeTab: { [key: string]: "fonctionnalites" | "personnalisation" | "positionnement"; }; setActiveTab: (tabs: { [key: string]: "fonctionnalites" | "personnalisation" | "positionnement"; }) => void; }> > = { product_table: ProductTableProperties, customer_info: CustomerInfoProperties, company_info: CompanyInfoProperties, company_logo: CompanyLogoProperties, woocommerce_order_date: WoocommerceOrderDateProperties, woocommerce_invoice_number: WoocommerceInvoiceNumberProperties, document_type: DocumentTypeProperties, dynamic_text: DynamicTextProperties, mentions: MentionsProperties, text: TextProperties, rectangle: ShapeProperties, circle: ShapeProperties, image: ImageProperties, line: LineProperties, }; export const PropertiesPanel = memo(function PropertiesPanel({ className, }: PropertiesPanelProps) { const { state, updateElement, removeElement } = useBuilder(); const [activeTab, setActiveTab] = useState<{ [key: string]: "fonctionnalites" | "personnalisation" | "positionnement"; }>({}); const isMobile = useIsMobile(); const _isTablet = useIsTablet(); // Optimisation: mémoriser les éléments sélectionnés const selectedElements = useMemo(() => { const selected = state.elements.filter((el) => state.selection.selectedElements.includes(el.id), ); return selected; }, [state.elements, state.selection.selectedElements]); // Optimisation: mémoriser les handlers const handlePropertyChange = useCallback( (elementId: string, property: string, value: unknown) => { updateElement(elementId, { [property]: value }); }, [updateElement], ); const handleDeleteSelected = useCallback(() => { state.selection.selectedElements.forEach((id) => { removeElement(id); }); }, [state.selection.selectedElements, removeElement]); if (selectedElements.length === 0) { return (
e.stopPropagation()} style={{ padding: isMobile ? "8px" : "12px", backgroundColor: "#f9f9f9", border: "1px solid #ddd", borderRadius: "4px", minHeight: isMobile ? "150px" : "200px", maxHeight: isMobile ? "calc(50vh - 16px)" : "calc(100vh - 32px)", display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", textAlign: "center", }} >
🎯
{isMobile ? "Sélectionnez un élément" : "Sélectionnez un élément pour modifier ses propriétés"}
Cliquez sur un élément du canvas pour commencer
); } return (
e.stopPropagation()} style={{ padding: "12px", backgroundColor: "#f9f9f9", border: "1px solid #ddd", borderRadius: "4px", maxHeight: "calc(100vh - 32px)", overflowY: "auto", }} >

Propriétés ({selectedElements.length})

{selectedElements.map((element) => (
e.stopPropagation()} style={{ marginBottom: "16px", padding: "12px", backgroundColor: "#ffffff", border: "1px solid #e0e0e0", borderRadius: "4px", maxHeight: "calc(100vh - 120px)", overflowY: "auto", }} >
{element.type} - {element.id.slice(0, 8)}
{/* Propriétés communes - masquées pour les éléments qui ont leurs propres onglets */} {!ELEMENTS_WITH_CUSTOM_PROPERTIES.has(element.type) && (
handlePropertyChange(element.id, "x", value) } /> handlePropertyChange(element.id, "y", value) } /> handlePropertyChange(element.id, "width", value) } /> handlePropertyChange(element.id, "height", value) } /> handlePropertyChange(element.id, "rotation", value) } />
handlePropertyChange( element.id, "opacity", parseFloat(e.target.value), ) } style={{ width: "100%" }} /> {Math.round((element.opacity || 1) * 100)}%
)} {/* Composant de propriétés spécifique selon le type d'élément */} {(() => { const PropertyComponent = ELEMENT_PROPERTY_COMPONENTS[element.type]; if (PropertyComponent) { return ( ); } return null; })()} {!ELEMENTS_WITH_CUSTOM_PROPERTIES.has(element.type) && ( )}
))}
); });