feat(cc-050): AI Activity Privacy page
This commit is contained in:
parent
bafc493961
commit
dbd93d0be2
1 changed files with 89 additions and 0 deletions
89
src/app/dashboard/privacy/ai-activity/page.tsx
Normal file
89
src/app/dashboard/privacy/ai-activity/page.tsx
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
import { apiFetch } from '../../../../lib/api';
|
||||||
|
import type { AiRequest } from '../../../../lib/api';
|
||||||
|
import { useSession } from '../../../../components/session-provider';
|
||||||
|
|
||||||
|
export default function AiActivityPrivacyPage() {
|
||||||
|
const { activeTenant } = useSession();
|
||||||
|
const tenantId = activeTenant?.tenantId ?? '';
|
||||||
|
|
||||||
|
const { data: requests = [], isLoading } = useQuery({
|
||||||
|
queryKey: ['ai-activity-privacy', tenantId],
|
||||||
|
queryFn: () => apiFetch<AiRequest[]>('/v1/ai-requests?limit=200', { tenantId }),
|
||||||
|
enabled: Boolean(tenantId),
|
||||||
|
staleTime: 30_000,
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="max-w-4xl space-y-6">
|
||||||
|
<div>
|
||||||
|
<h1 className="font-display text-2xl font-semibold text-ink">Activitate AI</h1>
|
||||||
|
<p className="mt-1 text-sm text-ink-faint">
|
||||||
|
Transparență completă asupra accesului AI la datele workspace-ului. Fiecare cerere este
|
||||||
|
identificată printr-un <span className="font-mono text-xs">context_manifest_hash</span>{' '}
|
||||||
|
unic ce atestă setul de date permis.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="card p-4">
|
||||||
|
<p className="text-xs text-ink-faint">
|
||||||
|
<span className="font-semibold text-ink">Notă privind confidențialitatea:</span> Conținutul
|
||||||
|
contextelor AI nu este reținut de platformă. Hash-ul contextului permite auditarea tipului
|
||||||
|
de date accesate fără a expune datele în sine.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{isLoading ? (
|
||||||
|
<p className="text-sm text-ink-faint">Se încarcă…</p>
|
||||||
|
) : requests.length === 0 ? (
|
||||||
|
<div className="card p-10 text-center">
|
||||||
|
<p className="text-[32px]">✓</p>
|
||||||
|
<p className="mt-2 text-sm font-medium text-ink">Nicio activitate AI înregistrată</p>
|
||||||
|
<p className="mt-1 text-xs text-ink-faint">AI-ul nu a accesat nicio dată din workspace.</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<ul className="space-y-2">
|
||||||
|
{requests.map((req) => (
|
||||||
|
<li key={req.id} className="card px-4 py-3">
|
||||||
|
<div className="flex items-start justify-between gap-4">
|
||||||
|
<div className="min-w-0 flex-1">
|
||||||
|
<p className="text-sm font-medium text-ink capitalize">
|
||||||
|
{req.purpose.replace(/_/g, ' ')}
|
||||||
|
</p>
|
||||||
|
<div className="mt-1.5 flex flex-wrap items-center gap-2">
|
||||||
|
<span className="rounded bg-paper-sunken px-1.5 py-0.5 font-mono text-[10px] text-ink-faint">
|
||||||
|
{req.actionClass}
|
||||||
|
</span>
|
||||||
|
<span className="font-mono text-[10px] text-ink-line">·</span>
|
||||||
|
<span className="font-mono text-[11px] text-ink-faint">{req.model}</span>
|
||||||
|
<span className="font-mono text-[10px] text-ink-line">·</span>
|
||||||
|
<span
|
||||||
|
title={`Context hash: ${req.contextManifestHash}`}
|
||||||
|
className="cursor-help font-mono text-[9px] text-ink-line"
|
||||||
|
>
|
||||||
|
#{req.contextManifestHash.slice(0, 12)}…
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="shrink-0 text-right">
|
||||||
|
<p className="text-[11px] text-ink-faint whitespace-nowrap">
|
||||||
|
{new Date(req.createdAt).toLocaleDateString('ro-RO', {
|
||||||
|
day: 'numeric', month: 'short', year: 'numeric',
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
<p className="text-[11px] text-ink-line">
|
||||||
|
{new Date(req.createdAt).toLocaleTimeString('ro-RO', {
|
||||||
|
hour: '2-digit', minute: '2-digit',
|
||||||
|
})}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue