"use client"; import { useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { ExternalLink, KeyRound, Loader2 } from "lucide-react"; import Modal from "@/components/common/Modal"; import { getPageIndexConfig, updatePageIndexConfig, type PageIndexConfig, } from "@/lib/knowledge-api"; const DEFAULT_BASE_URL = "https://api.pageindex.ai"; interface PageIndexSettingsModalProps { isOpen: boolean; onClose: () => void; /** Called after a successful save so callers can refresh provider state. */ onSaved?: () => void; } export default function PageIndexSettingsModal({ isOpen, onClose, onSaved, }: PageIndexSettingsModalProps) { const { t } = useTranslation(); const [config, setConfig] = useState(null); const [apiKey, setApiKey] = useState(""); const [baseUrl, setBaseUrl] = useState(""); const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [error, setError] = useState(null); useEffect(() => { if (!isOpen) return; let cancelled = false; setLoading(true); setError(null); setApiKey(""); getPageIndexConfig({ force: true }) .then((cfg) => { if (cancelled) return; setConfig(cfg); setBaseUrl(cfg.api_base_url || ""); }) .catch((err) => { if (!cancelled) setError(err instanceof Error ? err.message : String(err)); }) .finally(() => { if (!cancelled) setLoading(false); }); return () => { cancelled = true; }; }, [isOpen]); const persist = async (payload: { api_key?: string; api_base_url?: string; }) => { setSaving(true); setError(null); try { const next = await updatePageIndexConfig(payload); setConfig(next); setApiKey(""); onSaved?.(); return next; } catch (err) { setError(err instanceof Error ? err.message : String(err)); return null; } finally { setSaving(false); } }; const handleSave = async () => { // Blank key keeps the stored one; a typed value replaces it. const payload: { api_key?: string; api_base_url?: string } = { api_base_url: baseUrl.trim() || undefined, }; if (apiKey.trim()) payload.api_key = apiKey.trim(); const next = await persist(payload); if (next) onClose(); }; const keySet = config?.api_key_set ?? false; return ( {} : onClose} title={t("PageIndex settings")} titleIcon={} width="md" closeOnBackdrop={!saving} closeOnEscape={!saving} footer={
{t("Get an API key")}
} >

{t( "PageIndex is a hosted, vectorless retrieval engine. Documents in a PageIndex knowledge base are uploaded to PageIndex's servers for processing. One key is shared by all your PageIndex knowledge bases.", )}

{loading ? (
) : ( <>
setApiKey(event.target.value)} disabled={saving} placeholder={ keySet ? t("•••••••• (configured — leave blank to keep)") : t("Enter your PageIndex API key") } className="w-full rounded-lg border border-[var(--border)] bg-[var(--background)] px-3 py-2 text-[13px] text-[var(--foreground)] outline-none transition-colors focus:border-[var(--foreground)]/25 disabled:opacity-50" /> {keySet && ( )}
setBaseUrl(event.target.value)} disabled={saving} placeholder={DEFAULT_BASE_URL} className="w-full rounded-lg border border-[var(--border)] bg-[var(--background)] px-3 py-2 text-[13px] text-[var(--foreground)] outline-none transition-colors focus:border-[var(--foreground)]/25 disabled:opacity-50" />
)} {error && (
{error}
)}
); }