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 */}