Move the serach box to teh sidebar
This commit is contained in:
@@ -13,7 +13,6 @@ import { NotificationPanel } from '../../ui/NotificationPanel/NotificationPanel'
|
||||
import { CompactLanguageSelector } from '../../ui/LanguageSelector';
|
||||
import {
|
||||
Menu,
|
||||
Search,
|
||||
Bell,
|
||||
X
|
||||
} from 'lucide-react';
|
||||
@@ -59,7 +58,7 @@ export interface HeaderProps {
|
||||
}
|
||||
|
||||
export interface HeaderRef {
|
||||
focusSearch: () => void;
|
||||
// No search-related methods anymore
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,63 +99,28 @@ export const Header = forwardRef<HeaderRef, HeaderProps>(({
|
||||
clearAll
|
||||
} = useNotifications();
|
||||
|
||||
const [isSearchFocused, setIsSearchFocused] = useState(false);
|
||||
const [searchValue, setSearchValue] = useState('');
|
||||
const [isNotificationPanelOpen, setIsNotificationPanelOpen] = useState(false);
|
||||
|
||||
const searchInputRef = React.useRef<HTMLInputElement>(null);
|
||||
const defaultSearchPlaceholder = searchPlaceholder || t('common:forms.search_placeholder', 'Search...');
|
||||
|
||||
// Focus search input
|
||||
const focusSearch = useCallback(() => {
|
||||
searchInputRef.current?.focus();
|
||||
}, []);
|
||||
|
||||
// Expose ref methods
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
focusSearch,
|
||||
}), [focusSearch]);
|
||||
|
||||
// Handle search
|
||||
const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setSearchValue(e.target.value);
|
||||
}, []);
|
||||
|
||||
const handleSearchSubmit = useCallback((e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (searchValue.trim()) {
|
||||
// TODO: Implement search functionality
|
||||
console.log('Search:', searchValue);
|
||||
}
|
||||
}, [searchValue]);
|
||||
|
||||
const clearSearch = useCallback(() => {
|
||||
setSearchValue('');
|
||||
searchInputRef.current?.focus();
|
||||
}, []);
|
||||
// No search functions available anymore
|
||||
}), []);
|
||||
|
||||
|
||||
// Keyboard shortcuts
|
||||
React.useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
// Cmd/Ctrl + K for search
|
||||
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
|
||||
e.preventDefault();
|
||||
focusSearch();
|
||||
}
|
||||
|
||||
// Escape to close menus
|
||||
if (e.key === 'Escape') {
|
||||
setIsNotificationPanelOpen(false);
|
||||
if (isSearchFocused) {
|
||||
searchInputRef.current?.blur();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('keydown', handleKeyDown);
|
||||
return () => document.removeEventListener('keydown', handleKeyDown);
|
||||
}, [focusSearch, isSearchFocused]);
|
||||
}, []);
|
||||
|
||||
// Close menus when clicking outside
|
||||
React.useEffect(() => {
|
||||
@@ -238,71 +202,18 @@ export const Header = forwardRef<HeaderRef, HeaderProps>(({
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Search */}
|
||||
{showSearch && isAuthenticated && (
|
||||
<form
|
||||
onSubmit={handleSearchSubmit}
|
||||
className="hidden md:flex items-center flex-1 max-w-md mx-4"
|
||||
>
|
||||
<div className="relative w-full">
|
||||
<div className="absolute left-3 top-0 bottom-0 flex items-center pointer-events-none">
|
||||
<Search className="h-4 w-4 text-[var(--text-tertiary)]" />
|
||||
</div>
|
||||
<input
|
||||
ref={searchInputRef}
|
||||
type="text"
|
||||
value={searchValue}
|
||||
onChange={handleSearchChange}
|
||||
onFocus={() => setIsSearchFocused(true)}
|
||||
onBlur={() => setIsSearchFocused(false)}
|
||||
placeholder={defaultSearchPlaceholder}
|
||||
className={clsx(
|
||||
'w-full pl-10 pr-12 py-2.5 text-sm',
|
||||
'bg-[var(--bg-secondary)] border border-[var(--border-primary)]',
|
||||
'rounded-lg transition-colors duration-200',
|
||||
'focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]/20',
|
||||
'focus:border-[var(--color-primary)]',
|
||||
'placeholder:text-[var(--text-tertiary)]',
|
||||
'h-9'
|
||||
)}
|
||||
aria-label={t('common:accessibility.search', 'Search in the application')}
|
||||
/>
|
||||
{searchValue ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={clearSearch}
|
||||
className="absolute right-3 top-0 bottom-0 flex items-center p-1 hover:bg-[var(--bg-tertiary)] rounded-full transition-colors"
|
||||
aria-label={t('common:actions.clear', 'Clear search')}
|
||||
>
|
||||
<X className="h-3 w-3 text-[var(--text-tertiary)]" />
|
||||
</button>
|
||||
) : (
|
||||
<div className="absolute right-3 top-0 bottom-0 flex items-center pointer-events-none">
|
||||
<kbd className="hidden lg:inline-flex items-center justify-center h-5 px-1.5 text-xs text-[var(--text-tertiary)] font-mono bg-[var(--bg-tertiary)] rounded border border-[var(--border-primary)]">
|
||||
⌘K
|
||||
</kbd>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</form>
|
||||
{/* Space for potential future content */ }
|
||||
{isAuthenticated && (
|
||||
<div className="hidden md:flex items-center flex-1 max-w-md mx-4">
|
||||
{/* Empty space to maintain layout consistency */}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Right section */}
|
||||
{isAuthenticated && (
|
||||
<div className="flex items-center gap-1">
|
||||
{/* Mobile search */}
|
||||
{showSearch && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={focusSearch}
|
||||
className="md:hidden w-10 h-10 p-0 flex items-center justify-center"
|
||||
aria-label={t('common:actions.search', 'Search')}
|
||||
>
|
||||
<Search className="h-5 w-5" />
|
||||
</Button>
|
||||
)}
|
||||
{/* Placeholder for potential future items */ }
|
||||
|
||||
{/* Language selector */}
|
||||
<CompactLanguageSelector className="w-auto min-w-[60px]" />
|
||||
|
||||
Reference in New Issue
Block a user