'use client'; import { useEffect, useState, useMemo } from 'react'; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, } from '@/components/ui/dialog'; import { Input } from '@/components/ui/input'; import { ScrollArea } from '@/components/ui/scroll-area'; interface ShortcutGroup { title: string; shortcuts: { keys: string; description: string }[]; } const shortcutGroups: ShortcutGroup[] = [ { title: 'Global', shortcuts: [ { keys: '?', description: 'Open keyboard shortcuts help' }, { keys: '⌘K', description: 'Open command palette' }, { keys: '⌘⇧K', description: 'Deep search' }, { keys: 'Esc', description: 'Close panel / dialog' }, ], }, { title: 'Navigation', shortcuts: [ { keys: 'G then D', description: 'Go to Dashboard' }, { keys: 'G then T', description: 'Go to Tasks' }, { keys: 'G then H', description: 'Go to Habits' }, { keys: 'G then P', description: 'Go to Projects' }, { keys: 'G then N', description: 'Go to Notes' }, { keys: 'G then G', description: 'Go to Graph' }, { keys: 'G then C', description: 'Go to Calendar' }, { keys: 'G then S', description: 'Go to Search' }, { keys: 'G then A', description: 'Go to Analytics' }, ], }, { title: 'Creation', shortcuts: [ { keys: 'C (on tasks page)', description: 'New task' }, { keys: 'C (on habits page)', description: 'New habit' }, { keys: 'C (on projects page)', description: 'New project' }, { keys: 'C (on notes page)', description: 'New note' }, { keys: 'C (on project detail)', description: 'New section' }, ], }, { title: 'Entity Actions', shortcuts: [ { keys: 'Space (on tasks)', description: 'Open first task detail' }, { keys: 'E', description: 'Edit focused task' }, { keys: 'D', description: 'Delete focused task' }, { keys: '1-4 (on tasks)', description: 'Filter kanban column (todo→cancelled)' }, ], }, ]; export function ShortcutsHelp() { const [open, setOpen] = useState(false); const [search, setSearch] = useState(''); // Toggle with ? key useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { const target = e.target as HTMLElement; if ( target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.tagName === 'SELECT' || target.isContentEditable ) { return; } if (e.key === '?' && !e.metaKey && !e.ctrlKey && !e.altKey) { e.preventDefault(); setOpen((prev) => !prev); } if (e.key === 'Escape' && open) { setOpen(false); } }; document.addEventListener('keydown', handleKeyDown); return () => document.removeEventListener('keydown', handleKeyDown); }, [open]); const filteredGroups = useMemo(() => { if (!search.trim()) return shortcutGroups; const q = search.toLowerCase(); return shortcutGroups .map((group) => ({ ...group, shortcuts: group.shortcuts.filter( (s) => s.keys.toLowerCase().includes(q) || s.description.toLowerCase().includes(q) ), })) .filter((group) => group.shortcuts.length > 0); }, [search]); return ( Keyboard Shortcuts All available keyboard shortcuts for Project E. setSearch(e.target.value)} className="mb-4" aria-label="Search shortcuts" /> {filteredGroups.length === 0 ? (

No shortcuts match your search.

) : ( filteredGroups.map((group) => (

{group.title}

{group.shortcuts.map((shortcut) => (
{shortcut.description} {shortcut.keys}
))}
)) )}

Press ? to toggle this overlay

); }