'use client'; import { useState } from 'react'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { apiFetch } from '../../../../lib/api'; import { useSession } from '../../../../components/session-provider'; interface Observation { id: string; subjectType: string; subjectId: string; metric: string; value: string; unit: string | null; source: string; confidence: number | null; observedAt: string | null; createdAt: string; } interface ResearchBrief { id: string; title: string; organizationName: string | null; summary: string | null; briefType: string | null; createdAt: string; } const SUBJECT_TYPES = ['all','organization','goal','decision','contact','project','market','custom']; export default function InsightsPage() { const { activeTenant } = useSession(); const tenantId = activeTenant?.tenantId ?? ''; const qc = useQueryClient(); const [tab, setTab] = useState<'observations' | 'briefs'>('observations'); const [subjectFilter, setSubjectFilter] = useState('all'); const [showCreate, setShowCreate] = useState(false); const [form, setForm] = useState({ subjectType: 'organization', subjectId: '', metric: '', value: '', unit: '', source: 'analyst', confidence: '0.8' }); const { data: observations = [], isLoading: obsLoading } = useQuery({ queryKey: ['observations', tenantId, subjectFilter], queryFn: () => { const params = subjectFilter !== 'all' ? `?subjectType=${subjectFilter}` : ''; return apiFetch(`/v1/observations${params}`, { tenantId }); }, enabled: Boolean(tenantId), staleTime: 30_000, }); const { data: briefs = [], isLoading: briefsLoading } = useQuery({ queryKey: ['briefs', tenantId], queryFn: () => apiFetch('/v1/research-briefs?limit=100', { tenantId }), enabled: Boolean(tenantId), staleTime: 60_000, }); const createMut = useMutation({ mutationFn: (body: Record) => apiFetch('/v1/observations', { tenantId, method: 'POST', body }), onSuccess: () => { qc.invalidateQueries({ queryKey: ['observations', tenantId] }); setShowCreate(false); setForm({ subjectType: 'organization', subjectId: '', metric: '', value: '', unit: '', source: 'analyst', confidence: '0.8' }); }, }); // Group observations by metric const byMetric: Record = {}; for (const o of observations) { byMetric[o.metric] = [...(byMetric[o.metric] ?? []), o]; } const topMetrics = Object.entries(byMetric) .sort(([, a], [, b]) => b.length - a.length) .slice(0, 6); return (

Insights

{observations.length} observații · {briefs.length} research briefs

{tab === 'observations' && ( )}
{/* Tabs */}
{[['observations', 'Observații'], ['briefs', 'Research Briefs']].map(([key, label]) => ( ))}
{tab === 'observations' && ( <> {/* Top metrics overview */} {topMetrics.length > 0 && (
{topMetrics.map(([metric, items]) => ( ))}
)} {/* Subject type filter */}
{SUBJECT_TYPES.map((t) => ( ))}
{/* Create form */} {showCreate && (

Observație nouă

setForm({ ...form, subjectId: e.target.value })} className="rounded-lg border bg-card px-3 py-2 text-sm text-ink focus:outline-none focus:ring-2 focus:ring-ring" /> setForm({ ...form, metric: e.target.value })} className="rounded-lg border bg-card px-3 py-2 text-sm text-ink focus:outline-none focus:ring-2 focus:ring-ring" /> setForm({ ...form, value: e.target.value })} className="rounded-lg border bg-card px-3 py-2 text-sm text-ink focus:outline-none focus:ring-2 focus:ring-ring" /> setForm({ ...form, unit: e.target.value })} className="rounded-lg border bg-card px-3 py-2 text-sm text-ink focus:outline-none focus:ring-2 focus:ring-ring" />
setForm({ ...form, confidence: e.target.value })} className="flex-1" /> {Math.round(parseFloat(form.confidence)*100)}%
)} {/* Observations list */} {obsLoading ? (
Se încarcă…
) : observations.length === 0 ? (

📊

Nicio observație înregistrată.

) : (
{observations.slice(0, 50).map((o) => (
{o.metric} {o.value}{o.unit ? ` ${o.unit}` : ''} {o.confidence != null && ( {Math.round(o.confidence*100)}% conf )}

{o.subjectType}:{o.subjectId.slice(0, 12)}… · {o.source}

{new Date(o.observedAt ?? o.createdAt).toLocaleDateString('ro-RO')}
))} {observations.length > 50 && (

și alte {observations.length - 50} observații…

)}
)} )} {tab === 'briefs' && ( <> {briefsLoading ? (
Se încarcă…
) : briefs.length === 0 ? (

📋

Niciun research brief.

) : (
{briefs.map((b) => (

{b.title}

{b.organizationName &&

🏢 {b.organizationName}

} {b.summary &&

{b.summary}

}

{new Date(b.createdAt).toLocaleDateString('ro-RO')}

))}
)} )}
); }