33import React , { FC , useState , useEffect } from "react" ;
44import {
55 Sparkles ,
6- Check ,
76 Plus ,
87 Edit ,
98 ThumbsUp ,
10- Settings
9+ Settings ,
10+ Check ,
11+ Minus
1112} from "lucide-react" ;
1213import { API_ENDPOINTS } from '../lib/config' ;
1314import { FaArrowLeft } from "react-icons/fa" ;
@@ -29,10 +30,8 @@ const AI_MODELS: AIModel[] = [
2930] ;
3031
3132interface TopicRefinerProps {
32- isLlmProcessing : boolean ;
3333 llmSuggestions : string [ ] ;
3434 setLlmSuggestions : ( suggestions : string [ ] ) => void ;
35- onRequestSuggestions : ( model : string , prompt : string , apiKey : string , topics : string [ ] ) => Promise < void > ;
3635 selectedTopics : string [ ] ;
3736 selectLlmSuggestion : ( suggestion : string ) => void ;
3837 newTopic : string ;
@@ -41,21 +40,21 @@ interface TopicRefinerProps {
4140 prevStep : ( ) => void ;
4241 handleSubmit : ( ) => void ;
4342 searchTerm : string ;
43+ removeLlmSuggestion : ( suggestion : string ) => void ;
4444}
4545
46- export const TopicRefiner : FC < TopicRefinerProps > = ( {
47- isLlmProcessing,
46+ export const TopicRefiner : FC < Omit < TopicRefinerProps , 'isLlmProcessing' > > = ( {
4847 llmSuggestions = [ ] ,
4948 setLlmSuggestions,
50- onRequestSuggestions,
5149 selectedTopics = [ ] ,
5250 selectLlmSuggestion,
5351 newTopic = "" ,
5452 setNewTopic,
5553 addNewTopic,
5654 prevStep,
5755 handleSubmit,
58- searchTerm
56+ searchTerm,
57+ removeLlmSuggestion
5958} ) => {
6059 const [ showPromptModal , setShowPromptModal ] = useState ( false ) ;
6160 const [ showWelcomeModal , setShowWelcomeModal ] = useState ( true ) ;
@@ -103,7 +102,7 @@ export const TopicRefiner: FC<TopicRefinerProps> = ({
103102 alert ( 'Failed to get AI suggestions.' ) ;
104103 }
105104 setShowPromptModal ( false ) ;
106- } catch ( error ) {
105+ } catch {
107106 alert ( 'Failed to get AI suggestions. Please try again.' ) ;
108107 }
109108 } ;
@@ -168,14 +167,14 @@ export const TopicRefiner: FC<TopicRefinerProps> = ({
168167 < p className = "text-muted mb-4" > Use AI suggestions to refine your topics or manually add/remove topics.</ p >
169168
170169 < div className = "row g-4" >
171- { /* LLM Suggestions */ }
170+ { /* Left column - Selected Topics */ }
172171 < div className = "col-md-6" >
173172 < div className = "card h-100" style = { { minHeight : 420 } } >
174173 < div className = "card-body" style = { { minHeight : 420 , maxHeight : 420 } } >
175174 < div className = "d-flex justify-content-between align-items-center mb-4" >
176175 < h3 className = "h5 mb-0 d-flex align-items-center" >
177176 < Sparkles className = "text-warning me-2" size = { 20 } />
178- AI Suggestions
177+ AI Suggested Topics
179178 </ h3 >
180179 < div className = "d-flex gap-2" >
181180 < button
@@ -188,84 +187,51 @@ export const TopicRefiner: FC<TopicRefinerProps> = ({
188187 </ button >
189188 </ div >
190189 </ div >
191- { /* Show selected topics first */ }
192- { selectedTopics . length > 0 && llmSuggestions . length === 0 && (
193- < div className = "d-flex flex-column h-100" style = { { minHeight : 250 , justifyContent : 'flex-start' } } >
194- < div className = "list-group w-100 mb-0" style = { { flex : 1 , overflowY : 'auto' , maxHeight : 300 , marginBottom : 0 , paddingBottom : 0 } } >
195- { selectedTopics . map ( ( topic ) => (
190+ < div className = "d-flex flex-column h-100" style = { { minHeight : 250 , justifyContent : 'flex-start' } } >
191+ < div className = "list-group w-100 mb-0" style = { { flex : 1 , overflowY : 'auto' , maxHeight : 300 , marginBottom : 0 , paddingBottom : 0 } } >
192+ { selectedTopics . map ( ( topic ) => {
193+ const isAI = llmSuggestions . includes ( topic ) ;
194+ return (
196195 < div key = { topic } className = "list-group-item d-flex justify-content-between align-items-center" >
197- < span > { topic } </ span >
198- < button
199- className = "btn btn-sm btn-outline-secondary"
200- disabled
201- >
202- < Check size = { 16 } />
203- </ button >
204- </ div >
205- ) ) }
206- </ div >
207- </ div >
208- ) }
209- { /* Show AI suggestions (excluding selected topics) */ }
210- { llmSuggestions . length > 0 ? (
211- < div >
212- < h6 className = "text-muted mb-2" > New Suggestions</ h6 >
213- < div className = "list-group" style = { { maxHeight : '200px' , overflowY : 'auto' } } >
214- { llmSuggestions
215- . filter ( suggestion => ! selectedTopics . includes ( suggestion ) )
216- . map ( ( suggestion ) => (
217- < div key = { suggestion } className = "list-group-item d-flex justify-content-between align-items-center" >
218- < span > { suggestion } </ span >
196+ < span >
197+ { topic }
198+ { isAI && < span className = "badge bg-info ms-2" > AI</ span > }
199+ </ span >
200+ { isAI ? (
201+ < button
202+ className = "btn btn-sm btn-outline-success"
203+ style = { { width : 32 , height : 32 , display : 'flex' , alignItems : 'center' , justifyContent : 'center' , padding : 0 } }
204+ disabled
205+ title = "Already added to AI suggestions"
206+ >
207+ < Check size = { 16 } />
208+ </ button >
209+ ) : (
219210 < button
220211 className = "btn btn-sm btn-outline-primary"
221- onClick = { ( ) => selectLlmSuggestion ( suggestion ) }
212+ onClick = { ( ) => selectLlmSuggestion ( topic ) }
213+ title = "Add to AI suggestions"
222214 >
223215 < Plus size = { 16 } />
224216 </ button >
225- </ div >
226- ) ) }
227- </ div >
228- </ div >
229- ) : (
230- < div className = "text-center py-5" >
231- { isLlmProcessing ? (
232- < p className = "text-primary" > Analyzing topics...</ p >
233- ) : null }
217+ ) }
218+ </ div >
219+ ) ;
220+ } ) }
234221 </ div >
235- ) }
222+ </ div >
236223 </ div >
237224 </ div >
238225 </ div >
239226
240- { /* Manual Topic Management */ }
227+ { /* Right column - AI Suggestions Reference */ }
241228 < div className = "col-md-6" >
242- < div className = "card h-100" style = { { minHeight : 180 } } >
243- < div className = "card-body" style = { { minHeight : 180 , maxHeight : 180 , overflowY : 'auto' } } >
229+ < div className = "card h-100" style = { { minHeight : 420 } } >
230+ < div className = "card-body" style = { { minHeight : 420 , maxHeight : 420 } } >
244231 < h3 className = "h5 mb-4 d-flex align-items-center" >
245232 < Edit size = { 20 } className = "text-primary me-2" />
246- Customize Topics
233+ User Finalized Topics
247234 </ h3 >
248-
249- { /* AI Suggestions (in right column) */ }
250- { llmSuggestions . length > 0 && (
251- < div className = "mb-4" >
252- < h6 className = "text-muted mb-2" > AI Suggestions (in right column)</ h6 >
253- < div className = "list-group" style = { { maxHeight : "200px" , overflowY : "auto" } } >
254- { llmSuggestions . filter ( suggestion => ! selectedTopics . includes ( suggestion ) ) . map ( ( suggestion ) => (
255- < div key = { suggestion } className = "list-group-item d-flex justify-content-between align-items-center" >
256- < span > { suggestion } </ span >
257- < button
258- className = "btn btn-sm btn-outline-primary"
259- onClick = { ( ) => selectLlmSuggestion ( suggestion ) }
260- >
261- < Plus size = { 16 } />
262- </ button >
263- </ div >
264- ) ) }
265- </ div >
266- </ div >
267- ) }
268-
269235 < div className = "mb-4" >
270236 < div className = "input-group" >
271237 < input
@@ -285,6 +251,28 @@ export const TopicRefiner: FC<TopicRefinerProps> = ({
285251 </ button >
286252 </ div >
287253 </ div >
254+ { llmSuggestions . length > 0 && (
255+ < div className = "mb-4" >
256+ < div className = "list-group" style = { { maxHeight : '250px' , overflowY : 'auto' } } >
257+ { llmSuggestions . map ( ( suggestion ) => (
258+ < div key = { suggestion } className = "list-group-item d-flex justify-content-between align-items-center" >
259+ < span className = "d-flex align-items-center" >
260+ { suggestion }
261+ < span className = "badge bg-info ms-2" > AI</ span >
262+ </ span >
263+ < button
264+ className = "btn btn-sm btn-outline-danger ms-2"
265+ style = { { width : 32 , height : 32 , display : 'flex' , alignItems : 'center' , justifyContent : 'center' , padding : 0 } }
266+ onClick = { ( ) => removeLlmSuggestion ( suggestion ) }
267+ title = "Remove from finalized topics"
268+ >
269+ < Minus size = { 16 } />
270+ </ button >
271+ </ div >
272+ ) ) }
273+ </ div >
274+ </ div >
275+ ) }
288276 </ div >
289277 </ div >
290278 </ div >
0 commit comments