diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 2827207..9a2c460 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -14,16 +14,20 @@ const App = () => {
enabled: true
});
const [systemInfo, setSystemInfo] = useState(null);
+ const [usageStats, setUsageStats] = useState(null);
const [loading, setLoading] = useState(false);
+ const [activeView, setActiveView] = useState('tasks'); // 'tasks' | 'dashboard'
// Fetch tasks on component mount
useEffect(() => {
fetchTasks();
fetchSystemInfo();
+ fetchUsageStats();
const interval = setInterval(() => {
fetchTasks();
fetchSystemInfo();
- }, 5000); // Refresh every 5 seconds
+ fetchUsageStats();
+ }, 10000);
return () => clearInterval(interval);
}, []);
@@ -47,6 +51,16 @@ const App = () => {
}
};
+ const fetchUsageStats = async () => {
+ try {
+ const response = await fetch('/api/system/usage');
+ const data = await response.json();
+ setUsageStats(data);
+ } catch (error) {
+ console.error('Error fetching usage stats:', error);
+ }
+ };
+
const handleCreateTask = async (e) => {
e.preventDefault();
setLoading(true);
@@ -118,15 +132,121 @@ const App = () => {
Claude Persistent Agent
Scheduled task management & Claude Code runner
- {systemInfo && (
-
-
- {systemInfo.task_count} tasks
-
- )}
+
+
+ {systemInfo && (
+
+
+ {systemInfo.task_count} tasks Β· {systemInfo.total_runs || 0} runs
+
+ )}
+
+ {activeView === 'dashboard' && (
+
+
System Dashboard
+
+ {systemInfo && (
+ <>
+
+
π
+
{systemInfo.task_count}
+
Total Tasks
+
+
+
β
+
{systemInfo.completed_runs || 0}
+
Completed Runs
+
+
+
β
+
{systemInfo.failed_runs || 0}
+
Failed Runs
+
+
+
β‘
+
{systemInfo.running_runs || 0}
+
Currently Running
+
+
+
π
+
{systemInfo.total_runs || 0}
+
Total Runs Ever
+
+
+
{systemInfo.scheduler_running ? 'π’' : 'π΄'}
+
{systemInfo.scheduler_running ? 'Active' : 'Stopped'}
+
Scheduler
+
+ >
+ )}
+
+
+
+
Claude API Usage
+
+ {usageStats ? (
+ <>
+
+ Claude Runs (all time)
+ {usageStats.claude_runs_total ?? 'β'}
+
+
+ Active Sessions
+ {usageStats.session_count ?? 'β'}
+
+
+ First Run
+ {usageStats.first_run ? new Date(usageStats.first_run).toLocaleString() : 'β'}
+
+
+ Last Run
+ {usageStats.last_run ? new Date(usageStats.last_run).toLocaleString() : 'β'}
+
+
+ π Next Monthly Reset
+ {usageStats.next_reset ? new Date(usageStats.next_reset).toLocaleDateString() : 'β'}
+
+
+ β³ Days Until Reset
+ {usageStats.days_until_reset ?? 'β'}
+
+ {usageStats.note && (
+
{usageStats.note}
+ )}
+ >
+ ) : (
+
Loading usage statsβ¦
+ )}
+
+
+
+
+
Task Breakdown
+
+ {tasks.length === 0 ? (
+
No tasks yet. Create one in the Tasks view.
+ ) : (
+ tasks.map(t => (
+
+ {t.name}
+ {t.schedule_type}
+ {t.status}
+ {t.last_run ? new Date(t.last_run).toLocaleString() : 'never'}
+
+ ))
+ )}
+
+
+
+ )}
+
+ {activeView === 'tasks' && (
);