import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { Card, Typography, Spin, Drawer, Empty, Tag, Button } from 'antd'; import { CalendarOutlined, RightOutlined, HistoryOutlined, RobotOutlined } from '@ant-design/icons'; import NarrativeSection from './NarrativeSection'; import StatsGrid from './StatsGrid'; import TrackList from './TrackList'; import Navbar from './Navbar'; const { Title, Text } = Typography; const Archives = () => { const [snapshots, setSnapshots] = useState([]); const [loading, setLoading] = useState(true); const [selectedSnapshot, setSelectedSnapshot] = useState(null); const [drawerVisible, setDrawerVisible] = useState(false); const fetchSnapshots = async () => { setLoading(true); try { const response = await axios.get('/api/snapshots'); setSnapshots(response.data); } catch (error) { console.error('Failed to fetch snapshots:', error); } finally { setLoading(false); } }; useEffect(() => { fetchSnapshots(); }, []); const handleSnapshotClick = (snapshot) => { setSelectedSnapshot(snapshot); setDrawerVisible(true); }; const closeDrawer = () => { setDrawerVisible(false); setSelectedSnapshot(null); }; // Helper to safely parse JSON if it comes as string (though axios usually handles it) const safeParse = (data) => { if (typeof data === 'string') { try { return JSON.parse(data); } catch (e) { return null; } } return data; }; return ( <>
<HistoryOutlined className="text-primary" /> Archives {snapshots.length} Snapshot{snapshots.length !== 1 && 's'} Found
{loading ? (
) : snapshots.length === 0 ? (
No archives found yet.} />
) : (
{snapshots.map((snap) => { const narrative = safeParse(snap.narrative_report); const metrics = safeParse(snap.metrics_payload); const date = new Date(snap.created_at); return ( handleSnapshotClick(snap)} >
} color="blue"> {date.toLocaleDateString(undefined, { weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' })} {date.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })}
Vibe {metrics?.vibe || 'Unknown Vibe'}
Musical Era
{metrics?.era?.musical_age || 'N/A'}
); })}
)} Snapshot: {selectedSnapshot && new Date(selectedSnapshot.created_at).toLocaleDateString()} } placement="right" width={800} // Wide drawer onClose={closeDrawer} open={drawerVisible} className="bg-[#0f172a] text-white" styles={{ header: { background: '#1e293b', borderBottom: '1px solid #334155' }, body: { background: '#0f172a', padding: '24px' }, mask: { backdropFilter: 'blur(4px)' } }} > {selectedSnapshot && (
{/* Reuse components but pass the specific snapshot data */} {/* Playlist Compositions if available */} {selectedSnapshot.playlist_composition && (
Archived Playlists
{/* We need to parse playlist composition if it's stored as JSON string */} {(() => { const playlists = safeParse(selectedSnapshot.playlist_composition); if (!playlists) return No playlist data archived.; return (
{playlists.six_hour && ( Short & Sweet (6h)}>
Theme {playlists.six_hour.theme} {playlists.six_hour.reasoning}
)} {playlists.daily && ( Daily Devotion}>
Strategy Daily Mix
)}
); })()}
)}
)}
); }; export default Archives;