import { useEffect, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import { askQuestion } from "../api/standards"; import "./StandardModal.css"; export default function StandardModal({ standard, onClose }) { const { t } = useTranslation(); const modalRef = useRef(null); const closeBtnRef = useRef(null); const inputRef = useRef(null); const [question, setQuestion] = useState(""); const [messages, setMessages] = useState([]); const [asking, setAsking] = useState(false); const [aiError, setAiError] = useState(null); const chatEndRef = useRef(null); useEffect(() => { closeBtnRef.current?.focus(); const onKey = (e) => e.key === "Escape" && onClose(); document.addEventListener("keydown", onKey); document.body.style.overflow = "hidden"; return () => { document.removeEventListener("keydown", onKey); document.body.style.overflow = ""; }; }, [onClose]); useEffect(() => { chatEndRef.current?.scrollIntoView({ behavior: "smooth" }); }, [messages, asking]); const handleBackdrop = (e) => { if (e.target === e.currentTarget) onClose(); }; const handleAsk = async (e) => { e.preventDefault(); const q = question.trim(); if (!q || asking) return; setMessages((prev) => [...prev, { role: "user", text: q }]); setQuestion(""); setAsking(true); setAiError(null); try { const { answer } = await askQuestion({ standard_id: standard.standard_id, question: q }); setMessages((prev) => [...prev, { role: "ai", text: answer }]); } catch (err) { setAiError(err.message || t("common.serverError")); } finally { setAsking(false); setTimeout(() => inputRef.current?.focus(), 50); } }; if (!standard) return null; const sections = Object.entries(standard.key_sections || {}); return (
{/* Header */}
{standard.category} {standard.standard_id}
{/* Standard detail */}
{standard.summary && ( )} {standard.keywords?.length > 0 && (

{t("modal.keywords")}

{standard.keywords.map((kw) => ( {kw} ))}
)} {sections.length > 0 && (

{t("modal.keySections")}

{sections.map(([name, text]) => (

{name}

{text}

))}
)} {/* AI chat panel */}

{t("modal.askAI")}

{messages.length > 0 && (
{messages.map((m, i) => (

{m.text}

))} {asking && (
)} {aiError && (

{aiError}

)}
)} {messages.length === 0 && !asking && (
{getSuggestions(standard, t).map((s) => ( ))}
)}
setQuestion(e.target.value)} placeholder={t("modal.chatPlaceholder")} maxLength={500} disabled={asking} aria-label={t("modal.questionLabel")} />
); } function getSuggestions(standard, t) { const base = [ t("modal.suggestion_keyReq", { id: standard.standard_id }), t("modal.suggestion_materials"), t("modal.suggestion_delivery"), ]; if (standard.key_sections?.["Chemical Requirements"]) { base.splice(1, 0, t("modal.suggestion_chemical")); } if (standard.key_sections?.["Physical Requirements"] || standard.key_sections?.["Physical Requirement"]) { base.splice(1, 0, t("modal.suggestion_physical")); } return base.slice(0, 3); }