Repository Public
1'use client';2import { useState } from 'react';3import { useWaits } from '@/lib/queries';4import { FilterChips } from '@/components/ui/chips';5import { EmptyState, ErrorState, Skeleton } from '@/components/ui/misc';6import { IllusAllClear } from '@/components/ui/illustrations';7import { WaitCard } from '@/components/waits/wait-card';89type Filter = 'all' | 'approval' | 'question';1011export default function ApprovalsPage() {12 const q = useWaits();13 const [filter, setFilter] = useState<Filter>('all');14 const all = q.data ?? [];15 const list = all.filter((w) => filter === 'all' || w.kind === filter);16 const n = (k: Filter) => all.filter((w) => k === 'all' || w.kind === k).length;17 return (18 <div className="h-full overflow-y-auto" data-testid="approvals-page">19 <div className="mx-auto flex w-full max-w-3xl flex-col gap-4 px-4 pb-32 pt-1 md:px-8 md:pb-12 md:pt-6">20 <div className="hidden md:block">21 <h1 className="text-xl font-bold tracking-tight">Approvals</h1>22 <p className="text-[13px] text-text-2">Agents are suspended on these requests. Nothing here runs until you decide; an expired request counts as a denial.</p>23 </div>24 {all.length > 0 && (25 <FilterChips label="Kind" value={filter} onChange={setFilter} options={[{ id: 'all', label: 'All', count: n('all') }, { id: 'approval', label: 'Approvals', count: n('approval') }, { id: 'question', label: 'Questions', count: n('question') }]} />26 )}27 {q.isError ? (28 <div className="card"><ErrorState error={q.error} onRetry={() => q.refetch()} /></div>29 ) : q.isPending ? (30 <><Skeleton className="h-44 rounded-md" /><Skeleton className="h-44 rounded-md" /></>31 ) : list.length === 0 ? (32 <div className="card" data-testid="approvals-empty">33 <EmptyState34 illustration={<IllusAllClear />}35 title={all.length === 0 ? 'Inbox zero' : 'Nothing of this kind'}36 description={all.length === 0 ? 'No agent is waiting for you. Requests for sensitive actions and questions land here, oldest first.' : 'Switch the filter to see the other requests.'}37 />38 </div>39 ) : (40 <ol className="flex flex-col gap-4" data-testid="approvals-list">41 {list.map((w) => (42 <li key={w.id}><WaitCard wait={w} /></li>43 ))}44 </ol>45 )}46 </div>47 </div>48 );49}50