feat: reminder button in list/tabs view, notifications show reminders, trash count live update
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 43s

- Add reminder action to NoteActions (masonry view) and NoteMetaSidebar (tabs view)
- NotificationPanel now fetches and displays upcoming/overdue reminders alongside share requests
- Badge count includes overdue reminders; overdue items show mark-as-done toggle
- Sidebar trash count refreshes on NoteRefreshContext trigger (no more manual refresh)
- Add "Clear completed" button on reminders page with clearCompletedReminders action
- Add i18n keys for new features (en/fr)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-30 20:43:02 +02:00
parent 07f8a60b69
commit 0a900b3582
9 changed files with 283 additions and 39 deletions

View File

@@ -9,6 +9,7 @@ import {
import {
Archive,
ArchiveRestore,
Bell,
MoreVertical,
Palette,
Pin,
@@ -22,6 +23,8 @@ import {
import { cn } from "@/lib/utils"
import { NOTE_COLORS } from "@/lib/types"
import { useLanguage } from "@/lib/i18n"
import { ReminderDialog } from "@/components/reminder-dialog"
import { useState } from "react"
interface NoteActionsProps {
isPinned: boolean
@@ -41,6 +44,9 @@ interface NoteActionsProps {
onPermanentDelete?: () => void
onOpenHistory?: () => void
historyEnabled?: boolean
noteId?: string
currentReminder?: Date | null
onUpdateReminder?: (noteId: string, reminder: Date | null) => void
className?: string
}
@@ -62,9 +68,13 @@ export function NoteActions({
onPermanentDelete,
onOpenHistory,
historyEnabled = false,
noteId,
currentReminder,
onUpdateReminder,
className
}: NoteActionsProps) {
const { t } = useLanguage()
const [showReminder, setShowReminder] = useState(false)
// Trash view: show only Restore and Permanent Delete
if (isTrashView) {
@@ -105,6 +115,36 @@ export function NoteActions({
className={cn("flex items-center justify-end gap-1", className)}
onClick={(e) => e.stopPropagation()}
>
{/* Reminder */}
{noteId && onUpdateReminder && (
<>
<Button
variant="ghost"
size="sm"
className={cn("h-8 w-8 p-0", currentReminder && "text-primary")}
title={t('reminder.setReminder')}
onClick={() => setShowReminder(true)}
>
<Bell className="h-4 w-4" />
</Button>
<div onClick={(e) => e.stopPropagation()}>
<ReminderDialog
open={showReminder}
onOpenChange={setShowReminder}
currentReminder={currentReminder || null}
onSave={(date) => {
onUpdateReminder(noteId, date)
setShowReminder(false)
}}
onRemove={() => {
onUpdateReminder(noteId, null)
setShowReminder(false)
}}
/>
</div>
</>
)}
{/* Color Palette */}
<DropdownMenu>
<DropdownMenuTrigger asChild>