|
import React, { useState, useEffect } from 'react'; |
|
import { getJobsHistory } from '../services/api'; |
|
import { History, LoaderCircle } from 'lucide-react'; |
|
|
|
function HistoryPanel({ onSelectJob }) { |
|
const [history, setHistory] = useState([]); |
|
const [isLoading, setIsLoading] = useState(false); |
|
const [isOpen, setIsOpen] = useState(false); |
|
|
|
const fetchHistory = () => { |
|
setIsLoading(true); |
|
getJobsHistory() |
|
.then(response => { |
|
setHistory(response.data.filter(job => job.status === 'SUCCESS' || job.status === 'FAILED')); |
|
}) |
|
.catch(error => console.error("Failed to fetch history:", error)) |
|
.finally(() => setIsLoading(false)); |
|
}; |
|
|
|
const togglePanel = () => { |
|
const newIsOpen = !isOpen; |
|
setIsOpen(newIsOpen); |
|
if (newIsOpen) { |
|
fetchHistory(); |
|
} |
|
}; |
|
|
|
const handleSelect = (job) => { |
|
onSelectJob(job); |
|
setIsOpen(false); |
|
} |
|
|
|
return ( |
|
<> |
|
<button |
|
onClick={togglePanel} |
|
className="fixed bottom-6 right-6 bg-green-600 hover:bg-green-700 text-white p-4 rounded-full shadow-lg z-50 transition-transform hover:scale-110 focus:outline-none focus:ring-2 focus:ring-green-400" |
|
aria-label="Toggle analysis history" |
|
> |
|
<History className="w-8 h-8" /> |
|
</button> |
|
|
|
{isOpen && <div onClick={() => setIsOpen(false)} className="fixed inset-0 bg-black/50 z-30 transition-opacity"></div>} |
|
|
|
<div className={`fixed top-0 right-0 h-full bg-gray-900 border-l border-gray-700 shadow-2xl z-40 transition-transform duration-500 ease-in-out ${isOpen ? 'translate-x-0' : 'translate-x-full'} w-full md:w-96`}> |
|
<div className="p-4 border-b border-gray-700 flex justify-between items-center"> |
|
<h2 className="text-xl font-bold">Analysis History</h2> |
|
<button onClick={() => setIsOpen(false)} className="text-gray-400 hover:text-white text-3xl">×</button> |
|
</div> |
|
<div className="p-4 overflow-y-auto h-[calc(100%-4rem)]"> |
|
{isLoading ? ( |
|
<div className="flex justify-center items-center h-full pt-20"> |
|
<LoaderCircle className="w-8 h-8 animate-spin text-green-400" /> |
|
</div> |
|
) : history.length === 0 ? ( |
|
<div className="text-center pt-20"> |
|
<p className="text-gray-500">No past analyses found.</p> |
|
<p className="text-xs text-gray-600 mt-2">Complete an analysis to see it here.</p> |
|
</div> |
|
) : ( |
|
<ul className="space-y-3"> |
|
{history.map(job => ( |
|
<li |
|
key={job.id} |
|
onClick={() => handleSelect(job)} |
|
className="p-3 bg-gray-800 rounded-md cursor-pointer hover:bg-green-800/50 border border-transparent hover:border-green-400/50 transition-all" |
|
> |
|
<p className="font-bold text-white">{job.ticker}</p> |
|
<div className="flex justify-between text-xs text-gray-400 mt-1"> |
|
<span>{new Date(job.created_at).toLocaleString('en-IN', { dateStyle: 'medium', timeStyle: 'short' })}</span> |
|
<span className={`font-semibold px-2 py-0.5 rounded-full ${job.status === 'SUCCESS' ? 'bg-green-900/50 text-green-300' : 'bg-red-900/50 text-red-300'}`}>{job.status}</span> |
|
</div> |
|
</li> |
|
))} |
|
</ul> |
|
)} |
|
</div> |
|
</div> |
|
</> |
|
); |
|
} |
|
|
|
export default HistoryPanel; |