// ============================================================================ // ADVERTISINGS VIEW - VERSION AVEC CONFIGURATIONS // ============================================================================ const AdvertisingsView = () => { const { customer } = useAuth(); const toast = useToast(); const [configurations, setConfigurations] = useState([]); const [selectedConfig, setSelectedConfig] = useState(null); const [advertisings, setAdvertisings] = useState([]); const [loading, setLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); const [editingAd, setEditingAd] = useState(null); const [uploading, setUploading] = useState(false); // Form state const [formTitle, setFormTitle] = useState(''); const [formImageUrl, setFormImageUrl] = useState(''); const [formDuration, setFormDuration] = useState(10000); const [formActive, setFormActive] = useState(true); const [preselectedScreenId, setPreselectedScreenId] = useState(null); const [formIsUnlimited, setFormIsUnlimited] = useState(true); const [formStartDate, setFormStartDate] = useState(''); const [formEndDate, setFormEndDate] = useState(''); useEffect(() => { loadConfigurations(); // Vérifier si on doit ouvrir la modal d'ajout automatiquement const shouldOpenModal = localStorage.getItem('open_add_modal'); const preselectedScreenId = localStorage.getItem('preselected_screen_id'); if (shouldOpenModal === 'advertisings' && preselectedScreenId) { // Nettoyer le localStorage localStorage.removeItem('open_add_modal'); localStorage.removeItem('preselected_screen_id'); // Ouvrir la modal après un court délai setTimeout(() => { setPreselectedScreenId(parseInt(preselectedScreenId)); openModal(null, parseInt(preselectedScreenId)); }, 500); } }, []); useEffect(() => { if (selectedConfig) { loadAdvertisings(); } }, [selectedConfig]); const loadConfigurations = async () => { try { const result = await api.getConfigurations(customer.id); if (result.configurations && result.configurations.length > 0) { setConfigurations(result.configurations); setSelectedConfig(result.configurations[0].id); } } catch (error) { toast.error('Erreur lors du chargement'); } setLoading(false); }; const loadAdvertisings = async () => { try { // Charger les publicités de la configuration const result = await api.getAdvertisingsByConfig(selectedConfig); if (result.advertisings) { setAdvertisings(result.advertisings); } } catch (error) { toast.error('Erreur lors du chargement des publicités'); } }; const handleFileUpload = async (e) => { const file = e.target.files[0]; if (!file) return; if (!file.type.startsWith('image/')) { toast.error('Seules les images sont acceptées'); return; } setUploading(true); try { const result = await api.uploadFile(file); if (result.url) { setFormImageUrl(result.url); toast.success('Image uploadée avec succès'); } } catch (error) { toast.error('Erreur lors de l\'upload'); } setUploading(false); }; const openModal = (ad = null, screenId = null) => { if (ad) { setEditingAd(ad); setFormTitle(ad.title || ''); setFormImageUrl(ad.image_url); setFormDuration(ad.display_duration); setFormActive(ad.is_active == 1); // Gérer les dates const hasNoDates = !ad.start_date && !ad.end_date; setFormIsUnlimited(hasNoDates); setFormStartDate(ad.start_date || ''); setFormEndDate(ad.end_date || ''); } else { setEditingAd(null); setFormTitle(''); setFormImageUrl(''); setFormDuration(10000); setFormActive(true); setFormIsUnlimited(true); setFormStartDate(''); setFormEndDate(''); } if (screenId) { setPreselectedScreenId(screenId); } setIsModalOpen(true); }; const handleSubmit = async (e) => { e.preventDefault(); // Validation côté client if (!formImageUrl || formImageUrl.trim() === '') { toast.error('Veuillez uploader une image avant de créer la publicité'); return; } const data = { customer_id: customer.id, title: formTitle, image_url: formImageUrl, display_duration: formDuration, is_active: formActive ? 1 : 0, start_date: formIsUnlimited ? null : formStartDate, end_date: formIsUnlimited ? null : formEndDate }; // Utiliser screen_id OU configuration_id selon le cas if (preselectedScreenId) { data.screen_id = preselectedScreenId; } else { data.configuration_id = selectedConfig; } console.log('📤 Envoi des données:', data); try { if (editingAd) { data.id = editingAd.id; const result = await api.updateAdvertising(data); if (result.success) { toast.success('Publicité modifiée'); loadAdvertisings(); setIsModalOpen(false); } else { toast.error(result.error || 'Erreur lors de la modification'); } } else { const result = await api.createAdvertising(data); if (result.success) { toast.success('Publicité créée'); loadAdvertisings(); setIsModalOpen(false); } else { toast.error(result.error || 'Erreur lors de la création'); } } } catch (error) { console.error('❌ Erreur:', error); const errorMessage = error.message || error.error || 'Erreur lors de l\'enregistrement'; toast.error(errorMessage); } }; const handleDelete = async (id) => { if (!confirm('Supprimer cette publicité ?')) return; try { const result = await api.deleteAdvertising(id); if (result.success) { toast.success('Publicité supprimée'); loadAdvertisings(); } } catch (error) { toast.error('Erreur lors de la suppression'); } }; if (loading) return ; if (configurations.length === 0) { return ( window.location.reload()} icon="fa-cog"> Aller aux Configurations } /> ); } const currentConfig = configurations.find(c => c.id === selectedConfig); return (

