diff --git a/src/app/capture/page.tsx b/src/app/capture/page.tsx index c88626a..e4a3954 100644 --- a/src/app/capture/page.tsx +++ b/src/app/capture/page.tsx @@ -52,7 +52,7 @@ function CaptureForm() { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ - text: `rec: ${title || url}\n\n${fullContent}`, + text: `web: ${title || url}\n\n${fullContent}`, }), }) diff --git a/src/components/bookmarklet-instructions.tsx b/src/components/bookmarklet-instructions.tsx index d813902..86b700d 100644 --- a/src/components/bookmarklet-instructions.tsx +++ b/src/components/bookmarklet-instructions.tsx @@ -44,13 +44,16 @@ export function BookmarkletInstructions() { return ( - {isOpen && ( -
setIsOpen(true)}> - -
+ {!isOpen && ( + )} diff --git a/src/components/header.tsx b/src/components/header.tsx index 648f926..064130f 100644 --- a/src/components/header.tsx +++ b/src/components/header.tsx @@ -1,16 +1,30 @@ 'use client' -import { useState } from 'react' +import { useState, useEffect } from 'react' import Link from 'next/link' import { usePathname } from 'next/navigation' import { Button } from '@/components/ui/button' import { Plus, FileText, Settings, Menu, X } from 'lucide-react' import { QuickAdd } from '@/components/quick-add' import { WorkModeToggle } from '@/components/work-mode-toggle' +import { BookmarkletInstructions } from '@/components/bookmarklet-instructions' +import { isWorkModeEnabled } from '@/lib/preferences' export function Header() { const pathname = usePathname() const [mobileMenuOpen, setMobileMenuOpen] = useState(false) + const [workModeToggleVisible, setWorkModeToggleVisible] = useState(true) + + useEffect(() => { + setWorkModeToggleVisible(isWorkModeEnabled()) + + const handlePreferencesChange = () => { + setWorkModeToggleVisible(isWorkModeEnabled()) + } + + window.addEventListener('preferences-updated', handlePreferencesChange) + return () => window.removeEventListener('preferences-updated', handlePreferencesChange) + }, []) return (
@@ -44,7 +58,8 @@ export function Header() {
- + + {workModeToggleVisible && } + + {workModeToggleVisible && ( +
+ Modo trabajo + +
+ )}
)} diff --git a/src/components/preferences-panel.tsx b/src/components/preferences-panel.tsx index 22355c6..f22c39d 100644 --- a/src/components/preferences-panel.tsx +++ b/src/components/preferences-panel.tsx @@ -5,6 +5,7 @@ import { FeatureFlags, getFeatureFlags, setFeatureFlags } from '@/lib/preference import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Badge } from '@/components/ui/badge' +import { BookmarkletInstructions } from '@/components/bookmarklet-instructions' export function PreferencesPanel() { const [flags, setFlags] = useState({ @@ -27,6 +28,8 @@ export function PreferencesPanel() { const handleWorkModeEnabled = (enabled: boolean) => { setFeatureFlags({ workModeEnabled: enabled }) setFlags(getFeatureFlags()) + // Dispatch custom event to notify other components (like Header) + window.dispatchEvent(new CustomEvent('preferences-updated')) } const handleRetentionChange = (value: string) => { @@ -97,10 +100,13 @@ export function PreferencesPanel() {
-
+

Integración externa

+ +
+ +
Sprint MVP-5 v0.1.0 -
diff --git a/src/components/quick-add.tsx b/src/components/quick-add.tsx index 6c248ee..3de4cb0 100644 --- a/src/components/quick-add.tsx +++ b/src/components/quick-add.tsx @@ -5,8 +5,9 @@ import { useRouter } from 'next/navigation' import { toast } from 'sonner' import { Input } from '@/components/ui/input' import { Textarea } from '@/components/ui/textarea' +import { Button } from '@/components/ui/button' import { cn } from '@/lib/utils' -import { Plus, Loader2, Text, Sparkles, X } from 'lucide-react' +import { Plus, Loader2, Sparkles, X, Text, ChevronDown } from 'lucide-react' import { inferNoteType, formatContentForType } from '@/lib/type-inference' import { NoteType } from '@/types/note' @@ -30,12 +31,13 @@ const TYPE_LABELS: Record = { export function QuickAdd() { const [value, setValue] = useState('') const [isLoading, setIsLoading] = useState(false) - const [isExpanded, setIsExpanded] = useState(false) + const [isOpen, setIsOpen] = useState(false) const [isMultiline, setIsMultiline] = useState(false) const [typeSuggestion, setTypeSuggestion] = useState(null) const [dismissedSuggestion, setDismissedSuggestion] = useState(false) const inputRef = useRef(null) const textareaRef = useRef(null) + const popupRef = useRef(null) const router = useRouter() const detectContentType = useCallback((text: string) => { @@ -58,7 +60,6 @@ export function QuickAdd() { }, [dismissedSuggestion]) const handlePaste = (e: React.ClipboardEvent) => { - // Let the paste happen first setDismissedSuggestion(false) setTimeout(() => { detectContentType(value) @@ -70,7 +71,7 @@ export function QuickAdd() { setValue(typeSuggestion.formattedContent) setTypeSuggestion(null) setIsMultiline(true) - setIsExpanded(true) + setIsOpen(true) } } @@ -101,7 +102,8 @@ export function QuickAdd() { description: note.title, }) setValue('') - setIsExpanded(false) + setIsOpen(false) + setIsMultiline(false) router.refresh() } catch (error) { toast.error('Error', { @@ -119,7 +121,7 @@ export function QuickAdd() { } if (e.key === 'Escape') { setValue('') - setIsExpanded(false) + setIsOpen(false) setIsMultiline(false) inputRef.current?.blur() textareaRef.current?.blur() @@ -129,25 +131,39 @@ export function QuickAdd() { const toggleMultiline = () => { setIsMultiline(!isMultiline) if (!isMultiline) { - setIsExpanded(true) setTimeout(() => textareaRef.current?.focus(), 0) } } + const handleInputFocus = () => { + setIsOpen(true) + } + + // Close popup when clicking outside + useEffect(() => { + const handleClickOutside = (e: MouseEvent) => { + if (popupRef.current && !popupRef.current.contains(e.target as Node)) { + setIsOpen(false) + } + } + if (isOpen) { + document.addEventListener('mousedown', handleClickOutside) + } + return () => document.removeEventListener('mousedown', handleClickOutside) + }, [isOpen]) + // Focus on keyboard shortcut useEffect(() => { const handleGlobalKeyDown = (e: KeyboardEvent) => { - // Ctrl+N or Cmd+N to focus quick add if ((e.key === 'n' && (e.metaKey || e.ctrlKey)) || (e.key === 'n' && e.altKey)) { e.preventDefault() inputRef.current?.focus() inputRef.current?.select() - setIsExpanded(true) + setIsOpen(true) } - // Escape to blur if (e.key === 'Escape' && document.activeElement === inputRef.current) { inputRef.current?.blur() - setIsExpanded(false) + setIsOpen(false) } } window.addEventListener('keydown', handleGlobalKeyDown) @@ -155,115 +171,128 @@ export function QuickAdd() { }, []) return ( -
-
-
- {isMultiline ? ( +
+ {/* Compact input row */} + +
+ { + setValue(e.target.value) + detectContentType(e.target.value) + if (e.target.value) setIsOpen(true) + }} + onKeyDown={handleKeyDown} + onFocus={handleInputFocus} + onPaste={handlePaste} + className="w-full sm:w-80 h-9 pr-16" + disabled={isLoading} + /> + {isLoading && ( + + )} + {/* Action buttons inside input */} +
+ + +
+
+ + + {/* Expanded popup */} + {isOpen && ( +
+ {/* Multiline textarea (shown when multiline mode) */} + {isMultiline && (