feat: add reminder and move-to-notebook actions to editorial note menu
- Add Bell/reminder item to EditorialNoteMenu (notes-editorial-view.tsx) - Add FolderOpen submenu for moving notes between notebooks - Import ReminderDialog, useNotebooks, DropdownMenuSub components - Fix settings/general/page.tsx to pass only required props to GeneralSettingsClient Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,16 @@ export default async function GeneralSettingsPage() {
|
|||||||
redirect('/api/auth/signin')
|
redirect('/api/auth/signin')
|
||||||
}
|
}
|
||||||
|
|
||||||
const settings = await getAISettings()
|
const {
|
||||||
|
preferredLanguage,
|
||||||
|
emailNotifications,
|
||||||
|
desktopNotifications,
|
||||||
|
autoSave,
|
||||||
|
} = await getAISettings()
|
||||||
|
|
||||||
return <GeneralSettingsClient initialSettings={settings} />
|
return (
|
||||||
|
<GeneralSettingsClient
|
||||||
|
initialSettings={{ preferredLanguage, emailNotifications, desktopNotifications, autoSave }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { getNoteFeedImage, getNotePlainExcerpt, getNoteDisplayTitle } from '@/li
|
|||||||
import { useLanguage } from '@/lib/i18n'
|
import { useLanguage } from '@/lib/i18n'
|
||||||
import { useRefresh } from '@/lib/use-refresh'
|
import { useRefresh } from '@/lib/use-refresh'
|
||||||
import { motion, AnimatePresence } from 'motion/react'
|
import { motion, AnimatePresence } from 'motion/react'
|
||||||
import { ChevronRight, MoreHorizontal, Trash2, Archive, Pin, History, Pencil, Sparkles, Loader2 } from 'lucide-react'
|
import { ChevronRight, MoreHorizontal, Trash2, Archive, Pin, History, Pencil, Sparkles, Loader2, Bell, FolderOpen, StickyNote } from 'lucide-react'
|
||||||
import { useSession } from 'next-auth/react'
|
import { useSession } from 'next-auth/react'
|
||||||
import { getAISettings } from '@/app/actions/ai-settings'
|
import { getAISettings } from '@/app/actions/ai-settings'
|
||||||
import { generateNoteIllustrationSvg } from '@/app/actions/note-illustration'
|
import { generateNoteIllustrationSvg } from '@/app/actions/note-illustration'
|
||||||
@@ -16,8 +16,13 @@ import {
|
|||||||
DropdownMenuItem,
|
DropdownMenuItem,
|
||||||
DropdownMenuSeparator,
|
DropdownMenuSeparator,
|
||||||
DropdownMenuTrigger,
|
DropdownMenuTrigger,
|
||||||
|
DropdownMenuSub,
|
||||||
|
DropdownMenuSubContent,
|
||||||
|
DropdownMenuSubTrigger,
|
||||||
} from '@/components/ui/dropdown-menu'
|
} from '@/components/ui/dropdown-menu'
|
||||||
import { deleteNote, toggleArchive, togglePin } from '@/app/actions/notes'
|
import { deleteNote, toggleArchive, togglePin, updateNote } from '@/app/actions/notes'
|
||||||
|
import { ReminderDialog } from '@/components/reminder-dialog'
|
||||||
|
import { useNotebooks } from '@/context/notebooks-context'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
|
|
||||||
type NotesEditorialViewProps = {
|
type NotesEditorialViewProps = {
|
||||||
@@ -43,7 +48,10 @@ function EditorialNoteMenu({ note, onOpen, onOpenHistory }: {
|
|||||||
}) {
|
}) {
|
||||||
const { t } = useLanguage()
|
const { t } = useLanguage()
|
||||||
const { refreshNotes } = useRefresh()
|
const { refreshNotes } = useRefresh()
|
||||||
|
const { notebooks } = useNotebooks()
|
||||||
const [, startTransition] = useTransition()
|
const [, startTransition] = useTransition()
|
||||||
|
const [showReminder, setShowReminder] = useState(false)
|
||||||
|
const [showNotebookMenu, setShowNotebookMenu] = useState(false)
|
||||||
|
|
||||||
const handleDelete = (e: React.MouseEvent) => {
|
const handleDelete = (e: React.MouseEvent) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
@@ -83,6 +91,18 @@ function EditorialNoteMenu({ note, onOpen, onOpenHistory }: {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleMoveToNotebook = (notebookId: string | null) => {
|
||||||
|
startTransition(async () => {
|
||||||
|
try {
|
||||||
|
await updateNote(note.id, { notebookId })
|
||||||
|
refreshNotes(note?.notebookId)
|
||||||
|
toast.success(t('notebookSuggestion.movedToNotebook') || 'Note déplacée')
|
||||||
|
} catch {
|
||||||
|
toast.error(t('general.error'))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild onClick={e => e.stopPropagation()}>
|
<DropdownMenuTrigger asChild onClick={e => e.stopPropagation()}>
|
||||||
@@ -109,6 +129,52 @@ function EditorialNoteMenu({ note, onOpen, onOpenHistory }: {
|
|||||||
{t('notes.history') || 'Historique'}
|
{t('notes.history') || 'Historique'}
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Rappel */}
|
||||||
|
<DropdownMenuItem onClick={e => { e.stopPropagation(); setShowReminder(true) }}>
|
||||||
|
<Bell className="h-4 w-4 mr-2" />
|
||||||
|
{note.reminder ? (t('reminder.changeReminder') || 'Modifier le rappel') : (t('reminder.setReminder') || 'Définir un rappel')}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
<ReminderDialog
|
||||||
|
open={showReminder}
|
||||||
|
onOpenChange={setShowReminder}
|
||||||
|
currentReminder={note.reminder ? new Date(note.reminder) : null}
|
||||||
|
onSave={(date) => {
|
||||||
|
startTransition(async () => {
|
||||||
|
await updateNote(note.id, { reminder: date })
|
||||||
|
refreshNotes(note?.notebookId)
|
||||||
|
setShowReminder(false)
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
onRemove={() => {
|
||||||
|
startTransition(async () => {
|
||||||
|
await updateNote(note.id, { reminder: null })
|
||||||
|
refreshNotes(note?.notebookId)
|
||||||
|
setShowReminder(false)
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* Déplacer vers notebook */}
|
||||||
|
<DropdownMenuSub open={showNotebookMenu} onOpenChange={setShowNotebookMenu}>
|
||||||
|
<DropdownMenuSubTrigger onClick={e => e.stopPropagation()}>
|
||||||
|
<FolderOpen className="h-4 w-4 mr-2" />
|
||||||
|
{t('notebookSuggestion.moveToNotebook') || 'Déplacer vers notebook'}
|
||||||
|
</DropdownMenuSubTrigger>
|
||||||
|
<DropdownMenuSubContent alignOffset={0} className="w-48">
|
||||||
|
<DropdownMenuItem onClick={e => { e.stopPropagation(); handleMoveToNotebook(null) }}>
|
||||||
|
<StickyNote className="h-4 w-4 mr-2" />
|
||||||
|
{t('notebookSuggestion.generalNotes') || 'Notes générales'}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
{notebooks.map((nb: any) => (
|
||||||
|
<DropdownMenuItem key={nb.id} onClick={e => { e.stopPropagation(); handleMoveToNotebook(nb.id) }}>
|
||||||
|
<FolderOpen className="h-4 w-4 mr-2" />
|
||||||
|
{nb.name}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
))}
|
||||||
|
</DropdownMenuSubContent>
|
||||||
|
</DropdownMenuSub>
|
||||||
|
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem onClick={handleDelete} className="text-red-600 dark:text-red-400 focus:text-red-600">
|
<DropdownMenuItem onClick={handleDelete} className="text-red-600 dark:text-red-400 focus:text-red-600">
|
||||||
<Trash2 className="h-4 w-4 mr-2" />
|
<Trash2 className="h-4 w-4 mr-2" />
|
||||||
|
|||||||
Reference in New Issue
Block a user