import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { BarChart, PieChart, MapPin, Calendar, Home, Settings, Filter, Download, ChevronDown, Info, ArrowUpRight, ArrowDownRight, Clock, X, Check, ThumbsUp, ThumbsDown, RefreshCw, AlertTriangle, MessageSquare, Lightbulb, Zap, BarChart2, TrendingUp as TrendingUpIcon, Search, ArrowUp, ArrowDown, ChevronLeft, ChevronRight, Maximize2, Minimize2, XCircle, FileText, BookOpen } from 'lucide-react'; // Mock data for demonstration const mockData = { totalSites: 1248, approvalRate: 68, pendingRate: 22, unfavorableRate: 10, regions: [ { id: 1, name: 'North', sites: 423, favorable: 302, unfavorable: 42, pending: 79 }, { id: 2, name: 'South', sites: 289, favorable: 186, unfavorable: 31, pending: 72 }, { id: 3, name: 'East', sites: 356, favorable: 249, unfavorable: 35, pending: 72 }, { id: 4, name: 'West', sites: 180, favorable: 112, unfavorable: 17, pending: 51 } ], technologies: [ { name: '4G', count: 876 }, { name: '5G', count: 372 } ], monthlyTrends: [ { month: 'Jan', approved: 42, rejected: 12, pending: 18 }, { month: 'Feb', approved: 48, rejected: 10, pending: 22 }, { month: 'Mar', approved: 53, rejected: 8, pending: 25 }, { month: 'Apr', approved: 61, rejected: 11, pending: 19 }, { month: 'May', approved: 58, rejected: 9, pending: 23 }, { month: 'Jun', approved: 65, rejected: 7, pending: 28 } ], recentSites: [ { id: 'ANF-2024-0123', location: 'Algiers', technology: '5G', status: 'Favorable', date: '2024-06-15' }, { id: 'ANF-2024-0124', location: 'Oran', technology: '4G', status: 'Pending', date: '2024-06-12' }, { id: 'ANF-2024-0125', location: 'Constantine', technology: '5G', status: 'Unfavorable', date: '2024-06-10' }, { id: 'ANF-2024-0126', location: 'Annaba', technology: '4G', status: 'Favorable', date: '2024-06-08' }, { id: 'ANF-2024-0127', location: 'Batna', technology: '4G', status: 'Favorable', date: '2024-06-05' } ], // Detailed data for each chart detailedData: { regions: { North: [ { id: 'ANF-2024-0101', location: 'Algiers', technology: '5G', status: 'Favorable', date: '2024-06-02', population: 3_500_000, density: 'High' }, { id: 'ANF-2024-0102', location: 'Blida', technology: '4G', status: 'Favorable', date: '2024-06-03', population: 1_002_000, density: 'Medium' }, { id: 'ANF-2024-0103', location: 'Tizi Ouzou', technology: '4G', status: 'Pending', date: '2024-06-05', population: 1_127_000, density: 'Medium' }, { id: 'ANF-2024-0104', location: 'Boumerdès', technology: '5G', status: 'Favorable', date: '2024-06-07', population: 802_000, density: 'Medium' }, { id: 'ANF-2024-0105', location: 'Tipaza', technology: '4G', status: 'Unfavorable', date: '2024-06-08', population: 591_000, density: 'Low' } ], South: [ { id: 'ANF-2024-0201', location: 'Adrar', technology: '4G', status: 'Favorable', date: '2024-06-01', population: 455_000, density: 'Very Low' }, { id: 'ANF-2024-0202', location: 'Tamanrasset', technology: '4G', status: 'Pending', date: '2024-06-04', population: 176_000, density: 'Very Low' }, { id: 'ANF-2024-0203', location: 'Illizi', technology: '4G', status: 'Pending', date: '2024-06-06', population: 52_000, density: 'Very Low' }, { id: 'ANF-2024-0204', location: 'Tindouf', technology: '5G', status: 'Unfavorable', date: '2024-06-09', population: 58_000, density: 'Very Low' }, { id: 'ANF-2024-0205', location: 'Béchar', technology: '4G', status: 'Favorable', date: '2024-06-10', population: 270_000, density: 'Low' } ], East: [ { id: 'ANF-2024-0301', location: 'Constantine', technology: '5G', status: 'Favorable', date: '2024-06-02', population: 938_000, density: 'High' }, { id: 'ANF-2024-0302', location: 'Annaba', technology: '5G', status: 'Favorable', date: '2024-06-05', population: 640_000, density: 'Medium' }, { id: 'ANF-2024-0303', location: 'Sétif', technology: '4G', status: 'Pending', date: '2024-06-07', population: 1_496_000, density: 'Medium' }, { id: 'ANF-2024-0304', location: 'Batna', technology: '4G', status: 'Unfavorable', date: '2024-06-09', population: 1_120_000, density: 'Medium' }, { id: 'ANF-2024-0305', location: 'Guelma', technology: '4G', status: 'Favorable', date: '2024-06-11', population: 482_000, density: 'Low' } ], West: [ { id: 'ANF-2024-0401', location: 'Oran', technology: '5G', status: 'Favorable', date: '2024-06-01', population: 1_584_000, density: 'High' }, { id: 'ANF-2024-0402', location: 'Tlemcen', technology: '4G', status: 'Pending', date: '2024-06-03', population: 949_000, density: 'Medium' }, { id: 'ANF-2024-0403', location: 'Sidi Bel Abbès', technology: '4G', status: 'Favorable', date: '2024-06-06', population: 604_000, density: 'Medium' }, { id: 'ANF-2024-0404', location: 'Mostaganem', technology: '5G', status: 'Unfavorable', date: '2024-06-08', population: 746_000, density: 'Medium' }, { id: 'ANF-2024-0405', location: 'Mascara', technology: '4G', status: 'Pending', date: '2024-06-10', population: 784_000, density: 'Medium' } ] }, approvalStatus: { Favorable: [ { id: 'ANF-2024-0501', location: 'Algiers', technology: '5G', region: 'North', date: '2024-06-01', approvalDate: '2024-06-10', processingTime: 9 }, { id: 'ANF-2024-0502', location: 'Oran', technology: '5G', region: 'West', date: '2024-06-02', approvalDate: '2024-06-09', processingTime: 7 }, { id: 'ANF-2024-0503', location: 'Constantine', technology: '4G', region: 'East', date: '2024-06-03', approvalDate: '2024-06-15', processingTime: 12 }, { id: 'ANF-2024-0504', location: 'Annaba', technology: '4G', region: 'East', date: '2024-06-04', approvalDate: '2024-06-18', processingTime: 14 }, { id: 'ANF-2024-0505', location: 'Blida', technology: '5G', region: 'North', date: '2024-06-05', approvalDate: '2024-06-12', processingTime: 7 } ], Unfavorable: [ { id: 'ANF-2024-0601', location: 'Batna', technology: '4G', region: 'East', date: '2024-06-01', rejectionDate: '2024-06-15', processingTime: 14, reason: 'Environmental concerns' }, { id: 'ANF-2024-0602', location: 'Tindouf', technology: '5G', region: 'South', date: '2024-06-03', rejectionDate: '2024-06-18', processingTime: 15, reason: 'Incomplete documentation' }, { id: 'ANF-2024-0603', location: 'Mostaganem', technology: '4G', region: 'West', date: '2024-06-05', rejectionDate: '2024-06-20', processingTime: 15, reason: 'Technical incompatibility' }, { id: 'ANF-2024-0604', location: 'Tipaza', technology: '5G', region: 'North', date: '2024-06-07', rejectionDate: '2024-06-21', processingTime: 14, reason: 'Zoning restrictions' }, { id: 'ANF-2024-0605', location: 'Béjaïa', technology: '4G', region: 'East', date: '2024-06-09', rejectionDate: '2024-06-25', processingTime: 16, reason: 'Proximity to sensitive area' } ], Pending: [ { id: 'ANF-2024-0701', location: 'Sétif', technology: '5G', region: 'East', date: '2024-06-10', currentStage: 'Technical Review', daysInProcess: 20 }, { id: 'ANF-2024-0702', location: 'Tlemcen', technology: '4G', region: 'West', date: '2024-06-11', currentStage: 'Environmental Assessment', daysInProcess: 19 }, { id: 'ANF-2024-0703', location: 'Tamanrasset', technology: '4G', region: 'South', date: '2024-06-12', currentStage: 'Initial Screening', daysInProcess: 18 }, { id: 'ANF-2024-0704', location: 'Tizi Ouzou', technology: '5G', region: 'North', date: '2024-06-13', currentStage: 'Public Consultation', daysInProcess: 17 }, { id: 'ANF-2024-0705', location: 'Mascara', technology: '4G', region: 'West', date: '2024-06-14', currentStage: 'Final Approval', daysInProcess: 16 } ] }, technologies: { '4G': [ { id: 'ANF-2024-0801', location: 'Algiers', region: 'North', status: 'Favorable', date: '2024-06-01', bandwidth: '20 MHz', coverage: '15 km' }, { id: 'ANF-2024-0802', location: 'Oran', region: 'West', status: 'Favorable', date: '2024-06-03', bandwidth: '15 MHz', coverage: '12 km' }, { id: 'ANF-2024-0803', location: 'Constantine', region: 'East', status: 'Pending', date: '2024-06-05', bandwidth: '10 MHz', coverage: '10 km' }, { id: 'ANF-2024-0804', location: 'Adrar', region: 'South', status: 'Unfavorable', date: '2024-06-07', bandwidth: '15 MHz', coverage: '20 km' }, { id: 'ANF-2024-0805', location: 'Annaba', region: 'East', status: 'Favorable', date: '2024-06-09', bandwidth: '20 MHz', coverage: '15 km' } ], '5G': [ { id: 'ANF-2024-0901', location: 'Algiers', region: 'North', status: 'Favorable', date: '2024-06-02', bandwidth: '100 MHz', coverage: '2 km' }, { id: 'ANF-2024-0902', location: 'Oran', region: 'West', status: 'Pending', date: '2024-06-04', bandwidth: '80 MHz', coverage: '1.5 km' }, { id: 'ANF-2024-0903', location: 'Constantine', region: 'East', status: 'Favorable', date: '2024-06-06', bandwidth: '100 MHz', coverage: '2 km' }, { id: 'ANF-2024-0904', location: 'Blida', region: 'North', status: 'Unfavorable', date: '2024-06-08', bandwidth: '60 MHz', coverage: '1 km' }, { id: 'ANF-2024-0905', location: 'Annaba', region: 'East', status: 'Favorable', date: '2024-06-10', bandwidth: '120 MHz', coverage: '2.5 km' } ] }, monthlyData: { 'Jan': [ { id: 'ANF-2024-0001', location: 'Algiers', technology: '4G', status: 'Favorable', region: 'North', date: '2024-01-05' }, { id: 'ANF-2024-0002', location: 'Oran', technology: '5G', status: 'Favorable', region: 'West', date: '2024-01-08' }, { id: 'ANF-2024-0003', location: 'Constantine', technology: '4G', status: 'Unfavorable', region: 'East', date: '2024-01-12' }, { id: 'ANF-2024-0004', location: 'Annaba', technology: '5G', status: 'Pending', region: 'East', date: '2024-01-15' }, { id: 'ANF-2024-0005', location: 'Adrar', technology: '4G', status: 'Favorable', region: 'South', date: '2024-01-20' } ], 'Feb': [ { id: 'ANF-2024-0006', location: 'Blida', technology: '4G', status: 'Favorable', region: 'North', date: '2024-02-03' }, { id: 'ANF-2024-0007', location: 'Tlemcen', technology: '5G', status: 'Pending', region: 'West', date: '2024-02-07' }, { id: 'ANF-2024-0008', location: 'Sétif', technology: '4G', status: 'Favorable', region: 'East', date: '2024-02-10' }, { id: 'ANF-2024-0009', location: 'Tamanrasset', technology: '4G', status: 'Unfavorable', region: 'South', date: '2024-02-15' }, { id: 'ANF-2024-0010', location: 'Mostaganem', technology: '5G', status: 'Favorable', region: 'West', date: '2024-02-22' } ], 'Mar': [ { id: 'ANF-2024-0011', location: 'Tizi Ouzou', technology: '4G', status: 'Favorable', region: 'North', date: '2024-03-02' }, { id: 'ANF-2024-0012', location: 'Sidi Bel Abbès', technology: '5G', status: 'Favorable', region: 'West', date: '2024-03-08' }, { id: 'ANF-2024-0013', location: 'Batna', technology: '4G', status: 'Pending', region: 'East', date: '2024-03-12' }, { id: 'ANF-2024-0014', location: 'Béchar', technology: '5G', status: 'Unfavorable', region: 'South', date: '2024-03-18' }, { id: 'ANF-2024-0015', location: 'Guelma', technology: '4G', status: 'Favorable', region: 'East', date: '2024-03-25' } ], 'Apr': [ { id: 'ANF-2024-0016', location: 'Boumerdès', technology: '5G', status: 'Favorable', region: 'North', date: '2024-04-05' }, { id: 'ANF-2024-0017', location: 'Mascara', technology: '4G', status: 'Pending', region: 'West', date: '2024-04-10' }, { id: 'ANF-2024-0018', location: 'Béjaïa', technology: '5G', status: 'Favorable', region: 'East', date: '2024-04-15' }, { id: 'ANF-2024-0019', location: 'Illizi', technology: '4G', status: 'Unfavorable', region: 'South', date: '2024-04-20' }, { id: 'ANF-2024-0020', location: 'Oran', technology: '5G', status: 'Favorable', region: 'West', date: '2024-04-25' } ], 'May': [ { id: 'ANF-2024-0021', location: 'Tipaza', technology: '4G', status: 'Favorable', region: 'North', date: '2024-05-03' }, { id: 'ANF-2024-0022', location: 'Tlemcen', technology: '5G', status: 'Favorable', region: 'West', date: '2024-05-08' }, { id: 'ANF-2024-0023', location: 'Constantine', technology: '4G', status: 'Pending', region: 'East', date: '2024-05-13' }, { id: 'ANF-2024-0024', location: 'Tindouf', technology: '5G', status: 'Unfavorable', region: 'South', date: '2024-05-18' }, { id: 'ANF-2024-0025', location: 'Annaba', technology: '4G', status: 'Favorable', region: 'East', date: '2024-05-23' } ], 'Jun': [ { id: 'ANF-2024-0026', location: 'Algiers', technology: '5G', status: 'Favorable', region: 'North', date: '2024-06-02' }, { id: 'ANF-2024-0027', location: 'Oran', technology: '4G', status: 'Pending', region: 'West', date: '2024-06-07' }, { id: 'ANF-2024-0028', location: 'Sétif', technology: '5G', status: 'Favorable', region: 'East', date: '2024-06-12' }, { id: 'ANF-2024-0029', location: 'Adrar', technology: '4G', status: 'Unfavorable', region: 'South', date: '2024-06-17' }, { id: 'ANF-2024-0030', location: 'Blida', technology: '5G', status: 'Favorable', region: 'North', date: '2024-06-22' } ] } } }; // Mock AI insights with confidence levels const mockInsights = [ { id: 1, text: "Approval rates have increased by 5.2% over the last quarter, with the North region showing the highest improvement.", confidence: 0.92, category: "trend", timestamp: new Date().toISOString(), feedbackGiven: false }, { id: 2, text: "The South region has a 25% higher pending rate than other regions, suggesting potential process delays.", confidence: 0.85, category: "bottleneck", timestamp: new Date().toISOString(), feedbackGiven: false }, { id: 3, text: "5G site approvals are processing 15% faster than 4G sites, indicating potential for technology-specific optimization.", confidence: 0.78, category: "opportunity", timestamp: new Date().toISOString(), feedbackGiven: false }, { id: 4, text: "There may be a correlation between site density and approval rates in urban areas, but more data is needed to confirm this pattern.", confidence: 0.62, category: "correlation", timestamp: new Date().toISOString(), feedbackGiven: false } ]; const Dashboard = () => { const [activeSection, setActiveSection] = useState('overview'); const [dateRange, setDateRange] = useState('Jan 2024 - Jun 2024'); const [showFilters, setShowFilters] = useState(false); const [selectedRegion, setSelectedRegion] = useState('All Regions'); const [selectedTechnology, setSelectedTechnology] = useState('All Technologies'); const [showAIAssistant, setShowAIAssistant] = useState(false); const [insights, setInsights] = useState(mockInsights); const [isGeneratingInsight, setIsGeneratingInsight] = useState(false); const [aiMessage, setAiMessage] = useState(''); const [aiConversation, setAiConversation] = useState([ { role: 'assistant', content: 'Bonjour ! Je suis votre assistant d\'analyse de données ANF. Comment puis-je vous aider aujourd\'hui ?' } ]); const [userInput, setUserInput] = useState(''); // New state for dashboard summarization const [dashboardSummary, setDashboardSummary] = useState(''); const [isGeneratingSummary, setIsGeneratingSummary] = useState(false); // New state for detail panel const [showDetailPanel, setShowDetailPanel] = useState(false); const [detailPanelData, setDetailPanelData] = useState([]); const [detailPanelTitle, setDetailPanelTitle] = useState(''); const [detailPanelDescription, setDetailPanelDescription] = useState(''); const [searchQuery, setSearchQuery] = useState(''); const [sortConfig, setSortConfig] = useState({ key: null, direction: 'ascending' }); const [isFullScreen, setIsFullScreen] = useState(false); const [currentPage, setCurrentPage] = useState(1); const [itemsPerPage, setItemsPerPage] = useState(10); // Simulate data loading const [loading, setLoading] = useState(true); useEffect(() => { // Simulate API call setTimeout(() => { setLoading(false); }, 1000); }, []); // Reset pagination when data changes useEffect(() => { setCurrentPage(1); }, [detailPanelData, searchQuery]); // Function to handle chart element clicks const handleChartElementClick = (dataType, dataKey) => { let data = []; let title = ''; let description = ''; // Simulate API call or fetch from mockData switch(dataType) { case 'region': data = mockData.detailedData.regions[dataKey] || []; title = `Région ${dataKey}`; description = `Détails des sites ANF dans la région ${dataKey}`; break; case 'status': data = mockData.detailedData.approvalStatus[dataKey] || []; title = `Statut: ${dataKey}`; description = `Sites ANF avec le statut ${dataKey}`; break; case 'technology': data = mockData.detailedData.technologies[dataKey] || []; title = `Technologie: ${dataKey}`; description = `Sites ANF utilisant la technologie ${dataKey}`; break; case 'month': data = mockData.detailedData.monthlyData[dataKey] || []; title = `Mois: ${dataKey}`; description = `Sites ANF déposés en ${dataKey} 2024`; break; default: data = []; title = 'Détails'; description = 'Informations détaillées'; } setDetailPanelData(data); setDetailPanelTitle(title); setDetailPanelDescription(description); setShowDetailPanel(true); setSearchQuery(''); setSortConfig({ key: null, direction: 'ascending' }); }; // Function to close detail panel const closeDetailPanel = () => { setShowDetailPanel(false); setTimeout(() => { setDetailPanelData([]); setDetailPanelTitle(''); setDetailPanelDescription(''); }, 300); // Wait for animation to complete }; // Function to toggle fullscreen mode for detail panel const toggleFullScreen = () => { setIsFullScreen(!isFullScreen); }; // Function to handle sorting const requestSort = (key) => { let direction = 'ascending'; if (sortConfig.key === key && sortConfig.direction === 'ascending') { direction = 'descending'; } setSortConfig({ key, direction }); }; // Function to generate dashboard summary const generateDashboardSummary = async () => { setIsGeneratingSummary(true); try { // Prepare the dashboard state data to send to the API const dashboardState = { kpis: { totalSites: mockData.totalSites, approvalRate: mockData.approvalRate, pendingRate: mockData.pendingRate, unfavorableRate: mockData.unfavorableRate }, filters: { region: selectedRegion, technology: selectedTechnology, dateRange: dateRange }, insights: insights.map(insight => ({ text: insight.text, confidence: insight.confidence, category: insight.category })), trends: { monthly: mockData.monthlyTrends, regions: mockData.regions.map(region => ({ name: region.name, sites: region.sites, favorable: region.favorable, unfavorable: region.unfavorable, pending: region.pending })), technologies: mockData.technologies } }; // In a real implementation, this would call the summarization API // const response = await fetch('https://www.sitebrew.ai/api/20uZR6/genai', { // method: 'POST', // headers: { 'Content-Type': 'application/json' }, // body: JSON.stringify({ // messages: [ // { // role: 'system', // content: 'You are a data analyst assistant that provides concise, natural language summaries of dashboard data. Summarize the key trends, correlations, and anomalies in 2-3 sentences.' // }, // { // role: 'user', // content: `Summarize this dashboard data: ${JSON.stringify(dashboardState)}` // } // ] // }) // }); // const data = await response.json(); // const summaryText = data.message.content; // Simulate API response await new Promise(resolve => setTimeout(resolve, 2000)); // Generate a summary based on the current dashboard state let summaryText = ''; // Different summaries based on selected filters if (selectedRegion !== 'All Regions' && selectedTechnology !== 'All Technologies') { summaryText = `La région ${selectedRegion} montre un taux d'approbation de ${mockData.approvalRate}% pour les sites ${selectedTechnology}, avec une augmentation de 5,2% par rapport au trimestre précédent. Les délais de traitement sont 15% plus courts que la moyenne nationale, mais 22% des demandes restent en attente, principalement en raison de contraintes environnementales.`; } else if (selectedRegion !== 'All Regions') { summaryText = `La région ${selectedRegion} représente ${mockData.regions.find(r => r.name === selectedRegion)?.sites || '~30%'} sites ANF, avec un taux d'approbation de ${mockData.approvalRate}%. Les déploiements 5G progressent plus rapidement (+18% ce trimestre) que les sites 4G, et les zones urbaines montrent des taux d'approbation significativement plus élevés que les zones rurales.`; } else if (selectedTechnology !== 'All Technologies') { summaryText = `Les sites ${selectedTechnology} représentent ${selectedTechnology === '4G' ? '70,2%' : '29,8%'} du total des déploiements ANF, avec un taux d'approbation de ${mockData.approvalRate}%. La tendance montre une augmentation constante des approbations depuis janvier 2024, mais la région Sud présente un taux d'attente 25% plus élevé que les autres régions.`; } else { summaryText = `Sur 1248 sites ANF, 68% ont reçu un avis favorable, 22% sont en attente et 10% ont été refusés, avec une tendance positive de +5,2% d'approbations ce trimestre. La région Nord montre les meilleurs résultats (71% d'approbation), tandis que le Sud présente un taux d'attente 25% plus élevé que la moyenne. Les sites 5G sont approuvés 15% plus rapidement que les sites 4G.`; } setDashboardSummary(summaryText); } catch (error) { console.error('Error generating summary:', error); setDashboardSummary('Impossible de générer un résumé en ce moment. Veuillez réessayer plus tard.'); } finally { setIsGeneratingSummary(false); } }; // Function to generate new AI insights based on current filters and data const generateNewInsight = useCallback(async () => { setIsGeneratingInsight(true); try { // In a real implementation, this would call the LLM API with current dashboard state // For demo purposes, we'll simulate an API call with a timeout // Prepare the prompt based on current filters and data state const prompt = `Analyze ANF site data with the following parameters: - Region: ${selectedRegion} - Technology: ${selectedTechnology} - Date Range: ${dateRange} - Current approval rate: ${mockData.approvalRate}% - Current pending rate: ${mockData.pendingRate}% - Current unfavorable rate: ${mockData.unfavorableRate}% Generate one actionable insight about telecommunications infrastructure deployment based on this data.`; // This would be a real API call in production // const response = await fetch('https://www.sitebrew.ai/api/20uZR6/genai', { // method: 'POST', // headers: { 'Content-Type': 'application/json' }, // body: JSON.stringify({ // messages: [ // { role: 'system', content: 'You are an analytics assistant that provides concise, data-driven insights about ANF telecommunications site data.' }, // { role: 'user', content: prompt } // ] // }) // }); // const data = await response.json(); // const newInsightText = data.message.content; // Simulate API response await new Promise(resolve => setTimeout(resolve, 1500)); // Generate a random new insight for demonstration const newInsightOptions = [ { text: `Dans la région ${selectedRegion === 'All Regions' ? 'Nord' : selectedRegion}, les sites utilisant la technologie ${selectedTechnology === 'All Technologies' ? '5G' : selectedTechnology} montrent un taux d'approbation 12% plus élevé que la moyenne. Considérez prioriser ces déploiements pour des résultats plus rapides.`, confidence: 0.88, category: "recommendation" }, { text: `Les délais d'approbation ont augmenté de 15% dans les zones rurales par rapport au trimestre précédent. Une révision des processus de validation pourrait être nécessaire pour ces régions.`, confidence: 0.72, category: "alert" }, { text: `Il semble y avoir une corrélation entre la densité de population et les taux d'approbation, mais les données actuelles sont insuffisantes pour établir une causalité définitive.`, confidence: 0.65, category: "correlation" } ]; const randomInsight = newInsightOptions[Math.floor(Math.random() * newInsightOptions.length)]; // Add the new insight to the list const newInsight = { id: insights.length + 1, text: randomInsight.text, confidence: randomInsight.confidence, category: randomInsight.category, timestamp: new Date().toISOString(), feedbackGiven: false }; setInsights(prevInsights => [newInsight, ...prevInsights]); } catch (error) { console.error('Error generating insight:', error); // Handle error appropriately } finally { setIsGeneratingInsight(false); } }, [selectedRegion, selectedTechnology, dateRange, insights]); // Function to provide feedback on an insight const provideInsightFeedback = (insightId, isPositive) => { // In a real implementation, this would send feedback to the backend // to improve future insights setInsights(prevInsights => prevInsights.map(insight => insight.id === insightId ? { ...insight, feedbackGiven: true, positiveRating: isPositive } : insight ) ); // Simulate API call to store feedback console.log(`Feedback for insight ${insightId}: ${isPositive ? 'positive' : 'negative'}`); }; // Function to get confidence level text and color const getConfidenceInfo = (confidenceScore) => { if (confidenceScore >= 0.85) { return { text: "Confiance élevée", color: "text-green-600", icon: }; } else if (confidenceScore >= 0.7) { return { text: "Confiance moyenne", color: "text-amber-600", icon: }; } else { return { text: "Confiance limitée", color: "text-gray-500", icon: }; } }; // Function to get category icon const getCategoryIcon = (category) => { switch(category) { case 'trend': return ; case 'bottleneck': return ; case 'opportunity': return ; case 'correlation': return ; case 'recommendation': return ; case 'alert': return ; default: return ; } }; // Function to handle sending a message to the AI assistant const handleSendMessage = async () => { if (!userInput.trim()) return; const newMessage = { role: 'user', content: userInput }; setAiConversation(prev => [...prev, newMessage]); setUserInput(''); // Simulate "typing" indicator setAiMessage('...'); try { // In a real implementation, this would call the LLM API // const response = await fetch('https://www.sitebrew.ai/api/20uZR6/genai', { // method: 'POST', // headers: { 'Content-Type': 'application/json' }, // body: JSON.stringify({ // messages: [ // { role: 'system', content: 'You are an analytics assistant for ANF telecommunications site data. Provide helpful, concise responses about the data and insights.' }, // ...aiConversation, // newMessage // ] // }) // }); // const data = await response.json(); // const assistantResponse = data.message.content; // Simulate API response await new Promise(resolve => setTimeout(resolve, 1000)); // Generate a response based on the user's input let assistantResponse = ''; const userQuestion = userInput.toLowerCase(); if (userQuestion.includes('région') || userQuestion.includes('region')) { assistantResponse = "D'après les données actuelles, la région Nord présente le plus grand nombre de sites ANF (423), suivie par l'Est (356), le Sud (289) et l'Ouest (180). La région Nord a également le taux d'approbation le plus élevé à 71%."; } else if (userQuestion.includes('technologie') || userQuestion.includes('5g') || userQuestion.includes('4g')) { assistantResponse = "La technologie 4G représente 70,2% des sites ANF (876 sites), tandis que la 5G représente 29,8% (372 sites). Les sites 5G ont un taux d'approbation moyen 8% plus élevé que les sites 4G."; } else if (userQuestion.includes('tendance') || userQuestion.includes('trend') || userQuestion.includes('évolution')) { assistantResponse = "Les approbations de sites ANF montrent une tendance à la hausse, avec une augmentation de 54,8% de janvier à juin 2024. Le taux d'approbation global est passé de 58% en janvier à 68% en juin."; } else if (userQuestion.includes('recommandation') || userQuestion.includes('suggestion')) { assistantResponse = "Basé sur les données actuelles, je recommande de:\n\n1. Accélérer le traitement des demandes en attente dans la région Sud, où le taux d'attente est 25% plus élevé que la moyenne\n\n2. Prioriser les déploiements 5G dans les zones urbaines où ils montrent un taux d'approbation supérieur\n\n3. Mettre en place un suivi spécifique pour les sites en attente depuis plus de 45 jours"; } else { assistantResponse = "Je peux vous aider à analyser les données ANF de plusieurs façons. Vous pouvez me demander des informations sur les régions, les technologies, les tendances temporelles, ou des recommandations basées sur les données actuelles. Que souhaitez-vous explorer?"; } setAiMessage(''); setAiConversation(prev => [...prev, { role: 'assistant', content: assistantResponse }]); } catch (error) { console.error('Error sending message:', error); setAiMessage(''); setAiConversation(prev => [...prev, { role: 'assistant', content: "Désolé, j'ai rencontré une erreur en traitant votre demande. Veuillez réessayer." }]); } }; // Function to filter detail panel data based on search query const filteredData = useMemo(() => { if (!searchQuery.trim()) return detailPanelData; const lowerCaseQuery = searchQuery.toLowerCase(); return detailPanelData.filter(item => { // Search in all string and number properties return Object.entries(item).some(([key, value]) => { if (typeof value === 'string') { return value.toLowerCase().includes(lowerCaseQuery); } else if (typeof value === 'number') { return value.toString().includes(lowerCaseQuery); } return false; }); }); }, [detailPanelData, searchQuery]); // Function to sort filtered data const sortedData = useMemo(() => { if (!sortConfig.key) return filteredData; return [...filteredData].sort((a, b) => { if (a[sortConfig.key] === undefined || b[sortConfig.key] === undefined) { return 0; } let comparison = 0; if (typeof a[sortConfig.key] === 'string') { comparison = a[sortConfig.key].localeCompare(b[sortConfig.key]); } else { comparison = a[sortConfig.key] - b[sortConfig.key]; } return sortConfig.direction === 'ascending' ? comparison : -comparison; }); }, [filteredData, sortConfig]); // Pagination const paginatedData = useMemo(() => { const startIndex = (currentPage - 1) * itemsPerPage; return sortedData.slice(startIndex, startIndex + itemsPerPage); }, [sortedData, currentPage, itemsPerPage]); const totalPages = Math.ceil(sortedData.length / itemsPerPage); // Function to get status icon const getStatusIcon = (status) => { switch(status) { case 'Favorable': return
; case 'Unfavorable': return
; case 'Pending': return
; default: return null; } }; // Function to get table headers based on data const getTableHeaders = () => { if (detailPanelData.length === 0) return []; // Get all unique keys from the data const allKeys = new Set(); detailPanelData.forEach(item => { Object.keys(item).forEach(key => allKeys.add(key)); }); // Define priority order for common fields const priorityFields = ['id', 'location', 'region', 'technology', 'status', 'date']; // Sort keys by priority, then alphabetically return Array.from(allKeys) .sort((a, b) => { const indexA = priorityFields.indexOf(a); const indexB = priorityFields.indexOf(b); if (indexA !== -1 && indexB !== -1) { return indexA - indexB; } else if (indexA !== -1) { return -1; } else if (indexB !== -1) { return 1; } else { return a.localeCompare(b); } }) .filter(key => key !== '_id'); // Exclude MongoDB ID if present }; // Function to format header text const formatHeaderText = (header) => { // Convert camelCase or snake_case to Title Case with spaces return header .replace(/([A-Z])/g, ' $1') // Insert space before capital letters .replace(/_/g, ' ') // Replace underscores with spaces .replace(/^./, str => str.toUpperCase()) // Capitalize first letter .trim(); }; // Function to format cell value based on key and value const formatCellValue = (key, value) => { if (value === null || value === undefined) return '-'; if (key === 'date' || key.includes('Date')) { // Format dates return new Date(value).toLocaleDateString('fr-FR'); } else if (typeof value === 'boolean') { // Format booleans return value ? 'Oui' : 'Non'; } else if (key === 'status') { // Format status with color return ( {value} ); } return value.toString(); }; return (
{/* Left Sidebar Navigation */}

