mirror of
https://github.com/R0m1k3/noteflow.git
synced 2026-10-23 15:18:16 +02:00
feat: add keyboard shortcuts and statistics dashboard
Keyboard Shortcuts: - Create useKeyboardShortcuts hook with configurable shortcuts - Support Ctrl/Cmd, Alt, Shift modifiers - Add 7 global shortcuts (New note, Search, Quick capture, etc.) - Create KeyboardShortcutsHelp modal with categorized shortcuts - Show formatted shortcut keys (⌘ on Mac, Ctrl on Windows) - Press ? to open shortcuts help Statistics Dashboard: - Create StatsDashboard component with productivity metrics - Calculate productivity score (0-100) based on completion rate - Show notes statistics (total, active, archived, priority) - Display todos statistics with completion rate - Track content stats (notes with todos/images/files, unique tags) - Show recent activity (notes updated in last 7 days) - Visual progress bar for productivity score - Integrate dashboard in left column below calendar
This commit is contained in:
4 files changed
+454
No files matched your search
@@ -41,6 +41,9 @@ import { PomodoroTimer } from "@/components/PomodoroTimer";
|
||||
import { KanbanBoard } from "@/components/KanbanBoard";
|
||||
import { getSmartTagSuggestions } from "@/utils/smartTags";
|
||||
import { QuickCaptureWidget } from "@/components/QuickCaptureWidget";
|
||||
import { StatsDashboard } from "@/components/StatsDashboard";
|
||||
import { KeyboardShortcutsHelp } from "@/components/KeyboardShortcutsHelp";
|
||||
import { useKeyboardShortcuts, type KeyboardShortcut } from "@/hooks/useKeyboardShortcuts";
|
||||
|
||||
// ===== FONCTIONS UTILITAIRES TIMEZONE EUROPE/PARIS =====
|
||||
|
||||
@@ -170,6 +173,8 @@ const Index = () => {
|
||||
const [selectedImage, setSelectedImage] = useState<string | null>(null);
|
||||
const [addEventModal, setAddEventModal] = useState(false);
|
||||
const [editEventModal, setEditEventModal] = useState<{ open: boolean, event?: CalendarEvent }>({ open: false });
|
||||
const [showKeyboardHelp, setShowKeyboardHelp] = useState(false);
|
||||
const [showStatsDashboard, setShowStatsDashboard] = useState(false);
|
||||
|
||||
// Pagination states
|
||||
const [notesPage, setNotesPage] = useState(0);
|
||||
@@ -934,6 +939,72 @@ const Index = () => {
|
||||
setCalendarPage(0);
|
||||
}, [calendarEvents.length]);
|
||||
|
||||
// Define keyboard shortcuts
|
||||
const keyboardShortcuts: KeyboardShortcut[] = [
|
||||
{
|
||||
key: 'n',
|
||||
ctrl: true,
|
||||
description: 'Nouvelle note',
|
||||
handler: () => !showAdmin && handleCreateNote()
|
||||
},
|
||||
{
|
||||
key: 'k',
|
||||
ctrl: true,
|
||||
description: 'Rechercher',
|
||||
handler: () => {
|
||||
const searchInput = document.querySelector('input[type="search"]') as HTMLInputElement;
|
||||
if (searchInput) searchInput.focus();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'q',
|
||||
ctrl: true,
|
||||
description: 'Capture rapide',
|
||||
handler: () => {
|
||||
const captureButton = document.querySelector('[title="Capture rapide (Ctrl+Q)"]') as HTMLButtonElement;
|
||||
if (captureButton) captureButton.click();
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 'Escape',
|
||||
description: 'Fermer note/modal',
|
||||
handler: () => {
|
||||
if (openNote) setOpenNote(null);
|
||||
else if (showAdmin) setShowAdmin(false);
|
||||
else if (showKeyboardHelp) setShowKeyboardHelp(false);
|
||||
},
|
||||
preventDefault: false
|
||||
},
|
||||
{
|
||||
key: '?',
|
||||
shift: true,
|
||||
description: 'Aide raccourcis',
|
||||
handler: () => setShowKeyboardHelp(true)
|
||||
},
|
||||
{
|
||||
key: 'e',
|
||||
ctrl: true,
|
||||
description: 'Archiver note',
|
||||
handler: async () => {
|
||||
if (openNote?.id) {
|
||||
await handleUpdateNote({ archived: !openNote.archived });
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
key: 's',
|
||||
ctrl: true,
|
||||
description: 'Sauvegarder (auto)',
|
||||
handler: () => {
|
||||
// Note: Auto-save is handled by the editor
|
||||
showSuccess('Auto-save actif');
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
// Register keyboard shortcuts
|
||||
useKeyboardShortcuts(keyboardShortcuts, !showAdmin);
|
||||
|
||||
// Pagination for todos
|
||||
const activeTodos = todos.filter(t => !t.completed);
|
||||
const completedTodos = todos.filter(t => t.completed);
|
||||
@@ -1191,6 +1262,9 @@ const Index = () => {
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
{/* Statistics Dashboard */}
|
||||
<StatsDashboard notes={notes} todos={todos} />
|
||||
</div>
|
||||
|
||||
{/* Middle Column: Notes or Open Note */}
|
||||
@@ -3068,6 +3142,13 @@ const Index = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Keyboard Shortcuts Help Modal */}
|
||||
<KeyboardShortcutsHelp
|
||||
open={showKeyboardHelp}
|
||||
onOpenChange={setShowKeyboardHelp}
|
||||
shortcuts={keyboardShortcuts}
|
||||
/>
|
||||
|
||||
{/* Quick Capture Widget */}
|
||||
<QuickCaptureWidget onNoteCaptured={loadNotes} />
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user