import React, { useState } from 'react'; import { __ } from '@wordpress/i18n'; import { api } from '../api'; import { Button, Badge, Notice } from './ui'; import { IconSparkle } from './icons'; /** * "Let the AI propose the keywords." * * Typing keywords into an empty box is the step where most people stall: they * know their business, not which phrasings a search engine sees. The engine is * already connected for meta descriptions and FAQs, and it has the whole site * to read, so it can propose terms grounded in what this site actually * publishes rather than generic head terms. * * Suggestions are never applied silently — each one is a chip the user picks. * An AI that fills a tracking list by itself is an AI that quietly spends a * SERP credit per day per keyword it invented. * * @param {object} props * @param {number} [props.postId] Narrow suggestions to one page. * @param {Function} props.onPick Called with the chosen keyword string. * @param {string[]} [props.taken] Keywords already in use, shown as done. * @param {string} [props.label] Button wording. */ export default function KeywordSuggest({ postId = 0, group = 'shorttail', onPick, taken = [], label }) { const [busy, setBusy] = useState(false); const [items, setItems] = useState(null); const [error, setError] = useState(null); const [used, setUsed] = useState([]); const lower = taken.map((t) => String(t).toLowerCase()); const suggest = async () => { setBusy(true); setError(null); try { const payload = await api.post('/ai/keywords', { group, ...(postId ? { post_id: postId } : {}) }); setItems(payload.keywords || []); } catch (e) { setError(e.message); } finally { setBusy(false); } }; const pick = (keyword) => { setUsed((prev) => [...prev, keyword.toLowerCase()]); onPick(keyword); }; return (
{items && items.length > 0 && ( {__('Pick the ones worth tracking.', 'ai-rank-suite')} )}
{error && {error}} {items && items.length === 0 && ( {__('The engine returned no usable suggestions. Try again, or add a keyword by hand.', 'ai-rank-suite')} )} {items && items.length > 0 && (
{items.map((item) => { const done = used.includes(item.keyword.toLowerCase()) || lower.includes(item.keyword.toLowerCase()); return ( ); })}
)}
); }