feat(ui): panneau repliable, carnets plus lisibles et accueil plus clair
Harmonise la liste des notes et l’éditeur (titres, dates, retour), rend la saisie rapide et les raccourcis de l’accueil utilisables sur téléphone, et conserve le panneau latéral repliable.
This commit is contained in:
@@ -16,6 +16,7 @@ import {
|
||||
Loader2,
|
||||
} from 'lucide-react'
|
||||
import { useRouter } from 'next/navigation'
|
||||
import { consumeRememberedSearchQuery, rememberSearchQuery } from '@/lib/search/restore-search'
|
||||
import { useNotebooks } from '@/context/notebooks-context'
|
||||
import { useLanguage } from '@/lib/i18n'
|
||||
import type { Note } from '@/lib/types'
|
||||
@@ -89,9 +90,12 @@ export function SearchModal({ isOpen, onClose }: SearchModalProps) {
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
setTimeout(() => inputRef.current?.focus(), 50)
|
||||
setQuery('')
|
||||
setResults([])
|
||||
setSelectedIndex(0)
|
||||
const restored = consumeRememberedSearchQuery()
|
||||
setQuery(restored)
|
||||
if (!restored) {
|
||||
setResults([])
|
||||
setSelectedIndex(0)
|
||||
}
|
||||
}
|
||||
}, [isOpen])
|
||||
|
||||
@@ -111,6 +115,18 @@ export function SearchModal({ isOpen, onClose }: SearchModalProps) {
|
||||
[notebooks]
|
||||
)
|
||||
|
||||
const openNoteFromSearch = useCallback((noteId: string) => {
|
||||
rememberSearchQuery(query)
|
||||
const onHome = typeof window !== 'undefined' && window.location.pathname === '/home'
|
||||
const params = onHome
|
||||
? new URLSearchParams(window.location.search)
|
||||
: new URLSearchParams()
|
||||
params.set('openNote', noteId)
|
||||
params.set('from', 'search')
|
||||
router.push(`/home?${params.toString()}`)
|
||||
onClose()
|
||||
}, [query, router, onClose])
|
||||
|
||||
// Fetch notes from API with debounce
|
||||
useEffect(() => {
|
||||
if (debounceRef.current) clearTimeout(debounceRef.current)
|
||||
@@ -393,14 +409,13 @@ export function SearchModal({ isOpen, onClose }: SearchModalProps) {
|
||||
else if (e.key === 'Enter') {
|
||||
e.preventDefault()
|
||||
if (filteredMatches[selectedIndex]) {
|
||||
router.push(`/home?openNote=${filteredMatches[selectedIndex].noteId}`)
|
||||
onClose()
|
||||
openNoteFromSearch(filteredMatches[selectedIndex].noteId)
|
||||
}
|
||||
}
|
||||
}
|
||||
window.addEventListener('keydown', handleKeyDown)
|
||||
return () => window.removeEventListener('keydown', handleKeyDown)
|
||||
}, [isOpen, selectedIndex, filteredMatches, onClose, router])
|
||||
}, [isOpen, selectedIndex, filteredMatches, onClose, openNoteFromSearch])
|
||||
|
||||
// Save/remove query from localStorage
|
||||
const handleSaveQuery = () => {
|
||||
@@ -587,8 +602,7 @@ export function SearchModal({ isOpen, onClose }: SearchModalProps) {
|
||||
key={m.id}
|
||||
onClick={() => setSelectedIndex(idx)}
|
||||
onDoubleClick={() => {
|
||||
router.push(`/home?openNote=${m.noteId}`)
|
||||
onClose()
|
||||
openNoteFromSearch(m.noteId)
|
||||
}}
|
||||
className={`p-2.5 rounded-xl cursor-pointer text-left select-none relative flex flex-col gap-1 border transition-all ${
|
||||
isSelected
|
||||
@@ -676,8 +690,7 @@ export function SearchModal({ isOpen, onClose }: SearchModalProps) {
|
||||
<div className="pt-4 border-t border-border/40 dark:border-zinc-800 flex items-center justify-between shrink-0 mt-3">
|
||||
<button
|
||||
onClick={() => {
|
||||
router.push(`/home?openNote=${activeMatch.noteId}`)
|
||||
onClose()
|
||||
openNoteFromSearch(activeMatch.noteId)
|
||||
}}
|
||||
className="px-5 py-2.5 bg-brand-accent text-white hover:bg-brand-accent/90 text-xs font-semibold rounded-xl flex items-center gap-2 transition-all shadow-sm"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user