import React, { useState, useCallback } from 'react'; import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell, LineChart, Line, Area, AreaChart } from 'recharts'; import { Upload, Music, TrendingUp, Users, Heart, Calendar, PlayCircle, FileText, Download, AlertCircle } from 'lucide-react'; const CSVAnalyticsDashboard = () => { const [data, setData] = useState([]); const [loading, setLoading] = useState(false); const [error, setError] = useState(''); const [fileName, setFileName] = useState(''); const [showDashboard, setShowDashboard] = useState(false); const handleFileUpload = useCallback((event) => { const file = event.target.files[0]; if (!file) return; if (!file.name.endsWith('.csv')) { setError('Please upload a CSV file'); return; } setLoading(true); setError(''); setFileName(file.name); const reader = new FileReader(); reader.onload = async (e) => { try { const csvContent = e.target.result; const Papa = await import('papaparse'); const parsedData = Papa.parse(csvContent, { header: true, dynamicTyping: true, skipEmptyLines: true }); if (parsedData.errors.length > 0) { setError('Error parsing CSV file'); setLoading(false); return; } // Validate required columns for music data const requiredColumns = ['song', 'streams']; const columns = parsedData.meta.fields; const hasRequiredColumns = requiredColumns.every(col => columns.includes(col)); if (!hasRequiredColumns) { setError('CSV must contain at least "song" and "streams" columns'); setLoading(false); return; } setData(parsedData.data.filter(row => row.song && row.streams)); setShowDashboard(true); } catch (err) { setError('Failed to process file'); } finally { setLoading(false); } }; reader.readAsText(file); }, []); const resetUpload = () => { setData([]); setShowDashboard(false); setFileName(''); setError(''); }; if (showDashboard && data.length > 0) { return ; } return (
{/* Header */}

CSV Analytics

Upload your CSV file and get instant music statistics

{/* Upload Area */}

Upload Your CSV File

Your CSV should contain columns: song, streams, and optionally listeners, saves, release_date

{loading ? 'Processing...' : 'Click to upload or drag and drop'}

CSV files only

{error && (
{error}
)} {fileName && !error && (
File uploaded: {fileName}
)}
{/* Sample CSV Format */}

Sample CSV Format:

song,listeners,streams,saves,release_date
"Song Title 1",1000,500000,250,2023-08-02
"Song Title 2",800,300000,180,2024-01-15
); }; const Dashboard = ({ data, fileName, onReset }) => { const totalStreams = data.reduce((sum, song) => sum + (song.streams || 0), 0); const totalListeners = data.reduce((sum, song) => sum + (song.listeners || 0), 0); const totalSaves = data.reduce((sum, song) => sum + (song.saves || 0), 0); const avgStreams = totalStreams / data.length; const chartData = data.map(song => ({ name: song.song.length > 15 ? song.song.substring(0, 15) + '...' : song.song, fullName: song.song, streams: song.streams || 0, listeners: song.listeners || 0, saves: song.saves || 0, releaseDate: song.release_date || 'Unknown' })); const timelineData = data .filter(song => song.release_date) .map(song => ({ date: song.release_date, streams: song.streams || 0, name: song.song })) .sort((a, b) => new Date(a.date) - new Date(b.date)); const COLORS = ['#8b5cf6', '#a78bfa', '#c4b5fd', '#ddd6fe', '#ede9fe', '#f3f4f6']; const formatNumber = (num) => { if (num >= 1000000) { return (num / 1000000).toFixed(1) + 'M'; } else if (num >= 1000) { return (num / 1000).toFixed(1) + 'K'; } return num.toString(); }; return (
{/* Header */}

Analytics Dashboard

Data from: {fileName}

{/* Stats Cards */}
} /> } /> } /> } />
{/* Charts Grid */}
{/* Bar Chart */} }> [formatNumber(value), 'Streams']} /> {/* Pie Chart */} }> `${name} ${(percent * 100).toFixed(0)}%`} > {chartData.map((entry, index) => ( ))} [formatNumber(value), 'Streams']} />
{/* Timeline Chart */} {timelineData.length > 0 && ( }> new Date(date).toLocaleDateString('en-US', { month: 'short', year: '2-digit' })} /> [formatNumber(value), 'Streams']} /> )} {/* Data Table */}

Detailed Data

{data.some(song => song.listeners) && ( )} {data.some(song => song.saves) && ( )} {data.some(song => song.release_date) && ( )} {data.map((song, index) => ( {data.some(s => s.listeners) && ( )} {data.some(s => s.saves) && ( )} {data.some(s => s.release_date) && ( )} ))}
Song StreamsListenersSavesRelease Date
{song.song} {formatNumber(song.streams || 0)}{formatNumber(song.listeners || 0)}{formatNumber(song.saves || 0)} {song.release_date ? new Date(song.release_date).toLocaleDateString('en-US') : 'Unknown'}
); }; const StatsCard = ({ title, value, icon }) => (

{title}

{value}

{icon}
); const ChartCard = ({ title, icon, children }) => (

{icon} {title}

{children}
); export default CSVAnalyticsDashboard;