/** * BoostMedia AI Content Generator Admin - Configure Step * * @package BoostMedia_AI * @license GPL-2.0-or-later */ import { useMemo } from 'react' import { ChevronLeft, ChevronRight } from 'lucide-react' import type { GenerationConfig } from './SelectPostTypeStep' import { Button, Card, HelpTooltip } from '../common' import { TagInput } from './TagInput' import { t, isRtl } from '../../lib/i18n' interface ConfigureStepProps { config: GenerationConfig onUpdate: (config: GenerationConfig) => void onBack: () => void onNext: () => void } const countPresets = [10, 50, 100, 500, 1000] const weekdayOptions = [ { value: 0, label: t('Sun') }, { value: 1, label: t('Mon') }, { value: 2, label: t('Tue') }, { value: 3, label: t('Wed') }, { value: 4, label: t('Thu') }, { value: 5, label: t('Fri') }, { value: 6, label: t('Sat') }, ] function ToggleSwitch({ checked, onChange, }: { checked: boolean onChange: () => void }) { return ( ) } export interface ConfigureContentProps { config: GenerationConfig onUpdate: (config: GenerationConfig) => void } export function ConfigureContent({ config, onUpdate, }: ConfigureContentProps) { const selectedTermCount = config.term ? config.term.split(',').filter(Boolean).length : 0 const hasMultipleCategories = selectedTermCount > 1 const lengthOptions = useMemo(() => [ { value: 'auto' as const, label: t('AI decides'), description: t('Based on samples') }, { value: 'short' as const, label: t('Short'), description: t('~300 words') }, { value: 'medium' as const, label: t('Medium'), description: t('~600 words') }, { value: 'long' as const, label: t('Long'), description: t('~1000 words') }, ], []) const repeatSummary = useMemo(() => { if (config.generationType !== 'repeating') { return '' } const unitLabel = config.repeatUnit === 'day' ? t(config.repeatEvery === 1 ? 'day' : 'days') : config.repeatUnit === 'month' ? t(config.repeatEvery === 1 ? 'month' : 'months') : t(config.repeatEvery === 1 ? 'week' : 'weeks') const weekdayLabel = config.repeatUnit === 'week' && config.repeatWeekdays.length > 0 ? ` • ${config.repeatWeekdays.map((weekday) => weekdayOptions.find((option) => option.value === weekday)?.label || weekday).join(', ')}` : '' const budgetParts = [ config.maxTotalRuns ? `${t('Up to')} ${config.maxTotalRuns} ${t(config.maxTotalRuns === 1 ? 'run' : 'runs')}` : '', config.maxTotalPosts ? `${t('Up to')} ${config.maxTotalPosts} ${t(config.maxTotalPosts === 1 ? 'post' : 'posts')}` : '', config.stopAfterMonths ? `${t('Stop after')} ${config.stopAfterMonths} ${t(config.stopAfterMonths === 1 ? 'month' : 'months')}` : '', ].filter(Boolean) return `${t('Every')} ${config.repeatEvery > 1 ? `${config.repeatEvery} ` : ''}${unitLabel}`.replace(/\s+/g, ' ').trim() + `${weekdayLabel} • ${String(config.repeatHour).padStart(2, '0')}:00` + (budgetParts.length > 0 ? ` • ${budgetParts.join(' • ')}` : '') }, [config.generationType, config.maxTotalPosts, config.maxTotalRuns, config.repeatEvery, config.repeatHour, config.repeatUnit, config.repeatWeekdays, config.stopAfterMonths]) const updateNullablePositiveNumber = ( key: 'stopAfterMonths' | 'maxTotalRuns' | 'maxTotalPosts', value: string, ) => { const normalized = value.trim() onUpdate({ ...config, [key]: normalized === '' ? null : Math.max(1, parseInt(normalized, 10) || 1), }) } return (

{t('Use a clear internal name so you can manage this plan later from the Content Plans dashboard.')}

onUpdate({ ...config, planName: e.target.value })} placeholder={t('e.g.: Fire pumps monthly blog plan')} className=" w-full p-3 rounded-bc border border-bc-gray-300 bg-white text-bc-gray-800 placeholder:text-bc-gray-400 focus:ring-2 focus:ring-bc-primary focus:border-bc-primary transition-all duration-200 " />

{t('Choose whether this plan runs once or keeps running automatically, and set its publishing behavior in the same place.')}

{[ { value: 'one_time' as const, label: t('One-time plan'), description: t('Run this plan manually whenever you choose'), }, { value: 'repeating' as const, label: t('Repeating plan'), description: t('Keep this plan active and let WordPress run it on a schedule'), }, ].map((option) => ( ))}
{config.generationType === 'repeating' ? (
onUpdate({ ...config, repeatEvery: Math.max(1, parseInt(e.target.value, 10) || 1) })} className="w-full rounded-bc border border-bc-gray-300 px-3 py-2" />
{config.repeatUnit === 'week' ? (
{weekdayOptions.map((weekday) => { const selected = config.repeatWeekdays.includes(weekday.value) return ( ) })}

{t('Leave all weekdays unselected to run on the same weekday cadence as the plan start date.')}

) : null}
updateNullablePositiveNumber('stopAfterMonths', e.target.value)} placeholder={t('Unlimited')} className="w-full rounded-bc border border-bc-gray-300 px-3 py-2" />
updateNullablePositiveNumber('maxTotalRuns', e.target.value)} placeholder={t('Unlimited')} className="w-full rounded-bc border border-bc-gray-300 px-3 py-2" /> {config.remainingRuns !== null ? (

{t('Remaining runs')}: {config.remainingRuns}

) : null}
updateNullablePositiveNumber('maxTotalPosts', e.target.value)} placeholder={t('Unlimited')} className="w-full rounded-bc border border-bc-gray-300 px-3 py-2" /> {config.remainingPosts !== null ? (

{t('Remaining posts')}: {config.remainingPosts}

) : null}
{t('Schedule summary')}

{repeatSummary}

) : (
{t('Run this plan manually whenever you choose')}
)}
{/* Topic — textarea */}

{t('Describe what the batch of posts should be about. Be as specific or general as you like — AI will understand.')}