Publicités

Gérez les publicités de vos configurations

{/* Sélecteur de configuration */}
{currentConfig && (
{currentConfig.screens_count} écran(s) utilisent cette configuration
)}
{/* Liste des publicités */} {advertisings.length === 0 ? ( openModal()} icon="fa-plus"> Ajouter une publicité } /> ) : (
{/* Header */}
Image
Titre
Durée
Période
Statut
Actions
{/* Lignes */} {advertisings.map(ad => (
{/* Image */}
{ad.title
{/* Titre */}
{ad.title || Sans titre}
{/* Durée */}
{ad.display_duration / 1000}s
{/* Période */}
{ad.start_date && ad.end_date ? (
{new Date(ad.start_date).toLocaleDateString('fr-FR')}
{new Date(ad.end_date).toLocaleDateString('fr-FR')}
) : (
Permanent
)}
{/* Statut */}
{ad.is_active == 1 ? 'Active' : 'Inactive'}
{/* Actions */}
))}
)} {/* Modal Créer/Modifier */} setIsModalOpen(false)} title={editingAd ? 'Modifier la publicité' : 'Nouvelle publicité'} >
{/* Upload zone */}
document.getElementById('sm-ad-file-input').click()} > {formImageUrl ? (
Preview

Image uploadée

) : (

Cliquez pour uploader une image

JPG, PNG (max 5MB)

)} {uploading && (

Upload en cours...

)}
setFormDuration(parseInt(val))} placeholder="10000" required icon="fa-clock" /> {/* Période d'affichage */}
); }; // ============================================================================ // NEWS VIEW - VERSION AVEC CONFIGURATIONS // ============================================================================ const NewsView = () => { const { customer } = useAuth(); const toast = useToast(); const [configurations, setConfigurations] = useState([]); const [selectedConfig, setSelectedConfig] = useState(null); const [news, setNews] = useState([]); const [loading, setLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); const [editingNews, setEditingNews] = useState(null); // Form state const [formTitle, setFormTitle] = useState(''); const [formSubtitle, setFormSubtitle] = useState(''); const [formTime, setFormTime] = useState(''); const [formTags, setFormTags] = useState(''); const [formColor, setFormColor] = useState('red'); const [formPriority, setFormPriority] = useState('medium'); const [formActive, setFormActive] = useState(true); const colorSchemes = [ { value: 'red', label: 'Rouge', from: '#f43f5e', to: '#dc2626' }, { value: 'purple', label: 'Violet', from: '#a855f7', to: '#7c3aed' }, { value: 'blue', label: 'Bleu', from: '#3b82f6', to: '#1d4ed8' }, { value: 'green', label: 'Vert', from: '#10b981', to: '#059669' }, { value: 'orange', label: 'Orange', from: '#f97316', to: '#ea580c' }, { value: 'yellow', label: 'Jaune', from: '#eab308', to: '#ca8a04' }, { value: 'pink-pastel', label: 'Rose pastel', from: '#fbcfe8', to: '#f9a8d4' }, { value: 'lavender-pastel', label: 'Lavande pastel', from: '#e9d5ff', to: '#d8b4fe' }, { value: 'sky-pastel', label: 'Ciel pastel', from: '#bae6fd', to: '#7dd3fc' }, { value: 'mint-pastel', label: 'Menthe pastel', from: '#a7f3d0', to: '#6ee7b7' }, { value: 'peach-pastel', label: 'Pêche pastel', from: '#fed7aa', to: '#fdba74' }, { value: 'lemon-pastel', label: 'Citron pastel', from: '#fef08a', to: '#fde047' } ]; useEffect(() => { loadConfigurations(); // Vérifier si on doit ouvrir la modal d'ajout automatiquement const shouldOpenModal = localStorage.getItem('open_add_modal'); const preselectedScreenId = localStorage.getItem('preselected_screen_id'); if (shouldOpenModal === 'news' && preselectedScreenId) { // Nettoyer le localStorage localStorage.removeItem('open_add_modal'); localStorage.removeItem('preselected_screen_id'); // Ouvrir la modal après un court délai setTimeout(() => { openModal(null, parseInt(preselectedScreenId)); }, 500); } }, []); useEffect(() => { if (selectedConfig) { loadNews(); } }, [selectedConfig]); const loadConfigurations = async () => { try { const result = await api.getConfigurations(customer.id); if (result.configurations && result.configurations.length > 0) { setConfigurations(result.configurations); setSelectedConfig(result.configurations[0].id); } } catch (error) { toast.error('Erreur lors du chargement'); } setLoading(false); }; const loadNews = async () => { try { const result = await api.getNewsByConfig(selectedConfig); if (result.news) { setNews(result.news); } } catch (error) { toast.error('Erreur lors du chargement des alertes'); } }; const openModal = (newsItem = null) => { if (newsItem) { setEditingNews(newsItem); setFormTitle(newsItem.title); setFormSubtitle(newsItem.subtitle || ''); setFormTime(newsItem.time_info || ''); setFormTags(newsItem.tags ? newsItem.tags.join(', ') : ''); setFormColor(newsItem.color_scheme); setFormPriority(newsItem.priority); setFormActive(newsItem.is_active == 1); } else { setEditingNews(null); setFormTitle(''); setFormSubtitle(''); setFormTime(''); setFormTags(''); setFormColor('red'); setFormPriority('medium'); setFormActive(true); } setIsModalOpen(true); }; const handleSubmit = async (e) => { e.preventDefault(); const tags = formTags.split(',').map(t => t.trim()).filter(t => t); const data = { configuration_id: selectedConfig, customer_id: customer.id, title: formTitle, subtitle: formSubtitle, time_info: formTime, tags: tags, color_scheme: formColor, priority: formPriority, is_active: formActive ? 1 : 0 }; try { if (editingNews) { data.id = editingNews.id; const result = await api.updateNews(data); if (result.success) { toast.success('Alerte modifiée'); loadNews(); setIsModalOpen(false); } } else { const result = await api.createNews(data); if (result.success) { toast.success('Alerte créée'); loadNews(); setIsModalOpen(false); } } } catch (error) { toast.error('Erreur lors de l\'enregistrement'); } }; const handleDelete = async (id) => { if (!confirm('Supprimer cette alerte ?')) return; try { const result = await api.deleteNews(id); if (result.success) { toast.success('Alerte supprimée'); loadNews(); } } catch (error) { toast.error('Erreur lors de la suppression'); } }; if (loading) return ; if (configurations.length === 0) { return ( ); } const currentConfig = configurations.find(c => c.id === selectedConfig); return (

