Skip to content

Commit 426a4e3

Browse files
committed
DOC
1 parent 912abe8 commit 426a4e3

File tree

1 file changed

+69
-92
lines changed

1 file changed

+69
-92
lines changed

src/components/DashboardViews/DocumentsView.tsx

Lines changed: 69 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,10 @@ export default function DocumentsView({ isDark = true }: { isDark?: boolean }) {
6767
const [chunks, setChunks] = useState<DocumentChunk[]>([]);
6868
const [loadingChunks, setLoadingChunks] = useState(false);
6969
const [processingProgress, setProcessingProgress] = useState<ProcessingProgress | null>(null);
70-
const [isDragging, setIsDragging] = useState(false);
70+
const [textTitle, setTextTitle] = useState('');
71+
const [textContent, setTextContent] = useState('');
7172
const [deleteConfirmId, setDeleteConfirmId] = useState<string | null>(null);
7273

73-
const fileInputRef = useRef<HTMLInputElement>(null);
74-
7574
const kbId = knowledgeBase?.id || user?.id || '';
7675

7776
// ─── Load documents ───────────────────────────────────────
@@ -91,15 +90,16 @@ export default function DocumentsView({ isDark = true }: { isDark?: boolean }) {
9190
loadDocuments();
9291
}, [loadDocuments]);
9392

