import { useState, ReactNode } from 'react';
import { BaseElement } from '../../types/elements';
import { NumericPropertyInput } from '../ui/NumericPropertyInput';
import { ColorPropertyInput } from '../ui/ColorPropertyInput';
import { getEditorFeatureFlags } from '../../utils/editorFeatures';
interface OrderNumberElement extends BaseElement {
fontFamily?: string;
fontSize?: number;
color?: string;
fontWeight?: string;
fontStyle?: string;
textAlign?: string;
contentAlign?: string;
showHeaders?: boolean;
showBackground?: boolean;
showBorders?: boolean;
showLabel?: boolean;
showDate?: boolean;
labelText?: string;
labelPosition?: string;
dateFormat?: string;
headerFontSize?: number;
headerFontFamily?: string;
headerFontWeight?: string;
headerFontStyle?: string;
headerTextColor?: string;
textColor?: string;
numberFontSize?: number;
bodyFontSize?: number;
dateFontSize?: number;
bodyFontFamily?: string;
bodyFontWeight?: string;
bodyFontStyle?: string;
backgroundColor?: string;
borderColor?: string;
padding?: number;
}
// Composant Accordion personnalisé
const Accordion = ({ title, children, defaultOpen = false }: {
title: string;
children: ReactNode;
defaultOpen?: boolean;
}) => {
const [isOpen, setIsOpen] = useState(defaultOpen);
return (
setIsOpen(!isOpen)}
style={{
padding: '12px',
backgroundColor: '#f8f9fa',
cursor: 'pointer',
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
borderBottom: isOpen ? '1px solid #e9ecef' : 'none'
}}
>
{title}
▼
{isOpen && (
{children}
)}
);
};
// Composant Toggle personnalisé
const Toggle = ({ checked, onChange, label, description }: {
checked: boolean;
onChange: (checked: boolean) => void;
label: string;
description: string;
}) => (
{label}
onChange(!checked)}
style={{
position: 'relative',
width: '44px',
height: '24px',
backgroundColor: checked ? '#007bff' : '#ccc',
borderRadius: '12px',
cursor: 'pointer',
transition: 'background-color 0.2s ease',
border: 'none'
}}
>
{description}
);
interface OrderNumberPropertiesProps {
element: OrderNumberElement;
onChange: (elementId: string, property: string, value: unknown) => void;
activeTab: { [key: string]: 'fonctionnalites' | 'personnalisation' | 'positionnement' };
setActiveTab: (tabs: { [key: string]: 'fonctionnalites' | 'personnalisation' | 'positionnement' }) => void;
}
export function OrderNumberProperties({ element, onChange, activeTab, setActiveTab }: OrderNumberPropertiesProps) {
const currentTab = activeTab[element.id] || 'fonctionnalites';
const setCurrentTab = (tab: 'fonctionnalites' | 'personnalisation' | 'positionnement') => {
setActiveTab({ ...activeTab, [element.id]: tab });
};
const { canUseEditorThemes } = getEditorFeatureFlags();
return (
<>
{/* Système d'onglets pour Order Number */}
setCurrentTab('fonctionnalites')}
style={{
flex: '1 1 30%',
padding: '8px 6px',
backgroundColor: currentTab === 'fonctionnalites' ? '#007bff' : '#f0f0f0',
color: currentTab === 'fonctionnalites' ? '#fff' : '#333',
border: 'none',
cursor: 'pointer',
fontSize: '11px',
fontWeight: 'bold',
borderRadius: '3px 3px 0 0',
minWidth: '0',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis'
}}
title="Fonctionnalités"
>
Fonctionnalités
setCurrentTab('personnalisation')}
style={{
flex: '1 1 30%',
padding: '8px 6px',
backgroundColor: currentTab === 'personnalisation' ? '#007bff' : '#f0f0f0',
color: currentTab === 'personnalisation' ? '#fff' : '#333',
border: 'none',
cursor: 'pointer',
fontSize: '11px',
fontWeight: 'bold',
borderRadius: '3px 3px 0 0',
minWidth: '0',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis'
}}
title="Personnalisation"
>
Personnalisation
setCurrentTab('positionnement')}
style={{
flex: '1 1 30%',
padding: '8px 6px',
backgroundColor: currentTab === 'positionnement' ? '#007bff' : '#f0f0f0',
color: currentTab === 'positionnement' ? '#fff' : '#333',
border: 'none',
cursor: 'pointer',
fontSize: '11px',
fontWeight: 'bold',
borderRadius: '3px 3px 0 0',
minWidth: '0',
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis'
}}
title="Positionnement"
>
Positionnement
{/* Onglet Fonctionnalités */}
{currentTab === 'fonctionnalites' && (
<>
{/* Accordéon Propriétés de texte générales */}
Police générale
onChange(element.id, 'fontFamily', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Arial
Helvetica
Times New Roman
Georgia
Verdana
Tahoma
Trebuchet MS
Calibri
Cambria
Segoe UI
Courier New
Impact
Lucida Sans
Comic Sans MS
Lucida Console
onChange(element.id, 'fontSize', value)}
/>
onChange(element.id, 'color', value)}
/>
Style de police général
onChange(element.id, 'fontWeight', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Normal
Gras
100 (Très fin)
200
300 (Fin)
400 (Normal)
500
600
700 (Gras)
800
900 (Très gras)
Style italique général
onChange(element.id, 'fontStyle', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Normal
Italique
Oblique
Alignement du texte
onChange(element.id, 'textAlign', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Gauche
Centre
Droite
Justifié
{/* Section Structure de l'information */}
Structure des informations
onChange(element.id, 'showHeaders', checked)}
label="Afficher les en-têtes"
description="Affiche les titres des sections"
/>
onChange(element.id, 'showBackground', checked)}
label="Afficher le fond"
description="Affiche un fond coloré derrière le numéro de commande"
/>
onChange(element.id, 'showBorders', checked)}
label="Afficher les bordures"
description="Affiche les bordures autour des sections"
/>
{/* Section Éléments principaux */}
Éléments principaux
onChange(element.id, 'showLabel', checked)}
label="Afficher le libellé"
description="Affiche un texte devant le numéro de commande"
/>
onChange(element.id, 'showDate', checked)}
label="Afficher la date"
description="Affiche la date de commande"
/>
{/* Section Configuration du libellé */}
{element.showLabel !== false && (
Configuration du libellé
Position du libellé
onChange(element.id, 'labelPosition', e.target.value)}
style={{
width: '100%',
padding: '6px',
border: '1px solid #ccc',
borderRadius: '4px',
fontSize: '12px'
}}
>
Au-dessus du numéro
À gauche du numéro
À droite du numéro
En-dessous du numéro
)}
{/* Section Format de date */}
{element.showDate !== false && (
Format de date
Format d'affichage
onChange(element.id, 'dateFormat', e.target.value)}
style={{
width: '100%',
padding: '6px',
border: '1px solid #ccc',
borderRadius: '4px',
fontSize: '12px'
}}
>
JJ/MM/AAAA (31/12/2024)
MM/JJ/AAAA (12/31/2024)
JJ-MM-AAAA (31-12-2024)
AAAA-MM-JJ (2024-12-31)
JJ MMM AAAA (31 déc. 2024)
Format d'affichage de la date de commande
)}
ℹ️ Information
Le numéro de commande est automatiquement récupéré depuis WooCommerce.
Le format et la numérotation sont gérés par votre configuration WooCommerce.
>
)}
{/* Onglet Personnalisation */}
{currentTab === 'personnalisation' && (
<>
{canUseEditorThemes && (
{[
{
id: 'clean',
name: 'Propre',
preview: (
),
styles: {
backgroundColor: '#ffffff',
borderColor: '#f3f4f6',
textColor: '#374151',
headerTextColor: '#111827',
showHeaders: true,
showBackground: true,
showBorders: true
}
},
{
id: 'subtle',
name: 'Discret',
preview: (
),
styles: {
backgroundColor: '#fafbfc',
borderColor: '#f1f5f9',
textColor: '#475569',
headerTextColor: '#334155',
showHeaders: true,
showBackground: true,
showBorders: true
}
},
{
id: 'elegant',
name: 'Élégant',
preview: (
),
styles: {
backgroundColor: '#fefefe',
borderColor: '#f3e8ff',
textColor: '#6b21a8',
headerTextColor: '#581c87',
showHeaders: true,
showBackground: true,
showBorders: true
}
},
{
id: 'corporate',
name: 'Corporate',
preview: (
),
styles: {
borderColor: '#e5e7eb',
textColor: '#374151',
headerTextColor: '#111827',
showHeaders: true,
showBackground: false,
showBorders: true
}
},
{
id: 'minimal',
name: 'Minimal',
preview: (
),
styles: {
borderColor: 'transparent',
textColor: '#6b7280',
headerTextColor: '#374151',
showHeaders: false,
showBackground: false,
showBorders: false
}
}
].map(theme => (
{
// Appliquer toutes les propriétés du thème
Object.entries(theme.styles).forEach(([property, value]) => {
if (property !== 'backgroundColor' || theme.styles.showBackground !== false) {
onChange(element.id, property, value);
}
});
}}
style={{
padding: '6px',
border: '2px solid transparent',
borderRadius: '6px',
backgroundColor: '#ffffff',
cursor: 'pointer',
textAlign: 'center',
transition: 'all 0.2s ease',
minHeight: '70px',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
gap: '4px'
}}
onMouseEnter={(e) => {
e.currentTarget.style.borderColor = '#007bff';
e.currentTarget.style.backgroundColor = '#f8f9fa';
e.currentTarget.style.transform = 'translateY(-1px)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.borderColor = 'transparent';
e.currentTarget.style.backgroundColor = '#ffffff';
e.currentTarget.style.transform = 'translateY(0)';
}}
title={`Appliquer le thème ${theme.name}`}
>
{theme.name}
{theme.preview}
))}
)}
{element.showLabel !== false && element.showHeaders !== false && (
onChange(element.id, 'headerFontSize', value)}
/>
Famille de police
onChange(element.id, 'headerFontFamily', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Arial
Helvetica
Times New Roman
Georgia
Verdana
Tahoma
Trebuchet MS
Calibri
Cambria
Segoe UI
Courier New
Impact
Lucida Sans
Comic Sans MS
Lucida Console
Épaisseur de police
onChange(element.id, 'headerFontWeight', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Normal
Gras
100 (Très fin)
200
300 (Fin)
400 (Normal)
500
600
700 (Gras)
800
900 (Très gras)
Style de police
onChange(element.id, 'headerFontStyle', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Normal
Italique
Oblique
onChange(element.id, 'headerTextColor', value)}
/>
)}
{/* Accordéon Police du numéro et de la date */}
onChange(element.id, 'numberFontSize', value)}
/>
onChange(element.id, 'dateFontSize', value)}
/>
Famille de police
onChange(element.id, 'bodyFontFamily', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Arial
Helvetica
Times New Roman
Georgia
Verdana
Tahoma
Trebuchet MS
Calibri
Cambria
Segoe UI
Courier New
Impact
Lucida Sans
Comic Sans MS
Lucida Console
Épaisseur de police
onChange(element.id, 'bodyFontWeight', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Normal
Gras
100 (Très fin)
200
300 (Fin)
400 (Normal)
500
600
700 (Gras)
800
900 (Très gras)
Style de police
onChange(element.id, 'bodyFontStyle', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Normal
Italique
Oblique
onChange(element.id, 'textColor', value)}
/>
{/* Accordéon Couleurs */}
onChange(element.id, 'headerTextColor', value)}
/>
onChange(element.id, 'textColor', value)}
/>
{element.showBackground !== false && (
onChange(element.id, 'backgroundColor', value)}
/>
)}
onChange(element.id, 'borderColor', value)}
/>
>
)}
{/* Onglet Positionnement */}
{currentTab === 'positionnement' && (
<>
onChange(element.id, 'x', value)}
/>
onChange(element.id, 'y', value)}
/>
onChange(element.id, 'width', value)}
/>
onChange(element.id, 'height', value)}
/>
Alignement du contenu
onChange(element.id, 'contentAlign', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Aligner à gauche
Centrer
Aligner à droite
Alignement horizontal
onChange(element.id, 'textAlign', e.target.value)}
style={{
width: '100%',
padding: '4px 8px',
border: '1px solid #ccc',
borderRadius: '3px',
fontSize: '12px'
}}
>
Gauche
Centre
Droite
Justifié
onChange(element.id, 'padding', value)}
/>
>
)}
>
);
}