Add LICENSE, README, and Docs tab to Mission Control
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
'use client'
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
interface HistoryEntry {
|
||||
id: string
|
||||
task: string
|
||||
command: string
|
||||
project: string
|
||||
action: string
|
||||
createdAt: string
|
||||
status: string
|
||||
reply?: string
|
||||
}
|
||||
|
||||
const projects = ['all', 'sitemente', 'holacompi', 'arabredox', 'infrastructure', 'trading']
|
||||
|
||||
export function TaskHistoryPanel() {
|
||||
const [history, setHistory] = useState<HistoryEntry[]>([])
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [selectedProject, setSelectedProject] = useState<string>('all')
|
||||
|
||||
useEffect(() => {
|
||||
loadHistory()
|
||||
}, [selectedProject])
|
||||
|
||||
const loadHistory = async () => {
|
||||
setLoading(true)
|
||||
try {
|
||||
const url = selectedProject === 'all'
|
||||
? '/api/command-history'
|
||||
: `/api/command-history?project=${selectedProject}`
|
||||
const response = await fetch(url)
|
||||
if (response.ok) {
|
||||
const data = await response.json()
|
||||
setHistory(data.history || [])
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to load history:', error)
|
||||
}
|
||||
setLoading(false)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{/* Project Filter Tabs */}
|
||||
<div className="flex gap-2 flex-wrap">
|
||||
{projects.map(project => (
|
||||
<button
|
||||
key={project}
|
||||
onClick={() => setSelectedProject(project)}
|
||||
className={`px-4 py-2 rounded-lg text-sm font-medium transition ${
|
||||
selectedProject === project
|
||||
? 'bg-brand-pink text-white'
|
||||
: 'bg-white/10 text-white/70 hover:bg-white/20'
|
||||
}`}
|
||||
>
|
||||
{project === 'all' ? 'All Projects' : project.charAt(0).toUpperCase() + project.slice(1)}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* History List */}
|
||||
<div className="border border-white/20 rounded-lg p-4 bg-white/5">
|
||||
<h3 className="text-lg font-bold mb-4 flex items-center gap-2">
|
||||
📜 TASK HISTORY
|
||||
<span className="text-sm font-normal text-white/50">({history.length} entries)</span>
|
||||
</h3>
|
||||
|
||||
{loading ? (
|
||||
<p className="text-white/50 text-center py-8">Loading...</p>
|
||||
) : history.length === 0 ? (
|
||||
<p className="text-white/50 text-center py-8">
|
||||
No history for this project.
|
||||
</p>
|
||||
) : (
|
||||
<div className="space-y-4 max-h-[500px] overflow-y-auto">
|
||||
{history.slice().reverse().map((entry) => (
|
||||
<div
|
||||
key={entry.id}
|
||||
className="p-4 rounded-lg bg-white/5 border border-white/10"
|
||||
>
|
||||
<div className="flex items-start justify-between mb-2">
|
||||
<div>
|
||||
<p className="font-medium text-brand-pink">{entry.task}</p>
|
||||
<p className="text-xs text-white/40">
|
||||
{new Date(entry.createdAt).toLocaleString()}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="px-2 py-1 rounded text-xs bg-white/10 text-white/70">
|
||||
{entry.project}
|
||||
</span>
|
||||
<span className={`px-2 py-1 rounded text-xs ${
|
||||
entry.status === 'completed'
|
||||
? 'bg-green-500/20 text-green-400'
|
||||
: 'bg-white/10 text-white/50'
|
||||
}`}>
|
||||
{entry.status}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-3 p-3 rounded bg-black/30 border border-white/10">
|
||||
<p className="text-xs text-white/50 mb-1">You sent:</p>
|
||||
<p className="text-sm">{entry.command}</p>
|
||||
</div>
|
||||
|
||||
{entry.reply && (
|
||||
<div className="mt-2 p-3 rounded bg-brand-pink/10 border border-brand-pink/30">
|
||||
<p className="text-xs text-brand-pink mb-1">Horus replied:</p>
|
||||
<p className="text-sm text-white/90">{entry.reply}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user