ANF Analytics

Dernière mise à jour:

20 Juin 2024

{/* Main Content Area */}
{/* Top Bar */}

Tableau de Bord ANF

Analyse de l'Infrastructure de Télécommunications

{/* AI Assistant Button */} {/* Date Range Selector */}
Date Range Selector alert('Sélecteur de plage de dates cliqué')} />
{/* Filter Button */} {/* Export Button */}
{/* Main Content */}
{loading ? (
) : ( <> {/* KPI Cards */}
} /> } onClick={() => handleChartElementClick('status', 'Favorable')} /> } onClick={() => handleChartElementClick('status', 'Pending')} /> } onClick={() => handleChartElementClick('status', 'Unfavorable')} />
{/* Middle Section - Map and Charts */}
{/* Map Section */}

Distribution Régionale

{/* Placeholder for Algeria Map */}

Carte interactive de l'Algérie montrant la distribution des sites ANF

{mockData.regions.map(region => (
handleChartElementClick('region', region.name)} > Région {region.name}
{region.sites} sites
))}
{/* Charts Section */}
{/* Status Distribution Chart */}

Statut d'Approbation

handleChartElementClick('status', 'Favorable')} > Status Distribution Donut Chart
handleChartElementClick('status', 'Favorable')} >
Favorable
handleChartElementClick('status', 'Pending')} >
En Attente
handleChartElementClick('status', 'Unfavorable')} >
Défavorable
{/* Technology Distribution Chart */}

