/** * ========================================================================= * PLATEFORME ECO-PANNEAU.FR - VERSION 1.0.0 * Socle UI (3/4) - Design System et Layout Principal * ========================================================================= */ // ========================================================================= // 1. DESIGN SYSTEM : COMPOSANTS UI UNIFIÉS (FACTORISÉS) // ========================================================================= window.Button = ({ children, onClick, disabled, variant = 'primary', icon: Icon, className = '', type = 'button', title = '', ...props }) => { const baseClass = "px-4 py-2 rounded-xl text-xs font-bold transition flex items-center justify-center gap-2 shadow-sm border border-transparent"; const variants = { primary: "bg-emerald-600 text-white hover:bg-emerald-700 shadow-md", success: "bg-emerald-50 text-emerald-600 hover:bg-emerald-100", successSolid: "bg-emerald-600 text-white hover:bg-emerald-700 shadow-md", danger: "bg-red-50 text-red-600 hover:bg-red-100", dangerSolid: "bg-red-600 text-white hover:bg-red-700 shadow-md", warning: "bg-orange-50 text-orange-600 hover:bg-orange-100", warningSolid: "bg-orange-500 text-white hover:bg-orange-600 shadow-md", info: "bg-blue-50 text-blue-700 hover:bg-blue-100", infoSolid: "bg-blue-600 text-white hover:bg-blue-700 shadow-md", secondary: "bg-slate-100 text-slate-700 hover:bg-slate-200 border-slate-200", outline: "bg-white border-slate-200 text-slate-600 hover:bg-slate-50", purple: "bg-purple-50 text-purple-700 hover:bg-purple-100", dark: "bg-slate-900 text-white hover:bg-slate-800 shadow-md", ghost: "bg-transparent text-slate-500 hover:text-slate-800 hover:bg-slate-100 shadow-none border-transparent" }; const handleAction = (e) => { if (disabled) return; if (onClick) onClick(e); if (type === 'submit') { const form = e.currentTarget.closest('form'); if (form && typeof form.requestSubmit === 'function') { form.requestSubmit(); } } }; return (
{ if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); handleAction(e); } }} title={title} className={`${baseClass} ${variants[variant] || variants.primary} ${className} ${disabled ? 'opacity-50 cursor-not-allowed' : 'cursor-pointer'}`} {...props} > {Icon && } {children} {type === 'submit' && }
); }; window.IconBadge = ({ icon: Icon, variant = 'info', size = 'md', className = '' }) => { const variants = { primary: "bg-emerald-100 text-emerald-600", success: "bg-emerald-100 text-emerald-600", danger: "bg-red-100 text-red-600", warning: "bg-orange-100 text-orange-600", info: "bg-blue-100 text-blue-600", secondary: "bg-slate-100 text-slate-500", purple: "bg-purple-100 text-purple-600", dark: "bg-slate-800 text-slate-300" }; const sizes = { sm: "w-8 h-8 rounded-lg", md: "w-10 h-10 rounded-xl", lg: "w-12 h-12 rounded-2xl", xl: "w-14 h-14 rounded-2xl" }; const iconSizes = { sm: 14, md: 18, lg: 24, xl: 28 }; return (
{Icon && }
); }; window.Toggle = ({ checked, onChange, variant = 'success', disabled = false }) => { const variants = { success: 'bg-emerald-500', info: 'bg-blue-500', warning: 'bg-orange-500', danger: 'bg-red-500', purple: 'bg-purple-500' }; const colorClass = variants[variant] || variants.success; return (
{ if(onChange && !disabled) { e.stopPropagation(); onChange(!checked); } }} >
); }; window.EmptyState = ({ icon: Icon, text, subtext, className = "" }) => (
{Icon && }

{text}

{subtext &&

{subtext}

}
); window.AlertBox = ({ type = 'info', icon: Icon, title, children, className = "" }) => { const styles = { info: 'bg-blue-50 text-blue-800 border-blue-200', warning: 'bg-orange-50 text-orange-800 border-orange-200', error: 'bg-red-50 text-red-800 border-red-200', success: 'bg-emerald-50 text-emerald-800 border-emerald-200' }; const iconColors = { info: 'text-blue-500', warning: 'text-orange-500', error: 'text-red-500', success: 'text-emerald-500' }; return (
{Icon && }
{title &&

{title}

} {children}
); }; window.StatCard = ({ title, value, icon, variant = 'info', onClick }) => { const variants = { success: { bg: 'bg-emerald-100', text: 'text-emerald-600' }, info: { bg: 'bg-blue-100', text: 'text-blue-600' }, warning: { bg: 'bg-amber-100', text: 'text-amber-600' }, danger: { bg: 'bg-red-100', text: 'text-red-600' }, secondary: { bg: 'bg-slate-200', text: 'text-slate-600' }, purple: { bg: 'bg-purple-100', text: 'text-purple-600' }, indigo: { bg: 'bg-indigo-100', text: 'text-indigo-600' } }; const v = variants[variant] || variants.info; return (
{icon}

{title}

{value}

); }; window.PriceInput = ({ label, value, onChange, ...props }) => (
onChange(parseInt(e.target.value) || 0)} className="w-full border-2 border-slate-200 rounded-xl p-2.5 pr-8 text-sm focus:border-emerald-500 outline-none transition font-bold text-slate-800" {...props} />
); window.StatusBadge = ({ status, variant, className = '' }) => { let colorClass = 'bg-slate-100 text-slate-600 border-slate-200'; if (variant) { const variants = { success: 'bg-emerald-100 text-emerald-700 border-emerald-200', danger: 'bg-red-100 text-red-700 border-red-200', warning: 'bg-amber-100 text-amber-700 border-amber-200', info: 'bg-blue-100 text-blue-700 border-blue-200', secondary: 'bg-slate-100 text-slate-600 border-slate-200' }; colorClass = variants[variant] || colorClass; } else { const s = (status || '').toLowerCase(); if (s.includes('actif') || s.includes('livré') || s.includes('activé') || s.includes('accept')) { colorClass = 'bg-emerald-100 text-emerald-700 border-emerald-200'; } else if (s.includes('suspendu') || s.includes('erreur') || s.includes('hors ligne') || s.includes('refus') || s.includes('désactivé')) { colorClass = 'bg-red-100 text-red-700 border-red-200'; } else if (s.includes('brouillon') || s.includes('attente') || s.includes('validation') || s.includes('programmé')) { colorClass = 'bg-amber-100 text-amber-700 border-amber-200'; } else if (s.includes('expédié')) { colorClass = 'bg-blue-100 text-blue-700 border-blue-200'; } } return ( {status} ); }; window.FormInput = ({ label, value, onChange, type = 'text', required = false, disabled = false, placeholder = '', className = '', hint = '', error = false, errorText = '', ...props }) => (
{hint && !errorText &&

{hint}

} {errorText &&

{errorText}

}
); window.FormTextarea = ({ label, value, onChange, rows = 3, required = false, disabled = false, placeholder = '', className = '', hint = '', error = false, errorText = '', ...props }) => (