diff --git a/src/app/api/documents/import-url/route.ts b/src/app/api/documents/import-url/route.ts index e66dc43..62e4df1 100644 --- a/src/app/api/documents/import-url/route.ts +++ b/src/app/api/documents/import-url/route.ts @@ -2,7 +2,6 @@ import { NextRequest, NextResponse } from 'next/server'; import { requireAuthContext } from '@/lib/server/auth/auth'; import { fetchAndParseUrl } from '@/lib/server/documents/web-loader'; import { errorToLog, serverLogger } from '@/lib/server/logger'; -import { errorResponse } from '@/lib/server/errors/next-response'; export const dynamic = 'force-dynamic'; diff --git a/src/components/SettingsModal.tsx b/src/components/SettingsModal.tsx index 5ccc55d..f4a0b89 100644 --- a/src/components/SettingsModal.tsx +++ b/src/components/SettingsModal.tsx @@ -42,7 +42,7 @@ import { flushUserPreferencesSync } from '@/lib/client/api/user-state'; import toast from 'react-hot-toast'; import { useLibraryDocumentsQuery } from '@/hooks/useLibraryDocumentsQuery'; import { - SidebarNav, + SidebarDialog, SidebarNavItem, SegmentedControl, Button, @@ -50,8 +50,6 @@ import { IconButton, Input, Textarea, - ModalFrame, - ModalTitle, Select, } from '@/components/ui'; import ReactMarkdown from 'react-markdown'; @@ -562,90 +560,55 @@ export function SettingsModal({ return ( <> - + Settings + + + } + headerRight={ + + } + showCloseButton={false} + sections={visibleSections} + activeSectionId={activeSection} + onSectionChange={setActiveSection} + className="h-[490px]" + contentClassName={ + activeSection === 'admin' + ? 'bg-[radial-gradient(circle_at_top_right,color-mix(in_srgb,var(--accent),transparent_92%),transparent_35%)]' + : '' + } + customContent={ + isChangelogOpen ? ( + setIsChangelogOpen(false)} + /> + ) : undefined + } > - {/* Header */} -
-
- Settings - -
-
- -
-
- - {isChangelogOpen ? ( - setIsChangelogOpen(false)} - /> - ) : ( - <> - {/* Mobile nav */} - - {visibleSections.map((section) => { - const Icon = section.icon; - return ( - setActiveSection(section.id)} - active={activeSection === section.id} - icon={} - label={section.label} - /> - ); - })} - - -
- {/* Desktop: vertical sidebar */} - - - {/* Content */} -
{/* API Section */} {activeSection === 'api' && (
@@ -1174,11 +1137,7 @@ export function SettingsModal({
)} -
- - - )} -
+ setIsUploadDialogOpen(true)} - icon={} - label="Upload documents" /> )} bottomSlot={( diff --git a/src/components/documents/DocumentUploader.tsx b/src/components/documents/DocumentUploader.tsx index ffa1b27..21950d6 100644 --- a/src/components/documents/DocumentUploader.tsx +++ b/src/components/documents/DocumentUploader.tsx @@ -12,6 +12,7 @@ interface DocumentUploaderProps { variant?: 'default' | 'compact' | 'overlay'; children?: ReactNode; onUploadBatchChange?: (state: UploadBatchState) => void; + onClick?: () => void; } export interface UploadBatchState { @@ -28,6 +29,7 @@ export function DocumentUploader({ variant = 'default', children, onUploadBatchChange, + onClick, }: DocumentUploaderProps) { const uploaderId = useId(); const enableDocx = useFeatureFlag('enableDocxConversion'); @@ -88,8 +90,8 @@ export function DocumentUploader({ }, multiple: true, disabled: isUploading, - noClick: variant === 'overlay', - noKeyboard: variant === 'overlay' + noClick: variant === 'overlay' || !!onClick, + noKeyboard: variant === 'overlay' || !!onClick }); const isDisabled = isUploading; @@ -132,6 +134,12 @@ export function DocumentUploader({ return (
{ + if (onClick) { + e.stopPropagation(); + onClick(); + } + }} className={dropzoneSurfaceClass({ variant: variant === 'compact' ? 'compact' : 'default', active: isDragActive, diff --git a/src/components/documents/UploadMenuDialog.tsx b/src/components/documents/UploadMenuDialog.tsx index da492f1..760f755 100644 --- a/src/components/documents/UploadMenuDialog.tsx +++ b/src/components/documents/UploadMenuDialog.tsx @@ -5,10 +5,7 @@ import toast from 'react-hot-toast'; import { useDocuments } from '@/contexts/DocumentContext'; import { importUrl } from '@/lib/client/api/documents'; import { - ModalFrame, - ModalTitle, - SidebarNav, - SidebarNavItem, + SidebarDialog, SegmentedControl, Input, Textarea, @@ -163,285 +160,233 @@ export function UploadMenuDialog({ }; return ( - -
- {/* Header */} -
- Add Documents - + + {/* TAB 1: File Uploader */} + {activeTab === 'file' && ( +
+

+ Select files from your computer or drag and drop them anywhere. Supported formats include PDF, EPUB, TXT, and MD. +

+ { + onUploadBatchChange?.(state); + // Automatically close modal when files successfully start uploading + if (state.isActive) { + onClose(); + } + }} + />
+ )} - {/* Mobile Navigation (Horizontal row of items) */} - - {SIDEBAR_SECTIONS.map((section) => { - const Icon = section.icon; - return ( - handleTabChange(section.id)} - active={activeTab === section.id} - icon={} - label={section.label} + {/* TAB 2: Create Custom Document */} + {activeTab === 'create' && ( +
+
+
+
+ setDocName(e.target.value)} + placeholder="Document title (e.g. notes)" + className="w-full font-medium" + controlSize="md" + disabled={isCreatingDoc} + /> +
+
+ + ariaLabel="Document format selection" + value={docExtension} + options={[ + { value: '.md', label: 'Markdown (.md)' }, + { value: '.txt', label: 'Plain Text (.txt)' }, + ]} + onChange={setDocExtension} + className="grid-cols-2" + /> +
+
+ +
+