94-
// ─── Upload handler ───────────────────────────────────────
95-
const handleUpload = useCallback(async (file: File) => {
93+
// ─── Direct Text Submission ───────────────────────────────────────
94+
const handleSubmitText = useCallback(async () => {
9695
if (!user?.id || !kbId) return;
97-
98-
if (file.size > MAX_FILE_SIZE) {
99-
alert(`File too large. Maximum size is ${formatBytes(MAX_FILE_SIZE)}.`);
96+
if (!textTitle.trim() || !textContent.trim()) {
97+
alert('Please provide both a title and text content.');
10098
return;
10199
}
102100

101+
const syntheticFile = new File([textContent], `${textTitle.trim()}.txt`, { type: 'text/plain' });
102+
103103
setProcessingProgress({
104104
stage: 'uploading',
105105
current: 0,
@@ -108,42 +108,20 @@ export default function DocumentsView({ isDark = true }: { isDark?: boolean }) {
108108
});
109109

110110
const result = await ragService.processDocument(
111-
file,
111+
syntheticFile,
112112
kbId,
113113
user.id,
114114
(progress) => setProcessingProgress(progress),
115115
);
116116

117117
if (result) {
118-
// Refresh list
118+
setTextTitle('');
119+
setTextContent('');
119120
await loadDocuments();
120121
}
121122

122-
// Clear progress after a delay
123123
setTimeout(() => setProcessingProgress(null), 3000);
124-
}, [user?.id, kbId, loadDocuments]);
125-
126-
const handleFileSelect = (e: React.ChangeEvent<HTMLInputElement>) => {
127-
const file = e.target.files?.[0];
128-
if (file) handleUpload(file);
129-
e.target.value = '';
130-
};
131-
132-
// ─── Drag & drop ──────────────────────────────────────────
133-
const handleDragOver = (e: React.DragEvent) => {
134-
e.preventDefault();
135-
setIsDragging(true);
136-
};
137-
const handleDragLeave = (e: React.DragEvent) => {
138-
e.preventDefault();
139-
setIsDragging(false);
140-
};
141-
const handleDrop = (e: React.DragEvent) => {
142-
e.preventDefault();
143-
setIsDragging(false);
144-
const file = e.dataTransfer.files?.[0];
145-
if (file) handleUpload(file);
146-
};
124+
}, [user?.id, kbId, textTitle, textContent, loadDocuments]);
147125

148126
// ─── Expand / view chunks ─────────────────────────────────
149127
const toggleExpand = async (docId: string) => {
@@ -192,47 +170,13 @@ export default function DocumentsView({ isDark = true }: { isDark?: boolean }) {
192170
{t('kbDocs.description')}
193171
</p>
194172
</div>
195-
<button
196-
onClick={() => fileInputRef.current?.click()}
197-
disabled={!!processingProgress && processingProgress.stage !== 'done' && processingProgress.stage !== 'error'}
198-
className={cn(
199-
"inline-flex items-center gap-2 px-4 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 cursor-pointer border shadow-sm",
200-
"bg-gradient-to-r from-[#FF8A5B] via-[#FF9E6C] to-[#FFB286] text-white border-[#FF8A5B]/30",
201-
"hover:from-[#FF9E6C] hover:via-[#FF8A5B] hover:to-[#FFB286] hover:shadow-md hover:-translate-y-0.5",
202-
"disabled:opacity-50 disabled:pointer-events-none"
203-
)}
204-
>
205-
<Upload className="w-4 h-4" />
206-
{t('kbDocs.upload')}
207-
</button>
208-
<input
209-
ref={fileInputRef}
210-
type="file"
211-
accept={ACCEPTED_TYPES}
212-
className="hidden"
213-
onChange={handleFileSelect}
214-
/>
215173
</div>
216174

217-
{/* Drop Zone */}
218-
<div
219-
onDragOver={handleDragOver}
220-
onDragLeave={handleDragLeave}
221-
onDrop={handleDrop}
222-
onClick={() => {
223-
if (!processingProgress || processingProgress.stage === 'done' || processingProgress.stage === 'error') {
224-
fileInputRef.current?.click();
225-
}
226-
}}
227-
className={cn(
228-
"relative rounded-xl border-2 border-dashed p-8 transition-all duration-200 cursor-pointer",
229-
isDragging
230-
? "border-[#FF8A5B] bg-[#FF8A5B]/10 scale-[1.01]"
231-
: isDark
232-
? "border-white/10 hover:border-white/20 bg-white/[0.02] hover:bg-white/[0.04] backdrop-blur-sm"
233-
: "border-gray-200 hover:border-gray-300 bg-gray-50/50 hover:bg-gray-50",
234-
)}
235-
>
175+
{/* Text Input Zone */}
176+
<div className={cn(
177+
"relative rounded-xl border p-6 transition-all duration-200",
178+
isDark ? "bg-white/5 border-white/10" : "bg-white border-gray-200 shadow-sm"
179+
)}>
236180
{/* Processing Progress Overlay */}
237181
{processingProgress && processingProgress.stage !== 'done' && processingProgress.stage !== 'error' && (
238182
<div className="absolute inset-0 rounded-xl bg-black/50 backdrop-blur-sm flex items-center justify-center z-10">
@@ -276,22 +220,55 @@ export default function DocumentsView({ isDark = true }: { isDark?: boolean }) {
276220
</div>
277221
)}
278222

279-
<div className="flex flex-col items-center gap-3">
280-
<div className={cn(
281-
"w-14 h-14 rounded-2xl flex items-center justify-center border",
282-
isDark
283-
? "bg-white/5 border-white/10"
284-
: "bg-gray-100 border-gray-200"
285-
)}>
286-
<UploadCloud className={cn("w-7 h-7", isDark ? "text-white/40" : "text-gray-400")} />
223+
<div className="space-y-4">
224+
<div>
225+
<label className={cn("block text-sm font-medium mb-1.5", textPrimary)}>
226+
Document Title
227+
</label>
228+
<input
229+
type="text"
230+
placeholder="e.g. Employee Handbook"
231+
value={textTitle}
232+
onChange={(e) => setTextTitle(e.target.value)}
233+
className={cn(
234+
"w-full rounded-lg px-4 py-2 border text-sm outline-none transition-all",
235+
isDark
236+
? "bg-black/20 border-white/10 text-white placeholder:text-white/30 focus:border-[#FF8A5B]/50"
237+
: "bg-gray-50 border-gray-200 text-gray-900 placeholder:text-gray-400 focus:border-[#FF8A5B]"
238+
)}
239+
/>
240+
</div>
241+
<div>
242+
<label className={cn("block text-sm font-medium mb-1.5", textPrimary)}>
243+
Content
244+
</label>
245+
<textarea
246+
placeholder="Paste your text content here..."
247+
rows={6}
248+
value={textContent}
249+
onChange={(e) => setTextContent(e.target.value)}
250+
className={cn(
251+
"w-full rounded-lg px-4 py-3 border text-sm outline-none transition-all resize-y min-h-[120px]",
252+
isDark
253+
? "bg-black/20 border-white/10 text-white placeholder:text-white/30 focus:border-[#FF8A5B]/50"
254+
: "bg-gray-50 border-gray-200 text-gray-900 placeholder:text-gray-400 focus:border-[#FF8A5B]"
255+
)}
256+
/>
287257
</div>
288-
<div className="text-center">
289-
<p className={cn("text-sm font-medium", textPrimary)}>
290-
{t('kbDocs.dropzone')}
291-
</p>
292-
<p className={cn("text-xs mt-1", textMuted)}>
293-
PDF, TXT, MD, CSV, DOCX &middot; Max {formatBytes(MAX_FILE_SIZE)}
294-
</p>
258+
<div className="flex justify-end pt-2">
259+
<button
260+
onClick={handleSubmitText}
261+
disabled={!textTitle.trim() || !textContent.trim() || !!processingProgress}
262+
className={cn(
263+
"inline-flex items-center gap-2 px-5 py-2.5 rounded-xl text-sm font-semibold transition-all duration-200 cursor-pointer border shadow-sm",
264+
"bg-gradient-to-r from-[#FF8A5B] via-[#FF9E6C] to-[#FFB286] text-white border-[#FF8A5B]/30",
265+
"hover:from-[#FF9E6C] hover:via-[#FF8A5B] hover:to-[#FFB286] hover:shadow-md hover:-translate-y-0.5",
266+
"disabled:opacity-50 disabled:pointer-events-none"
267+
)}
268+
>
269+
<FileText className="w-4 h-4" />
270+
Save to Knowledge Base
271+
</button>
295272
</div>
296273
</div>
297274
</div>
@@ -488,12 +465,12 @@ export default function DocumentsView({ isDark = true }: { isDark?: boolean }) {
488465
{chunks.map((chunk, idx) => (
489466
<div
490467
key={chunk.id}
491-
className={cn(
492-
"rounded-lg border p-3 transition-colors",
493-
isDark
468+
className={cn(
469+
"rounded-lg border p-3 transition-colors",
470+
isDark
494471
? "bg-white/[0.03] border-white/10 hover:bg-white/[0.05]"
495472
: "bg-white border-gray-200 hover:bg-gray-50"
496-
)}
473+
)}
497474
>
498475
<div className="flex items-start gap-3">
499476
<span className={cn(

0 commit comments

Comments
 (0)