import { useMemo, useState } from "react"; import { useSearchParams } from "react-router-dom"; import type { AuditEvent } from "@/api"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Textarea } from "@/components/ui/textarea"; type Props = { events: AuditEvent[]; onRefresh: () => Promise; }; export function AuditPage({ events, onRefresh }: Props) { const [searchParams] = useSearchParams(); const initialEventType = searchParams.get("event_type") || "all"; const initialOutcome = searchParams.get("outcome") || "all"; const initialNeedle = searchParams.get("q") || ""; const [eventType, setEventType] = useState(initialEventType); const [outcome, setOutcome] = useState(initialOutcome); const [needle, setNeedle] = useState(initialNeedle); const eventTypes = useMemo( () => [ "all", ...Array.from(new Set(events.map((e) => e.event_type))).sort(), ], [events], ); const outcomes = useMemo( () => ["all", ...Array.from(new Set(events.map((e) => e.outcome))).sort()], [events], ); const filtered = useMemo(() => { const q = needle.trim().toLowerCase(); return events.filter((e) => { if (eventType !== "all" && e.event_type !== eventType) return false; if (outcome !== "all" && e.outcome !== outcome) return false; if (!q) return true; return ( e.message.toLowerCase().includes(q) || e.event_type.toLowerCase().includes(q) || e.outcome.toLowerCase().includes(q) || e.request_id?.toLowerCase().includes(q) || // why does the one flow from devicespage use this (e.actor_id || "").toLowerCase().includes(q) || (e.agent_id || "").toLowerCase().includes(q) ); }); }, [events, eventType, outcome, needle]); return ( Recent Audit Events

Showing {filtered.length} of {events.length}