/** * @file FileViewer.tsx * @description Read-only file-content modal for the config explorer. Takes * already-fetched data as props (path/data/error) rather than fetching * itself, so it stays tool-agnostic — the orchestrator (Claude or Codex * config page) owns the fetch. A markdown file gets a Raw / Preview switch * (`MarkdownPreview`); Raw is the default. * @author Nguyễn Ngọc Trí Vĩ */ import { useRef, useState } from "react"; import { useDialog } from "../../hooks/useDialog"; import { useTranslation } from "react-i18next"; import { FileText, X, AlertCircle, Eye, Code2 } from "lucide-react"; import type { CcFileResponse } from "../../lib/api"; import { CopyButton } from "./configPrimitives"; import { MarkdownPreview, isMarkdown } from "../MarkdownPreview"; export function FileViewer({ state, onClose, }: { state: { path: string; data: CcFileResponse | null; error: string | null }; onClose: () => void; }) { const { t } = useTranslation("ccConfig"); const [preview, setPreview] = useState(false); const canPreview = isMarkdown(state.path) && !!state.data; const panelRef = useRef(null); useDialog(true, panelRef, onClose); return (
e.stopPropagation()} >
{state.path} {canPreview && ( )}
{state.error ? (
{state.error}
) : !state.data ? (
…
) : preview && canPreview ? ( <> {state.data.truncated && (

{t("common.truncated")}

)} ) : (
              {state.data.text}
              {state.data.truncated && (
                
                  {"\n\n"}
                  {t("common.truncated")}
                
              )}
            
)}
); }