backup: Phase 6 search and export fixes before cleanup
- Added search button to main page header with Ctrl+K listener - Implemented SearchModal component rendering - Fixed SearchModal to use axiosInstance with correct backend URL (8916) - Fixed token key from 'auth_token' to 'inventory_token' - Verified export endpoints working correctly - All Phase 6 UAT fixes in place Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,7 @@ import ItemComparisonModal from '@/components/ItemComparisonModal';
|
||||
import StockAdjustmentPanel from '@/components/StockAdjustmentPanel';
|
||||
import NewItemDialog from '@/components/NewItemDialog';
|
||||
import ScannerSection from '@/components/ScannerSection';
|
||||
import SearchModal from '@/components/inventory/SearchModal';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import {
|
||||
Package,
|
||||
@@ -59,6 +60,7 @@ export default function Home() {
|
||||
const [categories, setCategories] = useState<any[]>([]);
|
||||
const [comparisonModal, setComparisonModal] = useState<{ show: boolean, newItem: any, existingItem: any, existingId: number | null }>({ show: false, newItem: null, existingItem: null, existingId: null });
|
||||
const [comparisonLoading, setComparisonLoading] = useState(false);
|
||||
const [showSearch, setShowSearch] = useState(false);
|
||||
|
||||
const { syncing, handleSync } = useSync({
|
||||
isOnline,
|
||||
@@ -152,6 +154,18 @@ export default function Home() {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
|
||||
e.preventDefault();
|
||||
setShowSearch(!showSearch);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||
}, [showSearch]);
|
||||
|
||||
const loadInventory = async () => {
|
||||
const cached = await db.items.toArray();
|
||||
setInventory(cached);
|
||||
@@ -389,6 +403,13 @@ export default function Home() {
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
onClick={() => setShowSearch(true)}
|
||||
className="p-2.5 bg-surface border border-slate-800 text-secondary rounded-xl hover:text-white transition-all active:scale-95"
|
||||
title="Search (Ctrl+K)"
|
||||
>
|
||||
<Search size={18} />
|
||||
</button>
|
||||
<button
|
||||
onClick={handleSync}
|
||||
disabled={syncing}
|
||||
@@ -431,6 +452,16 @@ export default function Home() {
|
||||
loading={comparisonLoading}
|
||||
/>
|
||||
|
||||
{/* Search Modal */}
|
||||
<SearchModal
|
||||
isOpen={showSearch}
|
||||
onClose={() => setShowSearch(false)}
|
||||
onSelectItem={(item) => {
|
||||
setSelectedItem(item);
|
||||
setShowSearch(false);
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* Stock Adjustment Panel */}
|
||||
<StockAdjustmentPanel
|
||||
selectedItem={selectedItem}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { X, Search } from 'lucide-react';
|
||||
import { Item } from '@/lib/db';
|
||||
import { axiosInstance } from '@/lib/api';
|
||||
|
||||
interface SearchModalProps {
|
||||
isOpen: boolean;
|
||||
@@ -41,22 +42,11 @@ export default function SearchModal({
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
const backendUrl = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8906';
|
||||
const token = localStorage.getItem('auth_token');
|
||||
const response = await fetch(`${backendUrl}/items/search?q=${encodeURIComponent(searchQuery)}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
const response = await axiosInstance.get('/items/search', {
|
||||
params: { q: searchQuery }
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Search failed');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
setResults(data || []);
|
||||
setResults(response.data || []);
|
||||
} catch (err) {
|
||||
const errorMsg = err instanceof Error ? err.message : 'Search failed';
|
||||
setError(errorMsg);
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user