Distribution des Technologies

{mockData.technologies.map(tech => (
handleChartElementClick('technology', tech.name)} >
{tech.name} {tech.count} sites
))}

70,2% des sites utilisent la technologie 4G, tandis que 29,8% utilisent la 5G.

{/* Monthly Trends Chart */}

Tendances Mensuelles d'Approbation

{/* Placeholder for line chart */}
{mockData.monthlyTrends.map((data, index) => (
handleChartElementClick('month', data.month)} >
{data.month}
))}
Favorable
En Attente
Défavorable
{/* AI Insights Panel - Enhanced Version */}

Insights IA

{insights.length === 0 ? (

Aucun insight disponible. Cliquez sur le bouton de rafraîchissement pour générer des insights.

) : (
{insights.map(insight => { const confidenceInfo = getConfidenceInfo(insight.confidence); return (
{getCategoryIcon(insight.category)}

{insight.text}

{confidenceInfo.icon} {confidenceInfo.text}
{!insight.feedbackGiven ? (
) : (
Merci pour votre feedback
)}
); })}
)}
{/* Bottom Section - Data Table */}

Demandes de Sites ANF Récentes

{mockData.recentSites.map((site, index) => ( { // Determine which data type to fetch based on the site const dataType = site.status === 'Favorable' ? 'status' : site.status === 'Unfavorable' ? 'status' : site.status === 'Pending' ? 'status' : 'technology'; const dataKey = site.status === 'Favorable' ? 'Favorable' : site.status === 'Unfavorable' ? 'Unfavorable' : site.status === 'Pending' ? 'Pending' : site.technology; handleChartElementClick(dataType, dataKey); }} > ))}
ID Site Emplacement Technologie Statut Date
{site.id} {site.location} {site.technology}
{getStatusIcon(site.status)} {site.status}
{site.date}
Affichage de 5 sur 42 entrées
)}
{/* Filter Panel */} {showFilters && (

Filtrer les Données

{/* Region Filter */}
Region Filter alert('Filtre de région cliqué')} />
{/* Technology Filter */}
{/* Status Filter */}
{/* Date Range Filter */}
Date Range Selector alert('Sélecteur de plage de dates cliqué')} />
)} {/* AI Assistant Chat Panel */} {showAIAssistant && (

Assistant Analytique ANF

{/* Dashboard Summary Button */}
{/* Dashboard Summary Display */} {dashboardSummary && (

Vue d'ensemble rapide

{dashboardSummary}

)}
{aiConversation.map((message, index) => (

{message.content}

))} {aiMessage && (
)}
setUserInput(e.target.value)} onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()} />

