import { useEffect, useState } from 'react'; import { __ } from '../lib/i18n'; /** * "Include in llms.txt" drawer section (adoption §2.1 parity note / FB-5). * * Mirrors the Gutenberg panel toggle inside the Pages/Products drawers. * Reads/writes the `_llmagnet_exclude_from_llms` meta through the thin * `llm-analytics/v1/post-llms-inclusion` endpoint (products are not under * wp/v2, so core meta REST is not usable here). Saves immediately on * toggle — independent of the drawer's main Save flow. */ export function LlmsIncludeToggle({ postId, apiRoot, apiNamespace, }: { postId: number; apiRoot: string; apiNamespace: string; }) { const [excluded, setExcluded] = useState(null); const [isSaving, setIsSaving] = useState(false); const [error, setError] = useState(null); const endpoint = `${apiRoot}${apiNamespace}/post-llms-inclusion`; const nonce = (window as any).wpApiSettings?.nonce || ''; useEffect(() => { let cancelled = false; setExcluded(null); setError(null); fetch(`${endpoint}?post_id=${postId}`, { headers: { 'X-WP-Nonce': nonce }, credentials: 'same-origin', }) .then((res) => (res.ok ? res.json() : Promise.reject(new Error(`HTTP ${res.status}`)))) .then((data) => { if (!cancelled && data?.success) { setExcluded(!!data.excluded); } }) .catch(() => { // Endpoint unavailable (e.g. older backend) — hide the control // instead of showing a broken toggle. if (!cancelled) setExcluded(null); }); return () => { cancelled = true; }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [postId]); if (excluded === null) { return null; } const included = !excluded; const handleToggle = async () => { const nextExcluded = included; // flipping setIsSaving(true); setError(null); const prev = excluded; setExcluded(nextExcluded); // optimistic try { const res = await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': nonce, }, credentials: 'same-origin', body: JSON.stringify({ post_id: postId, excluded: nextExcluded }), }); const data = await res.json(); if (!res.ok || !data?.success) { throw new Error(data?.error || `HTTP ${res.status}`); } setExcluded(!!data.excluded); } catch (err: any) { setExcluded(prev); setError(err?.message || __('Failed to save', 'llmagnet-llm-txt-generator')); } finally { setIsSaving(false); } }; return (

{__('llms.txt', 'llmagnet-llm-txt-generator')}

{error && (
{error}
)}
i {__('When off, this content is left out of llms.txt, llms-full.txt and the markdown docs. Changes apply to the export files right away.', 'llmagnet-llm-txt-generator')}
); }