import { defineWidget } from "@rezi-ui/core";
import { applyFilters, addEntry } from "@rezi-ui/core";
import type { LogEntry, LogLevel } from "@rezi-ui/core";
const ApiMonitor = defineWidget((ctx) => {
const [entries, setEntries] = ctx.useState<LogEntry[]>([]);
const [levelFilter, setLevelFilter] = ctx.useState<readonly LogLevel[]>([]);
const [sourceFilter, setSourceFilter] = ctx.useState<readonly string[]>([]);
const [searchQuery, setSearchQuery] = ctx.useState("");
const [scrollTop, setScrollTop] = ctx.useState(0);
// Simulate API calls
ctx.useEffect(() => {
const simulateApiCall = () => {
const sources = ["auth", "users", "posts", "comments"];
const source = sources[Math.floor(Math.random() * sources.length)];
const success = Math.random() > 0.1;
const entry: LogEntry = {
id: `api-${Date.now()}-${Math.random()}`,
timestamp: Date.now(),
level: success ? "info" : "error",
source: source ?? "unknown",
message: success
? `${source} request completed`
: `${source} request failed`,
durationMs: Math.floor(Math.random() * 1000),
details: success ? undefined : "Error: Connection timeout",
};
setEntries((prev) => addEntry(prev, entry));
};
const interval = setInterval(simulateApiCall, 500);
return () => clearInterval(interval);
}, []);
const filtered = applyFilters(entries, levelFilter, sourceFilter, searchQuery);
return ui.column({ gap: 1 }, [
ui.row({ gap: 1 }, [
ui.text("API Monitor", { variant: "heading" }),
ui.spacer({ flex: 1 }),
ui.text(`${entries.length} total`),
]),
ui.row({ gap: 1 }, [
ui.input({
id: "search",
value: searchQuery,
placeholder: "Search...",
onInput: setSearchQuery,
}),
ui.button({
id: "errors-only",
label: "Errors",
onPress: () => setLevelFilter(["error"]),
}),
ui.button({
id: "clear-filters",
label: "Clear",
onPress: () => {
setLevelFilter([]);
setSourceFilter([]);
setSearchQuery("");
},
}),
]),
ui.logsConsole({
id: "api-logs",
entries: filtered,
autoScroll: true,
scrollTop,
showTimestamps: true,
showSource: true,
onScroll: setScrollTop,
onClear: () => setEntries([]),
}),
]);
});