first commit

This commit is contained in:
2026-07-09 22:51:03 +02:00
commit fac491134d
50 changed files with 7547 additions and 0 deletions
+69
View File
@@ -0,0 +1,69 @@
import { useEffect, useMemo, useState } from "react";
import { api, type ServerRecord, type TaskRecord } from "../api/client";
import FilterBar, { type Filters } from "../components/FilterBar";
import ServerGroup from "../components/ServerGroup";
export default function Dashboard() {
const [servers, setServers] = useState<ServerRecord[]>([]);
const [tasks, setTasks] = useState<TaskRecord[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [filters, setFilters] = useState<Filters>({
serverId: undefined,
scheduleType: undefined,
search: "",
includeStale: false,
});
useEffect(() => {
api.servers
.list()
.then((res) => setServers(res.servers))
.catch((err) => setError(String(err)));
}, []);
useEffect(() => {
setLoading(true);
const handle = setTimeout(() => {
api.tasks
.list(filters)
.then((res) => {
setTasks(res.tasks);
setError(null);
})
.catch((err) => setError(String(err)))
.finally(() => setLoading(false));
}, 200);
return () => clearTimeout(handle);
}, [filters]);
const groups = useMemo(() => {
const byServer = new Map<number, { serverId: number; serverName: string; tasks: TaskRecord[] }>();
for (const task of tasks) {
const entry = byServer.get(task.serverId) ?? {
serverId: task.serverId,
serverName: task.serverName,
tasks: [],
};
entry.tasks.push(task);
byServer.set(task.serverId, entry);
}
return [...byServer.values()];
}, [tasks]);
return (
<div className="dashboard">
<FilterBar servers={servers} filters={filters} onChange={setFilters} />
{error && <div className="error-banner">{error}</div>}
{loading && <div className="loading-inline">Loading tasks</div>}
{!loading && groups.length === 0 && (
<div className="empty-state">
No scheduled tasks found yet. Add a server under "Servers" and install the agent to start reporting.
</div>
)}
{groups.map((group) => (
<ServerGroup key={group.serverId} serverName={group.serverName} tasks={group.tasks} />
))}
</div>
);
}