Files
resolutionflow/frontend/src/components/dashboard/TeamSummary.tsx
chihlasm bd29f590a2 fix: set account_id on all Session constructors; fix 3 ESLint errors in CI
Backend: start_session, prepare_session, batch_launch_sessions all missing
account_id=current_user.account_id — Phase 1 NOT NULL constraint made these
500 in test suite (test_ratings.py fixture couldn't create sessions).

Frontend ESLint:
- TaskLane.tsx: suppress react-refresh/only-export-components for clearTaskState
- TeamSummary.tsx: init loading from isAccountOwner to avoid sync setState in effect
- ScriptBodyEditor.tsx: move lastValueRef.current assignment into useEffect

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-10 14:41:42 +00:00

70 lines
2.8 KiB
TypeScript

import { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { Users, AlertTriangle, Activity, ArrowRight } from 'lucide-react'
import { usePermissions } from '@/hooks/usePermissions'
import { aiSessionsApi } from '@/api/aiSessions'
import { Skeleton } from '@/components/ui/Skeleton'
export function TeamSummary() {
const { isAccountOwner } = usePermissions()
const navigate = useNavigate()
const [escalationCount, setEscalationCount] = useState(0)
const [loading, setLoading] = useState(!!isAccountOwner)
useEffect(() => {
if (!isAccountOwner) return
aiSessionsApi.getEscalationQueue()
.then((esc) => setEscalationCount(esc.length))
.catch(() => {})
.finally(() => setLoading(false))
}, [isAccountOwner])
if (!isAccountOwner) return null
const items = [
{ label: 'Escalations', value: escalationCount, icon: AlertTriangle, color: '#fbbf24', href: '/escalations' },
{ label: 'Team Activity', value: '\u2014', icon: Activity, color: '#60a5fa', href: '/analytics' },
{ label: 'Members', value: '\u2014', icon: Users, color: '#a78bfa', href: '/account' },
]
return (
<div className="card-flat">
<div
className="flex items-center justify-between px-5 py-3"
style={{ borderBottom: '1px solid var(--color-border-default)' }}
>
<h3 className="font-heading text-sm font-bold text-foreground">Team Summary</h3>
<button
onClick={() => navigate('/analytics')}
className="flex items-center gap-1 text-[0.6875rem] text-muted-foreground hover:text-foreground transition-colors"
>
Manage <ArrowRight size={10} />
</button>
</div>
<div className="p-4 space-y-3">
{loading ? Array.from({ length: 3 }).map((_, i) => (
<div key={i} className="flex items-center gap-3 px-3 py-2.5">
<Skeleton className="h-4 w-4 rounded shrink-0" />
<Skeleton className="h-4 flex-1 max-w-28" />
<Skeleton className="h-5 w-8" />
</div>
)) : items.map((item) => (
<button
key={item.label}
onClick={() => navigate(item.href)}
className="flex w-full items-center gap-3 rounded-lg px-3 py-2.5 hover:bg-[var(--color-bg-card-hover)] transition-colors group"
>
<item.icon size={15} style={{ color: item.color }} className="shrink-0" />
<span className="flex-1 text-left text-[0.8125rem] text-muted-foreground group-hover:text-foreground transition-colors">
{item.label}
</span>
<span className="font-heading text-lg font-bold text-foreground tabular-nums">
{item.value}
</span>
</button>
))}
</div>
</div>
)
}