Exemples: "Quelle région a le plus de sites?", "Tendances des approbations", "Recommandations"

)} {/* Detail Panel - Sliding from right */} {showDetailPanel && (
{ // Close panel when clicking outside if (e.target === e.currentTarget) { closeDetailPanel(); } }} >
{/* Panel Header */}

{detailPanelTitle}

{detailPanelDescription}

{/* Search and Controls */}
setSearchQuery(e.target.value)} />
{sortedData.length > 0 ? (

Affichage de {Math.min((currentPage - 1) * itemsPerPage + 1, sortedData.length)} à {Math.min(currentPage * itemsPerPage, sortedData.length)} sur {sortedData.length} résultats {searchQuery && ` (filtrés de ${detailPanelData.length} total)`}

) : (

Aucun résultat trouvé

)}
{/* Table Content */}
{paginatedData.length > 0 ? ( {getTableHeaders().map(header => ( ))} {paginatedData.map((item, index) => ( {getTableHeaders().map(header => ( ))} ))}
requestSort(header)} >
{formatHeaderText(header)} {sortConfig.key === header && ( {sortConfig.direction === 'ascending' ? ( ) : ( )} )}
{formatCellValue(header, item[header])}
) : (

Aucune donnée trouvée

{searchQuery && ( )}
)}
{/* Pagination */} {sortedData.length > 0 && (
{Array.from({ length: Math.min(5, totalPages) }, (_, i) => { // Calculate page numbers to show (centered around current page) let pageNum; if (totalPages <= 5) { pageNum = i + 1; } else if (currentPage <= 3) { pageNum = i + 1; } else if (currentPage >= totalPages - 2) { pageNum = totalPages - 4 + i; } else { pageNum = currentPage - 2 + i; } return ( ); })}
Page {currentPage} sur {totalPages}
import React, { useState, useEffect, useCallback, useMemo } from 'react'; import { BarChart, PieChart, MapPin, Calendar, Home, Settings, Filter, Download, ChevronDown, Info, ArrowUpRight, ArrowDownRight, Clock, X, Check, ThumbsUp, ThumbsDown, RefreshCw, AlertTriangle, MessageSquare, Lightbulb, Zap, BarChart2, TrendingUp as TrendingUpIcon, Search, ArrowUp, ArrowDown, ChevronLeft, ChevronRight, Maximize2, Minimize2, XCircle } from 'lucide-react'; // ... (previous code remains the same) const mockData = { totalSites: 1248, approvalRate: 68, pendingRate: 22, unfavorableRate: 10, regions: [ { id: 1, name: 'North', sites: 423, favorable: 302, unfavorable: 42, pending: 79 }, { id: 2, name: 'South', sites: 289, favorable: 186, unfavorable: 31, pending: 72 }, { id: 3, name: 'East', sites: 356, favorable: 249, unfavorable: 35, pending: 72 }, { id: 4, name: 'West', sites: 180, favorable: 112, unfavorable: 17, pending: 51 } ], technologies: [ { name: '4G', count: 876 }, { name: '5G', count: 372 } ], monthlyTrends: [ { month: 'Jan', approved: 42, rejected: 12, pending: 18 }, { month: 'Feb', approved: 48, rejected: 10, pending: 22 }, { month: 'Mar', approved: 53, rejected: 8, pending: 25 }, { month: 'Apr', approved: 61, rejected: 11, pending: 19 }, { month: 'May', approved: 58, rejected: 9, pending: 23 }, { month: 'Jun', approved: 65, rejected: 7, pending: 28 } ], recentSites: [ { id: 'ANF-2024-0123', location: 'Algiers', technology: '5G', status: 'Favorable', date: '2024-06-15' }, { id: 'ANF-2024-0124', location: 'Oran', technology: '4G', status: 'Pending', date: '2024-06-12' }, { id: 'ANF-2024-0125', location: 'Constantine', technology: '5G', status: 'Unfavorable', date: '2024-06-10' }, { id: 'ANF-2024-0126', location: 'Annaba', technology: '4G', status: 'Favorable', date: '2024-06-08' }, { id: 'ANF-2024-0127', location: 'Batna', technology: '4G', status: 'Favorable', date: '2024-06-05' } ], // Detailed data for each chart detailedData: { regions: { North: [ { id: 'ANF-2024-0101', location: 'Algiers', technology: '5G', status: 'Favorable', date: '2024-06-02', population: 3_500_000, density: 'High' }, { id: 'ANF-2024-0102', location: 'Blida', technology: '4G', status: 'Favorable', date: '2024-06-03', population: 1_002_000, density: 'Medium' }, { id: 'ANF-2024-0103', location: 'Tizi Ouzou', technology: '4G', status: 'Pending', date: '2024-06-05', population: 1_127_000, density: 'Medium' }, { id: 'ANF-2024-0104', location: 'Boumerdès', technology: '5G', status: 'Favorable', date: '2024-06-07', population: 802_000, density: 'Medium' }, { id: 'ANF-2024-0105', location: 'Tipaza', technology: '4G', status: 'Unfavorable', date: '2024-06-08', population: 591_000, density: 'Low' } ], South: [ { id: 'ANF-2024-0201', location: 'Adrar', technology: '4G', status: 'Favorable', date: '2024-06-01', population: 455_000, density: 'Very Low' }, { id: 'ANF-2024-0202', location: 'Tamanrasset', technology: '4G', status: 'Pending', date: '2024-06-04', population: 176_000, density: 'Very Low' }, { id: 'ANF-2024-0203', location: 'Illizi', technology: '4G', status: 'Pending', date: '2024-06-06', population: 52_000, density: 'Very Low' }, { id: 'ANF-2024-0204', location: 'Tindouf', technology: '5G', status: 'Unfavorable', date: '2024-06-09', population: 58_000, density: 'Very Low' }, { id: 'ANF-2024-0205', location: 'Béchar', technology: '4G', status: 'Favorable', date: '2024-06-10', population: 270_000, density: 'Low' } ], East: [ { id: 'ANF-2024-0301', location: 'Constantine', technology: '5G', status: 'Favorable', date: '2024-06-02', population: 938_000, density: 'High' }, { id: 'ANF-2024-0302', location: 'Annaba', technology: '5G', status: 'Favorable', date: '2024-06-05', population: 640_000, density: 'Medium' }, { id: 'ANF-2024-0303', location: 'Sétif', technology: '4G', status: 'Pending', date: '2024-06-07', population: 1_496_000, density: 'Medium' }, { id: 'ANF-2024-0304', location: 'Batna', technology: '4G', status: 'Unfavorable', date: '2024-06-09', population: 1_120_000, density: 'Medium' }, { id: 'ANF-2024-0305', location: 'Guelma', technology: '4G', status: 'Favorable', date: '2024-06-11', population: 482_000, density: 'Low' } ], West: [ { id: 'ANF-2024-0401', location: 'Oran', technology: '5G', status: 'Favorable', date: '2024-06-01', population: 1_584_000, density: 'High' }, { id: 'ANF-2024-0402', location: 'Tlemcen', technology: '4G', status: 'Pending', date: '2024-06-03', population: 949_000, density: 'Medium' }, { id: 'ANF-2024-0403', location: 'Sidi Bel Abbès', technology: '4G', status: 'Favorable', date: '2024-06-06', population: 604_000, density: 'Medium' }, { id: 'ANF-2024-0404', location: 'Mostaganem', technology: '5G', status: 'Unfavorable', date: '2024-06-08', population: 746_000, density: 'Medium' }, { id: 'ANF-2024-0405', location: 'Mascara', technology: '4G', status: 'Pending', date: '2024-06-10', population: 784_000, density: 'Medium' } ] }, approvalStatus: { Favorable: [ { id: 'ANF-2024-0501', location: 'Algiers', technology: '5G', region: 'North', date: '2024-06-01', approvalDate: '2024-06-10', processingTime: 9 }, { id: 'ANF-2024-0502', location: 'Oran', technology: '5G', region: 'West', date: '2024-06-02', approvalDate: '2024-06-09', processingTime: 7 }, { id: 'ANF-2024-0503', location: 'Constantine', technology: '4G', region: 'East', date: '2024-06-03', approvalDate: '2024-06-15', processingTime: 12 }, { id: 'ANF-2024-0504', location: 'Annaba', technology: '4G', region: 'East', date: '2024-06-04', approvalDate: '2024-06-18', processingTime: 14 }, { id: 'ANF-2024-0505', location: 'Blida', technology: '5G', region: 'North', date: '2024-06-05', approvalDate: '2024-06-12', processingTime: 7 } ], Unfavorable: [ { id: 'ANF-2024-0601', location: 'Batna', technology: '4G', region: 'East', date: '2024-06-01', rejectionDate: '2024-06-15', processingTime: 14, reason: 'Environmental concerns' }, { id: 'ANF-2024-0602', location: 'Tindouf', technology: '5G', region: 'South', date: '2024-06-03', rejectionDate: '2024-06-18', processingTime: 15, reason: 'Incomplete documentation' }, { id: 'ANF-2024-0603', location: 'Mostaganem', technology: '4G', region: 'West', date: '2024-06-05', rejectionDate: '2024-06-20', processingTime: 15, reason: 'Technical incompatibility' }, { id: 'ANF-2024-0604', location: 'Tipaza', technology: '5G', region: 'North', date: '2024-06-07', rejectionDate: '2024-06-21', processingTime: 14, reason: 'Zoning restrictions' }, { id: 'ANF-2024-0605', location: 'Béjaïa', technology: '4G', region: 'East', date: '2024-06-09', rejectionDate: '2024-06-25', processingTime: 16, reason: 'Proximity to sensitive area' } ], Pending: [ { id: 'ANF-2024-0701', location: 'Sétif', technology: '5G', region: 'East', date: '2024-06-10', currentStage: 'Technical Review', daysInProcess: 20 }, { id: 'ANF-2024-0702', location: 'Tlemcen', technology: '4G', region: 'West', date: '2024-06-11', currentStage: 'Environmental Assessment', daysInProcess: 19 }, { id: 'ANF-2024-0703', location: 'Tamanrasset', technology: '4G', region: 'South', date: '2024-06-12', currentStage: 'Initial Screening', daysInProcess: 18 }, { id: 'ANF-2024-0704', location: 'Tizi Ouzou', technology: '5G', region: 'North', date: '2024-06-13', currentStage: 'Public Consultation', daysInProcess: 17 }, { id: 'ANF-2024-0705', location: 'Mascara', technology: '4G', region: 'West', date: '2024-06-14', currentStage: 'Final Approval', daysInProcess: 16 } ] }, technologies: { '4G': [ { id: 'ANF-2024-0801', location: 'Algiers', region: 'North', status: 'Favorable', date: '2024-06-01', bandwidth: '20 MHz', coverage: '15 km' }, { id: 'ANF-2024-0802', location: 'Oran', region: 'West', status: 'Favorable', date: '2024-06-03', bandwidth: '15 MHz', coverage: '12 km' }, { id: 'ANF-2024-0803', location: 'Constantine', region: 'East', status: 'Pending', date: '2024-06-05', bandwidth: '10 MHz', coverage: '10 km' }, { id: 'ANF-2024-0804', location: 'Adrar', region: 'South', status: 'Unfavorable', date: '2024-06-07', bandwidth: '15 MHz', coverage: '20 km' }, { id: 'ANF-2024-0805', location: 'Annaba', region: 'East', status: 'Favorable', date: '2024-06-09', bandwidth: '20 MHz', coverage: '15 km' } ], '5G': [ { id: 'ANF-2024-0901', location: 'Algiers', region: 'North', status: 'Favorable', date: '2024-06-02', bandwidth: '100 MHz', coverage: '2 km' }, { id: 'ANF-2024-0902', location: 'Oran', region: 'West', status: 'Pending', date: '2024-06-04', bandwidth: '80 MHz', coverage: '1.5 km' }, { id: 'ANF-2024-0903', location: 'Constantine', region: 'East', status: 'Favorable', date: '2024-06-06', bandwidth: '100 MHz', coverage: '2 km' }, { id: 'ANF-2024-0904', location: 'Blida', region: 'North', status: 'Unfavorable', date: '2024-06-08', bandwidth: '60 MHz', coverage: '1 km' }, { id: 'ANF-2024-0905', location: 'Annaba', region: 'East', status: 'Favorable', date: '2024-06-10', bandwidth: '120 MHz', coverage: '2.5 km' } ] }, monthlyData: { 'Jan': [ { id: 'ANF-2024-0001', location: 'Algiers', technology: '4G', status: 'Favorable', region: 'North', date: '2024-01-05' }, { id: 'ANF-2024-0002', location: 'Oran', technology: '5G', status: 'Favorable', region: 'West', date: '2024-01-08' }, { id: 'ANF-2024-0003', location: 'Constantine', technology: '4G', status: 'Unfavorable', region: 'East', date: '2024-01-12' }, { id: 'ANF-2024-0004', location: 'Annaba', technology: '5G', status: 'Pending', region: 'East', date: '2024-01-15' }, { id: 'ANF-2024-0005', location: 'Adrar', technology: '4G', status: 'Favorable', region: 'South', date: '2024-01-20' } ], 'Feb': [ { id: 'ANF-2024-0006', location: 'Blida', technology: '4G', status: 'Favorable', region: 'North', date: '2024-02-03' }, { id: 'ANF-2024-0007', location: 'Tlemcen', technology: '5G', status: 'Pending', region: 'West', date: '2024-02-07' }, { id: 'ANF-2024-0008', location: 'Sétif', technology: '4G', status: 'Favorable', region: 'East', date: '2024-02-10' }, { id: 'ANF-2024-0009', location: 'Tamanrasset', technology: '4G', status: 'Unfavorable', region: 'South', date: '2024-02-15' }, { id: 'ANF-2024-0010', location: 'Mostaganem', technology: '5G', status: 'Favorable', region: 'West', date: '2024-02-22' } ], 'Mar': [ { id: 'ANF-2024-0011', location: 'Tizi Ouzou', technology: '4G', status: 'Favorable', region: 'North', date: '2024-03-02' }, { id: 'ANF-2024-0012', location: 'Sidi Bel Abbès', technology: '5G', status: 'Favorable', region: 'West', date: '2024-03-08' }, { id: 'ANF-2024-0013', location: 'Batna', technology: '4G', status: 'Pending', region: 'East', date: '2024-03-12' }, { id: 'ANF-2024-0014', location: 'Béchar', technology: '5G', status: 'Unfavorable', region: 'South', date: '2024-03-18' }, { id: 'ANF-2024-0015', location: 'Guelma', technology: '4G', status: 'Favorable', region: 'East', date: '2024-03-25' } ], 'Apr': [ { id: 'ANF-2024-0016', location: 'Boumerdès', technology: '5G', status: 'Favorable', region: 'North', date: '2024-04-05' }, { id: 'ANF-2024-0017', location: 'Mascara', technology: '4G', status: 'Pending', region: 'West', date: '2024-04-10' }, { id: 'ANF-2024-0018', location: 'Béjaïa', technology: '5G', status: 'Favorable', region: 'East', date: '2024-04-15' }, { id: 'ANF-2024-0019', location: 'Illizi', technology: '4G', status: 'Unfavorable', region: 'South', date: '2024-04-20' }, { id: 'ANF-2024-0020', location: 'Oran', technology: '5G', status: 'Favorable', region: 'West', date: '2024-04-25' } ], 'May': [ { id: 'ANF-2024-0021', location: 'Tipaza', technology: '4G', status: 'Favorable', region: 'North', date: '2024-05-03' }, { id: 'ANF-2024-0022', location: 'Tlemcen', technology: '5G', status: 'Favorable', region: 'West', date: '2024-05-08' }, { id: 'ANF-2024-0023', location: 'Constantine', technology: '4G', status: 'Pending', region: 'East', date: '2024-05-13' }, { id: 'ANF-2024-0024', location: 'Tindouf', technology: '5G', status: 'Unfavorable', region: 'South', date: '2024-05-18' }, { id: 'ANF-2024-0025', location: 'Annaba', technology: '4G', status: 'Favorable', region: 'East', date: '2024-05-23' } ], 'Jun': [ { id: 'ANF-2024-0026', location: 'Algiers', technology: '5G', status: 'Favorable', region: 'North', date: '2024-06-02' }, { id: 'ANF-2024-0027', location: 'Oran', technology: '4G', status: 'Pending', region: 'West', date: '2024-06-07' }, { id: 'ANF-2024-0028', location: 'Sétif', technology: '5G', status: 'Favorable', region: 'East', date: '2024-06-12' }, { id: 'ANF-2024-0029', location: 'Adrar', technology: '4G', status: 'Unfavorable', region: 'South', date: '2024-06-17' }, { id: 'ANF-2024-0030', location: 'Blida', technology: '5G', status: 'Favorable', region: 'North', date: '2024-06-22' } ] } } }; // ... (rest of the code remains the same) const mockInsights = [ { id: 1, text: "Approval rates have increased by 5.2% over the last quarter, with the North region showing the highest improvement.", confidence: 0.92, category: "trend", timestamp: new Date().toISOString(), feedbackGiven: false }, { id: 2, text: "The South region has a 25% higher pending rate than other regions, suggesting potential process delays.", confidence: 0.85, category: "bottleneck", timestamp: new Date().toISOString(), feedbackGiven: false }, { id: 3, text: "5G site approvals are processing 15% faster than 4G sites, indicating potential for technology-specific optimization.", confidence: 0.78, category: "opportunity", timestamp: new Date().toISOString(), feedbackGiven: false }, { id: 4, text: "There may be a correlation between site density and approval rates in urban areas, but more data is needed to confirm this pattern.", confidence: 0.62, category: "correlation", timestamp: new Date().toISOString(), feedbackGiven: false } ]; const Dashboard = () => { const [activeSection, setActiveSection] = useState('overview'); const [dateRange, setDateRange] = useState('Jan 2024 - Jun 2024'); const [showFilters, setShowFilters] = useState(false); const [selectedRegion, setSelectedRegion] = useState('All Regions'); const [selectedTechnology, setSelectedTechnology] = useState('All Technologies'); const [showAIAssistant, setShowAIAssistant] = useState(false); const [insights, setInsights] = useState(mockInsights); const [isGeneratingInsight, setIsGeneratingInsight] = useState(false); const [aiMessage, setAiMessage] = useState(''); const [aiConversation, setAiConversation] = useState([ { role: 'assistant', content: 'Bonjour ! Je suis votre assistant d\'analyse de données ANF. Comment puis-je vous aider aujourd\'hui ?' } ]); const [userInput, setUserInput] = useState(''); // New state for detail panel const [showDetailPanel, setShowDetailPanel] = useState(false); const [detailPanelData, setDetailPanelData] = useState([]); const [detailPanelTitle, setDetailPanelTitle] = useState(''); const [detailPanelDescription, setDetailPanelDescription] = useState(''); const [searchQuery, setSearchQuery] = useState(''); const [sortConfig, setSortConfig] = useState({ key: null, direction: 'ascending' }); const [isFullScreen, setIsFullScreen] = useState(false); const [currentPage, setCurrentPage] = useState(1); const [itemsPerPage, setItemsPerPage] = useState(10); // Simulate data loading const [loading, setLoading] = useState(true); useEffect(() => { setTimeout(() => { setLoading(false); }, 1000); }, []); useEffect(() => { setCurrentPage(1); }, [detailPanelData, searchQuery]); const handleChartElementClick = (dataType, dataKey) => { let data = []; let title = ''; let description = ''; switch(dataType) { case 'region': data = mockData.detailedData.regions[dataKey] || []; title = `Région ${dataKey}`; description = `Détails des sites ANF dans la région ${dataKey}`; break; case 'status': data = mockData.detailedData.approvalStatus[dataKey] || []; title = `Statut: ${dataKey}`; description = `Sites ANF avec le statut ${dataKey}`; break; case 'technology': data = mockData.detailedData.technologies[dataKey] || []; title = `Technologie: ${dataKey}`; description = `Sites ANF utilisant la technologie ${dataKey}`; break; case 'month': data = mockData.detailedData.monthlyData[dataKey] || []; title = `Mois: ${dataKey}`; description = `Sites ANF déposés en ${dataKey} 2024`; break; default: data = []; title = 'Détails'; description = 'Informations détaillées'; } setDetailPanelData(data); setDetailPanelTitle(title); setDetailPanelDescription(description); setShowDetailPanel(true); setSearchQuery(''); setSortConfig({ key: null, direction: 'ascending' }); }; const closeDetailPanel = () => { setShowDetailPanel(false); setTimeout(() => { setDetailPanelData([]); setDetailPanelTitle(''); setDetailPanelDescription(''); }, 300); }; const toggleFullScreen = () => { setIsFullScreen(!isFullScreen); }; const requestSort = (key) => { let direction = 'ascending'; if (sortConfig.key === key && sortConfig.direction === 'ascending') { direction = 'descending'; } setSortConfig({ key, direction }); }; const generateNewInsight = useCallback(async () => { setIsGeneratingInsight(true); try { const prompt = `Analyze ANF site data with the following parameters: - Region: ${selectedRegion} - Technology: ${selectedTechnology} - Date Range: ${dateRange} - Current approval rate: ${mockData.approvalRate}% - Current pending rate: ${mockData.pendingRate}% - Current unfavorable rate: ${mockData.unfavorableRate}% Generate one actionable insight about telecommunications infrastructure deployment based on this data.`; await new Promise(resolve => setTimeout(resolve, 1500)); const newInsightOptions = [ { text: `Dans la région ${selectedRegion === 'All Regions' ? 'Nord' : selectedRegion}, les sites utilisant la technologie ${selectedTechnology === 'All Technologies' ? '5G' : selectedTechnology} montrent un taux d'approbation 12% plus élevé que la moyenne. Considérez prioriser ces déploiements pour des résultats plus rapides.`, confidence: 0.88, category: "recommendation" }, { text: `Les délais d'approbation ont augmenté de 15% dans les zones rurales par rapport au trimestre précédent. Une révision des processus de validation pourrait être nécessaire pour ces régions.`, confidence: 0.72, category: "alert" }, { text: `Il semble y avoir une corrélation entre la densité de population et les taux d'approbation, mais les données actuelles sont insuffisantes pour établir une causalité définitive.`, confidence: 0.65, category: "correlation" } ]; const randomInsight = newInsightOptions[Math.floor(Math.random() * newInsightOptions.length)]; const newInsight = { id: insights.length + 1, text: randomInsight.text, confidence: randomInsight.confidence, category: randomInsight.category, timestamp: new Date().toISOString(), feedbackGiven: false }; setInsights(prevInsights => [newInsight, ...prevInsights]); } catch (error) { console.error('Error generating insight:', error); } finally { setIsGeneratingInsight(false); } }, [selectedRegion, selectedTechnology, dateRange, insights]); const provideInsightFeedback = (insightId, isPositive) => { setInsights(prevInsights => prevInsights.map(insight => insight.id === insightId ? { ...insight, feedbackGiven: true, positiveRating: isPositive } : insight ) ); console.log(`Feedback for insight ${insightId}: ${isPositive ? 'positive' : 'negative'}`); }; const getConfidenceInfo = (confidenceScore) => { if (confidenceScore >= 0.85) { return { text: "Confiance élevée", color: "text-green-600", icon: }; } else if (confidenceScore >= 0.7) { return { text: "Confiance moyenne", color: "text-amber-600", icon: }; } else { return { text: "Confiance limitée", color: "text-gray-500", icon: }; } }; const getCategoryIcon = (category) => { switch(category) { case 'trend': return ; case 'bottleneck': return ; case 'opportunity': return ; case 'correlation': return ; case 'recommendation': return ; case 'alert': return ; default: return ; } }; const handleSendMessage = async () => { if (!userInput.trim()) return; const newMessage = { role: 'user', content: userInput }; setAiConversation(prev => [...prev, newMessage]); setUserInput(''); setAiMessage('...'); try { await new Promise(resolve => setTimeout(resolve, 1000)); let assistantResponse = ''; const userQuestion = userInput.toLowerCase(); if (userQuestion.includes('région') || userQuestion.includes('region')) { assistantResponse = "D'après les données actuelles, la région Nord présente le plus grand nombre de sites ANF (423), suivie par l'Est (356), le Sud (289) et l'Ouest (180). La région Nord a également le taux d'approbation le plus élevé à 71%."; } else if (userQuestion.includes('technologie') || userQuestion.includes('5g') || userQuestion.includes('4g')) { assistantResponse = "La technologie 4G représente 70,2% des sites ANF (876 sites), tandis que la 5G représente 29,8% (372 sites). Les sites 5G ont un taux d'approbation moyen 8% plus élevé que les sites 4G."; } else if (userQuestion.includes('tendance') || userQuestion.includes('trend') || userQuestion.includes('évolution')) { assistantResponse = "Les approbations de sites ANF montrent une tendance à la hausse, avec une augmentation de 54,8% de janvier à juin 2024. Le taux d'approbation global est passé de 58% en janvier à 68% en juin."; } else if (userQuestion.includes('recommandation') || userQuestion.includes('suggestion')) { assistantResponse = "Basé sur les données actuelles, je recommande de:\n\n1. Accélérer le traitement des demandes en attente dans la région Sud, où le taux d'attente est 25% plus élevé que la moyenne\n\n2. Prioriser les déploiements 5G dans les zones urbaines où ils montrent un taux d'approbation supérieur\n\n3. Mettre en place un suivi spécifique pour les sites en attente depuis plus de 45 jours"; } else { assistantResponse = "Je peux vous aider à analyser les données ANF de plusieurs façons. Vous pouvez me demander des informations sur les régions, les technologies, les tendances temporelles, ou des recommandations basées sur les données actuelles. Que souhaitez-vous explorer?"; } setAiMessage(''); setAiConversation(prev => [...prev, { role: 'assistant', content: assistantResponse }]); } catch (error) { console.error('Error sending message:', error); setAiMessage(''); setAiConversation(prev => [...prev, { role: 'assistant', content: "Désolé, j'ai rencontré une erreur en traitant votre demande. Veuillez réessayer." }]); } }; const filteredData = useMemo(() => { if (!searchQuery.trim()) return detailPanelData; const lowerCaseQuery = searchQuery.toLowerCase(); return detailPanelData.filter(item => { return Object.entries(item).some(([key, value]) => { if (typeof value === 'string') { return value.toLowerCase().includes(lowerCaseQuery); } else if (typeof value === 'number') { return value.toString().includes(lowerCaseQuery); } return false; }); }); }, [detailPanelData, searchQuery]); const sortedData = useMemo(() => { if (!sortConfig.key) return filteredData; return [...filteredData].sort((a, b) => { if (a[sortConfig.key] === undefined || b[sortConfig.key] === undefined) { return 0; } let comparison = 0; if (typeof a[sortConfig.key] === 'string') { comparison = a[sortConfig.key].localeCompare(b[sortConfig.key]); } else { comparison = a[sortConfig.key] - b[sortConfig.key]; } return sortConfig.direction === 'ascending' ? comparison : -comparison; }); }, [filteredData, sortConfig]); const paginatedData = useMemo(() => { const startIndex = (currentPage - 1) * itemsPerPage; return sortedData.slice(startIndex, startIndex + itemsPerPage); }, [sortedData, currentPage, itemsPerPage]); const totalPages = Math.ceil(sortedData.length / itemsPerPage); const getStatusIcon = (status) => { switch(status) { case 'Favorable': return
; case 'Unfavorable': return
; case 'Pending': return
; default: return null; } }; const getTableHeaders = () => { if (detailPanelData.length === 0) return []; const allKeys = new Set(); detailPanelData.forEach(item => { Object.keys(item).forEach(key => allKeys.add(key)); }); const priorityFields = ['id', 'location', 'region', 'technology', 'status', 'date']; return Array.from(allKeys) .sort((a, b) => { const indexA = priorityFields.indexOf(a); const indexB = priorityFields.indexOf(b); if (indexA !== -1 && indexB !== -1) { return indexA - indexB; } else if (indexA !== -1) { return -1; } else if (indexB !== -1) { return 1; } else { return a.localeCompare(b); } }) .filter(key => key !== '_id'); }; const formatHeaderText = (header) => { return header .replace(/([A-Z])/g, ' $1') .replace(/_/g, ' ') .replace(/^./, str => str.toUpperCase()) .trim(); }; const formatCellValue = (key, value) => { if (value === null || value === undefined) return '-'; if (key === 'date' || key.includes('Date')) { return new Date(value).toLocaleDateString('fr-FR'); } else if (typeof value === 'boolean') { return value ? 'Oui' : 'Non'; } else if (key === 'status') { return ( {value} ); } return value.toString(); }; return (
{/* Left Sidebar Navigation */}

ANF Analytics

Dernière mise à jour:

20 Juin 2024

{/* Main Content Area */}
{/* Top Bar */}

Tableau de Bord ANF

Analyse de l'Infrastructure de Télécommunications

{/* AI Assistant Button */} {/* Date Range Selector */}
Date Range Selector alert('Sélecteur de plage de dates cliqué')} />
{/* Filter Button */} {/* Export Button */}
{/* Main Content */}
{loading ? (
) : ( <>
} /> } onClick={() => handleChartElementClick('status', 'Favorable')} /> } onClick={() => handleChartElementClick('status', 'Pending')} /> } onClick={() => handleChartElementClick('status', 'Unfavorable')} />
{/* Map Section */}

Distribution Régionale

Carte interactive de l'Algérie montrant la distribution des sites ANF

{mockData.regions.map(region => (
handleChartElementClick('region', region.name)} > Région {region.name}
{region.sites} sites
))}
{/* Charts Section */}
{/* Status Distribution Chart */}

Statut d'Approbation

handleChartElementClick('status', 'Favorable')} > Status Distribution Donut Chart
handleChartElementClick('status', 'Favorable')} >
Favorable
handleChartElementClick('status', 'Pending')} >
En Attente
handleChartElementClick('status', 'Unfavorable')} >
Défavorable
{/* Technology Distribution Chart */}