Alertes & News

Gérez les alertes importantes de vos configurations

{/* Sélecteur de configuration */}
{currentConfig && (
{currentConfig.screens_count} écran(s) utilisent cette configuration
)}
{/* Liste des alertes */} {news.length === 0 ? ( openModal()} icon="fa-plus"> Ajouter une alerte } /> ) : (
{news.map(item => { const colorScheme = colorSchemes.find(c => c.value === item.color_scheme) || colorSchemes[0]; return (

{item.title}

{item.subtitle &&

{item.subtitle}

} {item.time_info &&

{item.time_info}

} {item.tags && item.tags.length > 0 && (
{item.tags.map((tag, i) => ( {tag} ))}
)}
{item.is_active == 1 ? 'Active' : 'Inactive'} Priorité: {item.priority}
); })}
)} {/* Modal Créer/Modifier */} setIsModalOpen(false)} title={editingNews ? 'Modifier l\'alerte' : 'Nouvelle alerte'} size="lg" >
{/* Aperçu de la couleur */}
c.value === formColor)?.from}, ${colorSchemes.find(c => c.value === formColor)?.to})` }} title="Aperçu de la couleur" >
); }; // ============================================================================ // SLIDERS VIEW - VERSION AVEC CONFIGURATIONS // ============================================================================ const SlidersView = () => { const { customer } = useAuth(); const toast = useToast(); const [configurations, setConfigurations] = useState([]); const [selectedConfig, setSelectedConfig] = useState(null); const [sliders, setSliders] = useState([]); const [loading, setLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); const [editingSlider, setEditingSlider] = useState(null); // Form state const [formMessage, setFormMessage] = useState(''); const [formIcon, setFormIcon] = useState(''); const [formDuration, setFormDuration] = useState(10000); const [formActive, setFormActive] = useState(true); useEffect(() => { loadConfigurations(); // Vérifier si on doit ouvrir la modal d'ajout automatiquement const shouldOpenModal = localStorage.getItem('open_add_modal'); const preselectedScreenId = localStorage.getItem('preselected_screen_id'); if (shouldOpenModal === 'sliders' && preselectedScreenId) { // Nettoyer le localStorage localStorage.removeItem('open_add_modal'); localStorage.removeItem('preselected_screen_id'); // Ouvrir la modal après un court délai setTimeout(() => { openModal(null, parseInt(preselectedScreenId)); }, 500); } }, []); useEffect(() => { if (selectedConfig) { loadSliders(); } }, [selectedConfig]); const loadConfigurations = async () => { try { const result = await api.getConfigurations(customer.id); if (result.configurations && result.configurations.length > 0) { setConfigurations(result.configurations); setSelectedConfig(result.configurations[0].id); } } catch (error) { toast.error('Erreur lors du chargement'); } setLoading(false); }; const loadSliders = async () => { try { const result = await api.getSlidersByConfig(selectedConfig); if (result.sliders) { setSliders(result.sliders); } } catch (error) { toast.error('Erreur lors du chargement des messages'); } }; const openModal = (slider = null) => { if (slider) { setEditingSlider(slider); setFormMessage(slider.message); setFormIcon(slider.icon || ''); setFormDuration(slider.display_duration); setFormActive(slider.is_active == 1); } else { setEditingSlider(null); setFormMessage(''); setFormIcon(''); setFormDuration(10000); setFormActive(true); } setIsModalOpen(true); }; const handleSubmit = async (e) => { e.preventDefault(); const data = { configuration_id: selectedConfig, customer_id: customer.id, message: formMessage, icon: formIcon, display_duration: formDuration, is_active: formActive ? 1 : 0 }; try { if (editingSlider) { data.id = editingSlider.id; const result = await api.updateSlider(data); if (result.success) { toast.success('Message modifié'); loadSliders(); setIsModalOpen(false); } } else { const result = await api.createSlider(data); if (result.success) { toast.success('Message créé'); loadSliders(); setIsModalOpen(false); } } } catch (error) { toast.error('Erreur lors de l\'enregistrement'); } }; const handleDelete = async (id) => { if (!confirm('Supprimer ce message ?')) return; try { const result = await api.deleteSlider(id); if (result.success) { toast.success('Message supprimé'); loadSliders(); } } catch (error) { toast.error('Erreur lors de la suppression'); } }; if (loading) return ; if (configurations.length === 0) { return ( ); } const currentConfig = configurations.find(c => c.id === selectedConfig); return (

Messages défilants

Gérez les messages du bandeau défilant

{/* Sélecteur de configuration */}
{currentConfig && (
{currentConfig.screens_count} écran(s) utilisent cette configuration
)}
{/* Liste des sliders */} {sliders.length === 0 ? ( openModal()} icon="fa-plus"> Ajouter un message } /> ) : (
{sliders.map(slider => (
{slider.icon && (
{slider.icon}
)}

{slider.message}

{slider.display_duration / 1000}s {slider.is_active == 1 ? 'Actif' : 'Inactif'}
))}
)} {/* Modal Créer/Modifier */} setIsModalOpen(false)} title={editingSlider ? 'Modifier le message' : 'Nouveau message'} >
setFormDuration(parseInt(val))} required icon="fa-clock" />
); }; // ============================================================================ // NUMBERS VIEW - VERSION AVEC CONFIGURATIONS // ============================================================================ const NumbersView = () => { const { customer } = useAuth(); const toast = useToast(); const [configurations, setConfigurations] = useState([]); const [selectedConfig, setSelectedConfig] = useState(null); const [numbers, setNumbers] = useState([]); const [loading, setLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); const [editingNumber, setEditingNumber] = useState(null); // Form state const [formLabel, setFormLabel] = useState(''); const [formNumber, setFormNumber] = useState(''); const [formSubtitle, setFormSubtitle] = useState(''); const [formCategory, setFormCategory] = useState('custom'); const [formIcon, setFormIcon] = useState(''); const [formActive, setFormActive] = useState(true); useEffect(() => { loadConfigurations(); // Vérifier si on doit ouvrir la modal d'ajout automatiquement const shouldOpenModal = localStorage.getItem('open_add_modal'); const preselectedScreenId = localStorage.getItem('preselected_screen_id'); if (shouldOpenModal === 'numbers' && preselectedScreenId) { // Nettoyer le localStorage localStorage.removeItem('open_add_modal'); localStorage.removeItem('preselected_screen_id'); // Ouvrir la modal après un court délai setTimeout(() => { openModal(null, parseInt(preselectedScreenId)); }, 500); } }, []); useEffect(() => { if (selectedConfig) { loadNumbers(); } }, [selectedConfig]); const loadConfigurations = async () => { try { const result = await api.getConfigurations(customer.id); if (result.configurations && result.configurations.length > 0) { setConfigurations(result.configurations); setSelectedConfig(result.configurations[0].id); } } catch (error) { toast.error('Erreur lors du chargement'); } setLoading(false); }; const loadNumbers = async () => { try { const result = await api.getNumbersByConfig(selectedConfig); if (result.numbers) { setNumbers(result.numbers); } } catch (error) { toast.error('Erreur lors du chargement des contacts'); } }; const openModal = (number = null) => { if (number) { setEditingNumber(number); setFormLabel(number.label); setFormNumber(number.number); setFormSubtitle(number.subtitle || ''); setFormCategory(number.category); setFormIcon(number.icon || ''); setFormActive(number.is_active == 1); } else { setEditingNumber(null); setFormLabel(''); setFormNumber(''); setFormSubtitle(''); setFormCategory('custom'); setFormIcon(''); setFormActive(true); } setIsModalOpen(true); }; const handleSubmit = async (e) => { e.preventDefault(); const data = { configuration_id: selectedConfig, customer_id: customer.id, label: formLabel, number: formNumber, subtitle: formSubtitle, category: formCategory, icon: formIcon, is_active: formActive ? 1 : 0 }; try { if (editingNumber) { data.id = editingNumber.id; const result = await api.updateNumber(data); if (result.success) { toast.success('Contact modifié'); loadNumbers(); setIsModalOpen(false); } } else { const result = await api.createNumber(data); if (result.success) { toast.success('Contact créé'); loadNumbers(); setIsModalOpen(false); } } } catch (error) { toast.error('Erreur lors de l\'enregistrement'); } }; const handleDelete = async (id) => { if (!confirm('Supprimer ce contact ?')) return; try { const result = await api.deleteNumber(id); if (result.success) { toast.success('Contact supprimé'); loadNumbers(); } } catch (error) { toast.error('Erreur lors de la suppression'); } }; if (loading) return ; if (configurations.length === 0) { return ( ); } const currentConfig = configurations.find(c => c.id === selectedConfig); const categories = { emergency: 'Urgence', concierge: 'Conciergerie', service: 'Services', custom: 'Autres' }; return (

Contacts rapides

Gérez les numéros de téléphone importants

{/* Sélecteur de configuration */}
{currentConfig && (
{currentConfig.screens_count} écran(s) utilisent cette configuration
)}
{/* Liste des contacts */} {numbers.length === 0 ? ( openModal()} icon="fa-plus"> Ajouter un contact } /> ) : (
{numbers.map(num => (
{num.icon &&
{num.icon}
}

{num.label}

{categories[num.category]}

{num.number}

{num.subtitle && (

{num.subtitle}

)}
{num.is_active == 1 ? 'Actif' : 'Inactif'}
))}
)} {/* Modal Créer/Modifier */} setIsModalOpen(false)} title={editingNumber ? 'Modifier le contact' : 'Nouveau contact'} >
); };