// ============================================================================
// 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 */}
{/* 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é'}
>
);
};
// ============================================================================
// 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"
>
);
};
// ============================================================================
// 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'}
>
);
};
// ============================================================================
// 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'}
>
);
};