'use client' import { useEffect, useCallback, useState, createContext, useContext, ReactNode } from 'react' import { useRouter } from 'next/navigation' import { X, Command, Search } from 'lucide-react' import clsx from 'clsx' // ============================================================================ // TYPES // ============================================================================ interface Shortcut { key: string label: string description: string action: () => void category: 'navigation' | 'actions' | 'global' requiresModifier?: boolean } interface KeyboardShortcutsContextType { shortcuts: Shortcut[] registerShortcut: (shortcut: Shortcut) => void unregisterShortcut: (key: string) => void showHelp: boolean setShowHelp: (show: boolean) => void } // ============================================================================ // CONTEXT // ============================================================================ const KeyboardShortcutsContext = createContext(null) export function useKeyboardShortcuts() { const context = useContext(KeyboardShortcutsContext) if (!context) { throw new Error('useKeyboardShortcuts must be used within KeyboardShortcutsProvider') } return context } // ============================================================================ // PROVIDER // ============================================================================ export function KeyboardShortcutsProvider({ children, shortcuts: defaultShortcuts = [], }: { children: ReactNode shortcuts?: Shortcut[] }) { const router = useRouter() const [shortcuts, setShortcuts] = useState(defaultShortcuts) const [showHelp, setShowHelp] = useState(false) const registerShortcut = useCallback((shortcut: Shortcut) => { setShortcuts(prev => { const existing = prev.find(s => s.key === shortcut.key) if (existing) return prev return [...prev, shortcut] }) }, []) const unregisterShortcut = useCallback((key: string) => { setShortcuts(prev => prev.filter(s => s.key !== key)) }, []) // Handle keyboard events useEffect(() => { const handleKeyDown = (e: KeyboardEvent) => { // Ignore if user is typing in an input if ( e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLSelectElement || (e.target as HTMLElement)?.isContentEditable ) { return } // Show help with ? if (e.key === '?' && !e.metaKey && !e.ctrlKey) { e.preventDefault() setShowHelp(true) return } // Close help with Escape if (e.key === 'Escape' && showHelp) { e.preventDefault() setShowHelp(false) return } // Find matching shortcut const shortcut = shortcuts.find(s => { if (s.requiresModifier) { return (e.metaKey || e.ctrlKey) && e.key.toLowerCase() === s.key.toLowerCase() } return e.key.toLowerCase() === s.key.toLowerCase() && !e.metaKey && !e.ctrlKey }) if (shortcut) { e.preventDefault() shortcut.action() } } window.addEventListener('keydown', handleKeyDown) return () => window.removeEventListener('keydown', handleKeyDown) }, [shortcuts, showHelp]) return ( {children} {showHelp && setShowHelp(false)} />} ) } // ============================================================================ // SHORTCUTS MODAL // ============================================================================ function ShortcutsModal({ shortcuts, onClose }: { shortcuts: Shortcut[]; onClose: () => void }) { const categories = { navigation: shortcuts.filter(s => s.category === 'navigation'), actions: shortcuts.filter(s => s.category === 'actions'), global: shortcuts.filter(s => s.category === 'global'), } return (
e.stopPropagation()} > {/* Header */}

Keyboard Shortcuts

{/* Content */}
{/* Navigation */} {categories.navigation.length > 0 && (

Navigation

{categories.navigation.map(shortcut => ( ))}
)} {/* Actions */} {categories.actions.length > 0 && (

Actions

{categories.actions.map(shortcut => ( ))}
)} {/* Global */} {categories.global.length > 0 && (

Global

{categories.global.map(shortcut => ( ))}
)}
{/* Footer */}

Press ? anytime to show this help

) } function ShortcutRow({ shortcut }: { shortcut: Shortcut }) { return (

{shortcut.label}

{shortcut.description}

{shortcut.requiresModifier && ( <> + )} {shortcut.key}
) } // ============================================================================ // USER BACKEND SHORTCUTS // ============================================================================ export function useUserShortcuts() { const router = useRouter() const { registerShortcut, unregisterShortcut, setShowHelp } = useKeyboardShortcuts() useEffect(() => { const userShortcuts: Shortcut[] = [ // Navigation { key: 'g', label: 'Go to Dashboard', description: 'Navigate to dashboard', action: () => router.push('/dashboard'), category: 'navigation' }, { key: 'w', label: 'Go to Watchlist', description: 'Navigate to watchlist', action: () => router.push('/watchlist'), category: 'navigation' }, { key: 'p', label: 'Go to Portfolio', description: 'Navigate to portfolio', action: () => router.push('/portfolio'), category: 'navigation' }, { key: 'a', label: 'Go to Auctions', description: 'Navigate to auctions', action: () => router.push('/auctions'), category: 'navigation' }, { key: 'i', label: 'Go to Intelligence', description: 'Navigate to TLD intelligence', action: () => router.push('/intelligence'), category: 'navigation' }, { key: 's', label: 'Go to Settings', description: 'Navigate to settings', action: () => router.push('/settings'), category: 'navigation' }, // Actions { key: 'n', label: 'Add Domain', description: 'Quick add a new domain', action: () => document.querySelector('input[placeholder*="domain"]')?.focus(), category: 'actions' }, { key: 'k', label: 'Search', description: 'Focus search input', action: () => document.querySelector('input[type="text"]')?.focus(), category: 'actions', requiresModifier: true }, // Global { key: '?', label: 'Show Shortcuts', description: 'Display this help', action: () => setShowHelp(true), category: 'global' }, { key: 'Escape', label: 'Close Modal', description: 'Close any open modal', action: () => {}, category: 'global' }, ] userShortcuts.forEach(registerShortcut) return () => { userShortcuts.forEach(s => unregisterShortcut(s.key)) } }, [router, registerShortcut, unregisterShortcut, setShowHelp]) } // ============================================================================ // ADMIN SHORTCUTS // ============================================================================ export function useAdminShortcuts() { const router = useRouter() const { registerShortcut, unregisterShortcut, setShowHelp } = useKeyboardShortcuts() useEffect(() => { const adminShortcuts: Shortcut[] = [ // Navigation { key: 'o', label: 'Overview', description: 'Go to admin overview', action: () => {}, category: 'navigation' }, { key: 'u', label: 'Users', description: 'Go to users management', action: () => {}, category: 'navigation' }, { key: 'b', label: 'Blog', description: 'Go to blog management', action: () => {}, category: 'navigation' }, { key: 'y', label: 'System', description: 'Go to system status', action: () => {}, category: 'navigation' }, // Actions { key: 'r', label: 'Refresh Data', description: 'Refresh current data', action: () => window.location.reload(), category: 'actions' }, { key: 'e', label: 'Export', description: 'Export current data', action: () => {}, category: 'actions' }, // Global { key: '?', label: 'Show Shortcuts', description: 'Display this help', action: () => setShowHelp(true), category: 'global' }, { key: 'd', label: 'Back to Dashboard', description: 'Return to user dashboard', action: () => router.push('/dashboard'), category: 'global' }, ] adminShortcuts.forEach(registerShortcut) return () => { adminShortcuts.forEach(s => unregisterShortcut(s.key)) } }, [router, registerShortcut, unregisterShortcut, setShowHelp]) } // ============================================================================ // SHORTCUT HINT COMPONENT // ============================================================================ export function ShortcutHint({ shortcut, className }: { shortcut: string; className?: string }) { return ( {shortcut} ) }