|
|
import React from 'react'; |
|
|
|
|
|
const TopicSelector = ({ |
|
|
onTopicsChange, |
|
|
availableTopics = [], |
|
|
selectedTopics = [], |
|
|
customTopics = [], |
|
|
onCustomTopicsChange, |
|
|
customSentence = '', |
|
|
onSentenceChange, |
|
|
multiTheme = true, |
|
|
onMultiThemeChange |
|
|
}) => { |
|
|
const handleTopicToggle = (topic) => { |
|
|
const newSelectedTopics = selectedTopics.includes(topic) |
|
|
? selectedTopics.filter(t => t !== topic) |
|
|
: [...selectedTopics, topic]; |
|
|
|
|
|
onTopicsChange(newSelectedTopics); |
|
|
}; |
|
|
|
|
|
const handleAddCustomTopic = () => { |
|
|
const newCustomTopics = [...customTopics, '']; |
|
|
onCustomTopicsChange && onCustomTopicsChange(newCustomTopics); |
|
|
}; |
|
|
|
|
|
const handleCustomTopicChange = (index, value) => { |
|
|
|
|
|
const spaceCount = (value.match(/ /g) || []).length; |
|
|
if (spaceCount > 2) { |
|
|
return; |
|
|
} |
|
|
|
|
|
const newCustomTopics = [...customTopics]; |
|
|
newCustomTopics[index] = value; |
|
|
onCustomTopicsChange && onCustomTopicsChange(newCustomTopics); |
|
|
}; |
|
|
|
|
|
const handleRemoveCustomTopic = (index) => { |
|
|
const newCustomTopics = customTopics.filter((_, i) => i !== index); |
|
|
onCustomTopicsChange && onCustomTopicsChange(newCustomTopics); |
|
|
}; |
|
|
|
|
|
return ( |
|
|
<div className="topic-selector"> |
|
|
<h3>Select Topics</h3> |
|
|
<div className="topic-buttons"> |
|
|
{availableTopics.map(topic => ( |
|
|
<button |
|
|
key={topic.id} |
|
|
className={`topic-btn ${selectedTopics.includes(topic.name) ? 'selected' : ''}`} |
|
|
onClick={() => handleTopicToggle(topic.name)} |
|
|
> |
|
|
{topic.name} |
|
|
</button> |
|
|
))} |
|
|
</div> |
|
|
|
|
|
{/* Custom Topics Section */} |
|
|
<div className="custom-topics-container"> |
|
|
<h3>Custom Topics</h3> |
|
|
<p className="custom-topics-description">Add your own topics (up to 3 words per box)</p> |
|
|
|
|
|
{customTopics.map((topic, index) => ( |
|
|
<div key={index} className="custom-topic-input-container"> |
|
|
<input |
|
|
type="text" |
|
|
value={topic} |
|
|
onChange={(e) => handleCustomTopicChange(index, e.target.value)} |
|
|
placeholder='Enter a custom topic... "climate change", "video game", "ice cream"' |
|
|
className="custom-topic-input" |
|
|
maxLength="30" |
|
|
/> |
|
|
<button |
|
|
type="button" |
|
|
onClick={() => handleRemoveCustomTopic(index)} |
|
|
className="remove-topic-btn" |
|
|
title="Remove topic" |
|
|
> |
|
|
✕ |
|
|
</button> |
|
|
</div> |
|
|
))} |
|
|
|
|
|
<button |
|
|
type="button" |
|
|
onClick={handleAddCustomTopic} |
|
|
className="add-topic-btn" |
|
|
> |
|
|
+ Add Custom Topic |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
<div className="sentence-input-container"> |
|
|
<label htmlFor="custom-sentence" className="sentence-label"> |
|
|
Custom Sentence (optional) |
|
|
</label> |
|
|
<textarea |
|
|
id="custom-sentence" |
|
|
className="sentence-input" |
|
|
value={customSentence} |
|
|
onChange={(e) => onSentenceChange && onSentenceChange(e.target.value)} |
|
|
placeholder='Enter a sentence to influence word selection... e.g., "india won the test series against england" or "Fresh ingredients make the perfect morning meal"' |
|
|
rows="3" |
|
|
maxLength="200" |
|
|
/> |
|
|
<div className="sentence-info"> |
|
|
<span className="char-count">{customSentence.length}/200 characters</span> |
|
|
{customSentence && ( |
|
|
<button |
|
|
type="button" |
|
|
className="clear-sentence-btn" |
|
|
onClick={() => onSentenceChange && onSentenceChange('')} |
|
|
title="Clear sentence" |
|
|
> |
|
|
Clear |
|
|
</button> |
|
|
)} |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div className="multi-theme-toggle-container"> |
|
|
<label className="multi-theme-toggle"> |
|
|
<input |
|
|
type="checkbox" |
|
|
checked={multiTheme} |
|
|
onChange={(e) => onMultiThemeChange && onMultiThemeChange(e.target.checked)} |
|
|
className="multi-theme-checkbox" |
|
|
/> |
|
|
<span className="multi-theme-label"> |
|
|
🎯 Use Multi-Theme Processing |
|
|
</span> |
|
|
</label> |
|
|
<p className="multi-theme-description"> |
|
|
{multiTheme |
|
|
? "AI will process each theme separately and balance results" |
|
|
: "AI will blend all themes into a single concept" |
|
|
} |
|
|
</p> |
|
|
</div> |
|
|
|
|
|
<p className="selected-count"> |
|
|
{selectedTopics.length + customTopics.filter(t => t.trim()).length} total topic{(selectedTopics.length + customTopics.filter(t => t.trim()).length) !== 1 ? 's' : ''} selected |
|
|
</p> |
|
|
</div> |
|
|
); |
|
|
}; |
|
|
|
|
|
export default TopicSelector; |
|
|
|