Distribution des Technologies

{mockData.technologies.map(tech => (
handleChartElementClick('technology', tech.name)} >
{tech.name} {tech.count} sites
))}

70,2% des sites utilisent la technologie 4G, tandis que 29,8% utilisent la 5G.

{/* Monthly Trends Chart */}

Tendances Mensuelles d'Approbation

{mockData.monthlyTrends.map((data, index) => (
handleChartElementClick('month', data.month)} >
{data.month}
))}
Favorable
En Attente
Défavorable
{/* AI Insights Panel - Enhanced Version */}

Insights IA

{insights.length === 0 ? (

Aucun insight disponible. Cliquez sur le bouton de rafraîchissement pour générer des insights.

) : (
{insights.map(insight => { const confidenceInfo = getConfidenceInfo(insight.confidence); return (
{getCategoryIcon(insight.category)}

{insight.text}

{confidenceInfo.icon} {confidenceInfo.text}
{!insight.feedbackGiven ? (
) : (
Merci pour votre feedback
)}
); })}
)}
{/* Bottom Section - Data Table */}

Demandes de Sites ANF Récentes

{mockData.recentSites.map((site, index) => ( { const dataType = site.status === 'Favorable' ? 'status' : site.status === 'Unfavorable' ? 'status' : site.status === 'Pending' ? 'status' : 'technology'; const dataKey = site.status === 'Favorable' ? 'Favorable' : site.status === 'Unfavorable' ? 'Unfavorable' : site.status === 'Pending' ? 'Pending' : site.technology; handleChartElementClick(dataType, dataKey); }} > ))}
ID Site Emplacement Technologie Statut Date
{site.id} {site.location} {site.technology}
{getStatusIcon(site.status)} {site.status}
{site.date}
Affichage de 5 sur 42 entrées
)}
{/* Filter Panel */} {showFilters && (

Filtrer les Données

{/* Region Filter */}
Region Filter alert('Filtre de région cliqué')} />
{/* Technology Filter */}
{/* Status Filter */}
{/* Date Range Filter */}
Date Range Selector alert('Sélecteur de plage de dates cliqué')} />
)} {/* AI Assistant Chat Panel */} {showAIAssistant && (

Assistant Analytique ANF

{aiConversation.map((message, index) => (

{message.content}

))} {aiMessage && (
)}
setUserInput(e.target.value)} onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()} />

