import React, { useMemo, useState, useEffect } from 'react';
import { Download, Edit2, Check, X, User } from 'lucide-react';
/**
* Read-only modal that surfaces the orchestrator-generated Credential
* Summary - the per-participant assessment of expertise, debating
* style, credibility on this question, and biases to watch.
*
* Built concurrently during Phase 1 (as each initial opinion lands).
* Rebuilt only if a participant's backing LLM model changes. The modal
* pulls a fresh snapshot via GET
* /api/chat/{id}/credentials each time it's opened, so the user sees
* the latest version regardless of when they peek.
*
* Layout mirrors ChatTableView (overlay + card + close button) for
* consistency with the existing transparency surfaces.
*/
export default function CredentialSummaryModal({
isOpen,
data,
onClose,
onRefresh,
humanParticipantId,
onEditHumanCredential,
}) {
// Hooks must run on every render, so the filename memo lives ABOVE
// the early return. The dependency on `isOpen` regenerates the
// timestamp each time the modal opens (matches PromptCatalogModal).
const filename = useMemo(() => {
const now = new Date();
const pad = (n) => String(n).padStart(2, '0');
return (
'ccai-credentials-'
+ `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`
+ `-${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`
+ '.txt'
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isOpen]);
if (!isOpen) return null;
const credentials = (data && data.credentials) || [];
const question = data?.question || '';
const handleDownload = () => {
if (!credentials.length) return;
const txt = renderCredentialsAsText(question, credentials);
const blob = new Blob([txt], { type: 'text/plain;charset=utf-8' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = filename;
a.click();
URL.revokeObjectURL(url);
};
return (
Credential Summary
The orchestrator's neutral assessment of each participant.
Built during Phase 1; updated only if a participant's model changes.
{onRefresh && (
)}
{question && (
Question:
{question}
)}
{credentials.length === 0 ? (
No Credential Summary has been generated yet. The
orchestrator builds it after Phase 1 (initial opinions).