- Fix bookmarklet URL to use absolute path with window.location.origin - Change capture prefix from 'rec:' to 'web:' for web captures - Add BookmarkletInstructions to header and preferences panel - Redesign QuickAdd as dropdown popup (no header overflow) - Move capture button and work mode to mobile menu - Fix isOpen bug in BookmarkletInstructions dialog
140 lines
5.0 KiB
TypeScript
140 lines
5.0 KiB
TypeScript
'use client'
|
|
|
|
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 (
|
|
<header className="sticky top-0 z-40 w-full border-b bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
|
|
<div className="container mx-auto px-2 sm:px-4">
|
|
{/* Desktop: single row */}
|
|
<div className="hidden sm:flex h-14 items-center justify-between gap-2">
|
|
<Link href="/" className="flex items-center gap-2">
|
|
<span className="text-xl font-bold">Recall</span>
|
|
</Link>
|
|
<nav className="flex items-center gap-1">
|
|
<Link href="/notes">
|
|
<Button
|
|
variant={pathname === '/notes' ? 'secondary' : 'ghost'}
|
|
size="sm"
|
|
className="gap-1.5"
|
|
>
|
|
<FileText className="h-4 w-4" />
|
|
Notas
|
|
</Button>
|
|
</Link>
|
|
<Link href="/settings">
|
|
<Button
|
|
variant={pathname === '/settings' ? 'secondary' : 'ghost'}
|
|
size="sm"
|
|
className="gap-1.5"
|
|
>
|
|
<Settings className="h-4 w-4" />
|
|
Configuración
|
|
</Button>
|
|
</Link>
|
|
</nav>
|
|
<div className="flex items-center gap-2">
|
|
<QuickAdd />
|
|
<BookmarkletInstructions />
|
|
{workModeToggleVisible && <WorkModeToggle />}
|
|
<Link href="/new">
|
|
<Button size="sm" className="gap-1.5">
|
|
<Plus className="h-4 w-4" />
|
|
Nueva nota
|
|
</Button>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile: hamburger + logo */}
|
|
<div className="flex sm:hidden h-14 items-center justify-between gap-2">
|
|
<Link href="/" className="flex items-center gap-2">
|
|
<span className="text-lg font-bold">Recall</span>
|
|
</Link>
|
|
<div className="flex items-center gap-1.5">
|
|
<QuickAdd />
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
|
className="p-2"
|
|
>
|
|
{mobileMenuOpen ? (
|
|
<X className="h-5 w-5" />
|
|
) : (
|
|
<Menu className="h-5 w-5" />
|
|
)}
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Mobile dropdown menu */}
|
|
{mobileMenuOpen && (
|
|
<div className="sm:hidden py-3 border-t flex flex-col gap-2">
|
|
<nav className="flex flex-col gap-1">
|
|
<Link href="/notes" onClick={() => setMobileMenuOpen(false)}>
|
|
<Button
|
|
variant={pathname === '/notes' ? 'secondary' : 'ghost'}
|
|
size="sm"
|
|
className="w-full justify-start gap-2"
|
|
>
|
|
<FileText className="h-4 w-4" />
|
|
Notas
|
|
</Button>
|
|
</Link>
|
|
<Link href="/settings" onClick={() => setMobileMenuOpen(false)}>
|
|
<Button
|
|
variant={pathname === '/settings' ? 'secondary' : 'ghost'}
|
|
size="sm"
|
|
className="w-full justify-start gap-2"
|
|
>
|
|
<Settings className="h-4 w-4" />
|
|
Configuración
|
|
</Button>
|
|
</Link>
|
|
</nav>
|
|
<div className="border-t pt-2 flex flex-col gap-1">
|
|
<Link href="/new" onClick={() => setMobileMenuOpen(false)}>
|
|
<Button size="sm" className="w-full justify-start gap-2">
|
|
<Plus className="h-4 w-4" />
|
|
Nueva nota
|
|
</Button>
|
|
</Link>
|
|
<BookmarkletInstructions />
|
|
{workModeToggleVisible && (
|
|
<div className="flex items-center justify-between px-2 py-1.5">
|
|
<span className="text-sm">Modo trabajo</span>
|
|
<WorkModeToggle />
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</header>
|
|
)
|
|
}
|