Skip to content

Commit 8c7d577

Browse files
committed
modify the topicrefiner
1 parent 578f4b9 commit 8c7d577

2 files changed

Lines changed: 258 additions & 163 deletions

File tree

src/components/TopicRefiner.tsx

Lines changed: 167 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
"use client"
22

3-
import React, { FC, useState } from "react";
3+
import React, { FC, useState, useEffect } from "react";
44
import {
55
Sparkles,
66
Check,
77
Plus,
8-
AlertCircle,
98
Edit,
10-
X,
119
ThumbsUp,
1210
Settings
1311
} from "lucide-react";
1412
import { API_ENDPOINTS } from '../lib/config';
13+
import { FaArrowLeft } from "react-icons/fa";
1514

1615
interface AIModel {
1716
id: string;
@@ -47,9 +46,9 @@ interface TopicRefinerProps {
4746
newTopic: string;
4847
setNewTopic: (topic: string) => void;
4948
addNewTopic: () => void;
50-
removeTopic: (topic: string) => void;
5149
prevStep: () => void;
5250
handleSubmit: () => void;
51+
searchTerm: string;
5352
}
5453

5554
export const TopicRefiner: FC<TopicRefinerProps> = ({
@@ -62,23 +61,32 @@ export const TopicRefiner: FC<TopicRefinerProps> = ({
6261
newTopic = "",
6362
setNewTopic,
6463
addNewTopic,
65-
removeTopic,
6664
prevStep,
67-
handleSubmit
65+
handleSubmit,
66+
searchTerm
6867
}) => {
6968
const [showPromptModal, setShowPromptModal] = useState(false);
69+
const [showWelcomeModal, setShowWelcomeModal] = useState(true);
7070
const [customPrompt, setCustomPrompt] = useState(
7171
"Please analyze these topics and suggest related or more specific topics that might be relevant."
7272
);
7373
const [selectedModel, setSelectedModel] = useState('gpt-4');
7474
const [apiKey, setApiKey] = useState('');
7575

76+
useEffect(() => {
77+
// Disable scroll on mount
78+
document.body.style.overflow = "hidden";
79+
return () => {
80+
// Restore scroll on unmount
81+
document.body.style.overflow = "";
82+
};
83+
}, []);
84+
7685
const handleGetSuggestions = async () => {
7786
if (!apiKey) {
7887
alert('Please enter an API key');
7988
return;
8089
}
81-
8290
if (selectedTopics.length === 0) {
8391
alert('Please select at least one topic before requesting suggestions');
8492
return;
@@ -87,48 +95,91 @@ export const TopicRefiner: FC<TopicRefinerProps> = ({
8795
try {
8896
const response = await fetch(API_ENDPOINTS.AI_PROCESS, {
8997
method: 'POST',
90-
headers: {
91-
'Content-Type': 'application/json',
92-
'Authorization': `Bearer ${apiKey}`
93-
},
98+
headers: { 'Content-Type': 'application/json' },
9499
body: JSON.stringify({
95-
model: selectedModel,
96-
prompt: customPrompt,
97-
topics: selectedTopics
100+
selectedModel,
101+
customPrompt,
102+
apiKey,
103+
searchTerm,
104+
selectedTopics
98105
})
99106
});
100-
101-
if (!response.ok) {
102-
throw new Error(`HTTP error! status: ${response.status}`);
103-
}
104-
105107
const data = await response.json();
106-
107-
if (data.suggestions) {
108-
setLlmSuggestions(data.suggestions);
109-
}
110-
111-
if (showPromptModal) {
112-
setShowPromptModal(false);
108+
if (data.success && data.result) {
109+
setLlmSuggestions(data.result);
110+
} else {
111+
alert('Failed to get AI suggestions.');
113112
}
113+
setShowPromptModal(false);
114114
} catch (error) {
115-
console.error('Error getting suggestions:', error);
116-
alert("Failed to get AI suggestions. Please try again.");
115+
alert('Failed to get AI suggestions. Please try again.');
117116
}
118117
};
119118

120119
return (
121-
<>
122-
<div className="card shadow-sm">
120+
<main className="container-fluid py-4" style={{ height: '100vh', overflowY: 'auto' }}>
121+
{/* Navigation/Header Row */}
122+
<div className="mx-auto" style={{ maxWidth: '90%' }}>
123+
<div className="d-flex align-items-center justify-content-between mb-4">
124+
{/* Left side with back button and titles */}
125+
<div className="d-flex align-items-center">
126+
<button
127+
className="btn btn-outline-secondary me-3"
128+
style={{ borderRadius: '50%', width: '40px', height: '40px', padding: 0 }}
129+
onClick={() => {
130+
if (showWelcomeModal) {
131+
setShowWelcomeModal(false);
132+
} else {
133+
prevStep();
134+
}
135+
}}
136+
>
137+
<FaArrowLeft />
138+
</button>
139+
<div>
140+
<h1 className="mb-0">Topic-Centric Filtering</h1>
141+
<h2 className="h5 text-muted mb-0 mt-1">Refine Your Topics</h2>
142+
</div>
143+
</div>
144+
{/* Right side with step indicator */}
145+
<div className="d-flex align-items-center gap-4">
146+
<div className="d-flex align-items-center gap-2 position-relative">
147+
<div
148+
className={"rounded-circle d-flex align-items-center justify-content-center text-dark bg-primary text-white"}
149+
style={{ width: "32px", height: "32px", zIndex: 1 }}
150+
>
151+
1
152+
</div>
153+
<div
154+
style={{
155+
width: "40px",
156+
height: "2px",
157+
backgroundColor: "#0d6efd",
158+
transition: "background-color 0.3s ease"
159+
}}
160+
/>
161+
<div
162+
className={"rounded-circle d-flex align-items-center justify-content-center text-dark bg-primary text-white"}
163+
style={{ width: "32px", height: "32px", zIndex: 1 }}
164+
>
165+
2
166+
</div>
167+
</div>
168+
<div className="text-muted">
169+
Step 2 of 2
170+
</div>
171+
</div>
172+
</div>
173+
</div>
174+
<div className="card shadow-sm mx-auto" style={{ maxWidth: '90%' }}>
123175
<div className="card-body">
124-
{/* <h2 className="card-title mb-3">Refine Your Topics</h2> */}
125176
<p className="text-muted mb-4">Use AI suggestions to refine your topics or manually add/remove topics.</p>
126177

127178
<div className="row g-4">
128179
{/* LLM Suggestions */}
129180
<div className="col-md-6">
130-
<div className="card h-100">
131-
<div className="card-body">
181+
<div className="card h-100" style={{ minHeight: 420 }}>
182+
<div className="card-body" style={{ minHeight: 420, maxHeight: 420 }}>
132183
<div className="d-flex justify-content-between align-items-center mb-4">
133184
<h3 className="h5 mb-0 d-flex align-items-center">
134185
<Sparkles className="text-warning me-2" size={20} />
@@ -145,36 +196,49 @@ export const TopicRefiner: FC<TopicRefinerProps> = ({
145196
</button>
146197
</div>
147198
</div>
148-
149-
{llmSuggestions.length > 0 ? (
150-
<div className="list-group" style={{ maxHeight: '400px', overflowY: 'auto' }}>
151-
{llmSuggestions.map((suggestion) => (
152-
<div key={suggestion} className="list-group-item d-flex justify-content-between align-items-center">
153-
<span>{suggestion}</span>
154-
<button
155-
className={`btn btn-sm ${selectedTopics.includes(suggestion) ? 'btn-success' : 'btn-outline-primary'}`}
156-
onClick={() => selectLlmSuggestion(suggestion)}
157-
disabled={selectedTopics.includes(suggestion)}
158-
>
159-
{selectedTopics.includes(suggestion) ? (
199+
{/* Show selected topics first */}
200+
{selectedTopics.length > 0 && llmSuggestions.length === 0 && (
201+
<div className="d-flex flex-column h-100" style={{ minHeight: 250, justifyContent: 'flex-start' }}>
202+
<div className="list-group w-100 mb-0" style={{ flex: 1, overflowY: 'auto', maxHeight: 300, marginBottom: 0, paddingBottom: 0 }}>
203+
{selectedTopics.map((topic) => (
204+
<div key={topic} className="list-group-item d-flex justify-content-between align-items-center">
205+
<span>{topic}</span>
206+
<button
207+
className="btn btn-sm btn-outline-secondary"
208+
disabled
209+
>
160210
<Check size={16} />
161-
) : (
162-
<Plus size={16} />
163-
)}
164-
</button>
165-
</div>
166-
))}
211+
</button>
212+
</div>
213+
))}
214+
</div>
215+
</div>
216+
)}
217+
{/* Show AI suggestions (excluding selected topics) */}
218+
{llmSuggestions.length > 0 ? (
219+
<div>
220+
<h6 className="text-muted mb-2">New Suggestions</h6>
221+
<div className="list-group" style={{ maxHeight: '200px', overflowY: 'auto' }}>
222+
{llmSuggestions
223+
.filter(suggestion => !selectedTopics.includes(suggestion))
224+
.map((suggestion) => (
225+
<div key={suggestion} className="list-group-item d-flex justify-content-between align-items-center">
226+
<span>{suggestion}</span>
227+
<button
228+
className="btn btn-sm btn-outline-primary"
229+
onClick={() => selectLlmSuggestion(suggestion)}
230+
>
231+
<Plus size={16} />
232+
</button>
233+
</div>
234+
))}
235+
</div>
167236
</div>
168237
) : (
169-
<div className="text-center text-muted py-5">
238+
<div className="text-center py-5">
170239
{isLlmProcessing ? (
171240
<p className="text-primary">Analyzing topics...</p>
172-
) : (
173-
<>
174-
<AlertCircle size={32} className="mb-3" />
175-
<p>Configure AI settings to receive suggestions</p>
176-
</>
177-
)}
241+
) : null}
178242
</div>
179243
)}
180244
</div>
@@ -183,8 +247,8 @@ export const TopicRefiner: FC<TopicRefinerProps> = ({
183247

184248
{/* Manual Topic Management */}
185249
<div className="col-md-6">
186-
<div className="card h-100">
187-
<div className="card-body">
250+
<div className="card h-100" style={{ minHeight: 180 }}>
251+
<div className="card-body" style={{ minHeight: 180, maxHeight: 180, overflowY: 'auto' }}>
188252
<h3 className="h5 mb-4 d-flex align-items-center">
189253
<Edit size={20} className="text-primary me-2" />
190254
Customize Topics
@@ -209,38 +273,12 @@ export const TopicRefiner: FC<TopicRefinerProps> = ({
209273
</button>
210274
</div>
211275
</div>
212-
213-
<div>
214-
<h4 className="h6 mb-3">Selected Topics ({selectedTopics.length})</h4>
215-
<div className="list-group" style={{ maxHeight: '400px', overflowY: 'auto' }}>
216-
{selectedTopics.length > 0 ? (
217-
selectedTopics.map((topic) => (
218-
<div key={topic} className="list-group-item d-flex justify-content-between align-items-center">
219-
<span>{topic}</span>
220-
<button
221-
className="btn btn-sm btn-outline-danger"
222-
onClick={() => removeTopic(topic)}
223-
>
224-
<X size={16} />
225-
</button>
226-
</div>
227-
))
228-
) : (
229-
<p className="text-muted text-center py-4 fst-italic">
230-
No topics selected yet.
231-
</p>
232-
)}
233-
</div>
234-
</div>
235276
</div>
236277
</div>
237278
</div>
238279
</div>
239280

240-
<div className="d-flex justify-content-between mt-4">
241-
<button className="btn btn-outline-secondary" onClick={prevStep}>
242-
Back
243-
</button>
281+
<div className="d-flex justify-content-end mt-4">
244282
<button
245283
className="btn btn-success d-flex align-items-center"
246284
onClick={handleSubmit}
@@ -253,6 +291,47 @@ export const TopicRefiner: FC<TopicRefinerProps> = ({
253291
</div>
254292
</div>
255293

294+
{/* Welcome Modal */}
295+
{showWelcomeModal && (
296+
<div className="modal show d-block" tabIndex={-1} role="dialog" style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
297+
<div className="modal-dialog modal-dialog-centered">
298+
<div className="modal-content">
299+
<div className="modal-header">
300+
<h5 className="modal-title d-flex align-items-center">
301+
<Sparkles className="text-warning me-2" size={20} />
302+
Welcome to Topic Refinement
303+
</h5>
304+
<button
305+
type="button"
306+
className="btn-close"
307+
onClick={() => setShowWelcomeModal(false)}
308+
aria-label="Close"
309+
></button>
310+
</div>
311+
<div className="modal-body">
312+
<div className="alert alert-info mb-0">
313+
<p className="mb-0">
314+
Your selected topics have been loaded. Please use AI to further refine them with your search term: <span className="badge bg-primary" style={{ fontSize: '1rem' }}>{searchTerm}</span>
315+
</p>
316+
</div>
317+
</div>
318+
<div className="modal-footer">
319+
{/* <button
320+
type="button"
321+
className="btn btn-primary"
322+
onClick={() => {
323+
setShowWelcomeModal(false);
324+
setShowPromptModal(true);
325+
}}
326+
>
327+
Configure AI Settings
328+
</button> */}
329+
</div>
330+
</div>
331+
</div>
332+
</div>
333+
)}
334+
256335
{/* Prompt Customization Modal */}
257336
{showPromptModal && (
258337
<div className="modal show d-block" tabIndex={-1} role="dialog" style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}>
@@ -368,6 +447,6 @@ export const TopicRefiner: FC<TopicRefinerProps> = ({
368447
</div>
369448
</div>
370449
)}
371-
</>
450+
</main>
372451
);
373452
};

0 commit comments

Comments
 (0)