Exemples: "Quelle région a le plus de sites?", "Tendances des approbations", "Recommandations"

)} {/* Detail Panel - Sliding from right */} {showDetailPanel && (
{ if (e.target === e.currentTarget) { closeDetailPanel(); } }} >
{/* Panel Header */}

{detailPanelTitle}

{detailPanelDescription}

{/* Search and Controls */}
setSearchQuery(e.target.value)} />
{sortedData.length > 0 ? (

Affichage de {Math.min((currentPage - 1) * itemsPerPage + 1, sortedData.length)} à {Math.min(currentPage * itemsPerPage, sortedData.length)} sur {sortedData.length} résultats {searchQuery && ` (filtrés de ${detailPanelData.length} total)`}

) : (

Aucun résultat trouvé

)}
{/* Table Content */}
{paginatedData.length > 0 ? ( {getTableHeaders().map(header => ( ))} {paginatedData.map((item, index) => ( {getTableHeaders().map(header => ( ))} ))}
requestSort(header)} >
{formatHeaderText(header)} {sortConfig.key === header && ( {sortConfig.direction === 'ascending' ? ( ) : ( )} )}
{formatCellValue(header, item[header])}
) : (

Aucune donnée trouvée

{searchQuery && ( )}
)}
{/* Pagination */} {sortedData.length > 0 && (
{Array.from({ length: Math.min(5, totalPages) }, (_, i) => { let pageNum; if (totalPages <= 5) { pageNum = i + 1; } else if (currentPage <= 3) { pageNum = i + 1; } else if (currentPage >= totalPages - 2) { pageNum = totalPages - 4 + i; } else { pageNum = currentPage - 2 + i; } return ( ); })}
Page {currentPage} sur {totalPages}
)}
)}
); }; const NavItem = ({ icon, label, active, onClick }) => { return ( ); }; const KpiCard = ({ title, value, change, icon, onClick }) => { const isPositive = change >= 0; return (

{title}

{value}

{icon}
{isPositive ? ( ) : ( )} {Math.abs(change)}% par rapport au mois dernier
); }; export default Dashboard;