diff --git a/src/components/SearchOverlay.tsx b/src/components/SearchOverlay.tsx
new file mode 100644
index 0000000..2169ce2
--- /dev/null
+++ b/src/components/SearchOverlay.tsx
@@ -0,0 +1,66 @@
+import { useEffect, useState } from 'react';
+import { Input } from '@/components/ui/input';
+import { X } from 'lucide-react';
+
+interface SearchOverlayProps {
+ isOpen: boolean;
+ onClose: () => void;
+ onSearch: (query: string) => void;
+}
+
+const SearchOverlay = ({ isOpen, onClose, onSearch }: SearchOverlayProps) => {
+ const [searchQuery, setSearchQuery] = useState('');
+
+ useEffect(() => {
+ if (isOpen) {
+ // Reset search when opened
+ setSearchQuery('');
+ }
+ }, [isOpen]);
+
+ useEffect(() => {
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if (e.key === 'Escape') {
+ onClose();
+ }
+ };
+
+ if (isOpen) {
+ window.addEventListener('keydown', handleKeyDown);
+ }
+
+ return () => {
+ window.removeEventListener('keydown', handleKeyDown);
+ };
+ }, [isOpen, onClose]);
+
+ if (!isOpen) return null;
+
+ return (
+
+
+
+ {
+ setSearchQuery(e.target.value);
+ onSearch(e.target.value);
+ }}
+ className="flex-1"
+ autoFocus
+ />
+
+
+
+
+ );
+};
+
+export default SearchOverlay;
\ No newline at end of file
diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx
index 795a118..476e802 100644
--- a/src/pages/Index.tsx
+++ b/src/pages/Index.tsx
@@ -1,4 +1,4 @@
-import { useState } from 'react';
+import { useState, useEffect } from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Plus, Factory, TrendingUp, Briefcase, FileText } from 'lucide-react';
@@ -10,6 +10,7 @@ import { IndJob } from '@/lib/types';
import { Badge } from '@/components/ui/badge';
import BatchTransactionForm from '@/components/BatchTransactionForm';
import { useJobs } from '@/hooks/useDataService';
+import SearchOverlay from '@/components/SearchOverlay';
const Index = () => {
const {
@@ -26,11 +27,25 @@ const Index = () => {
const [showJobForm, setShowJobForm] = useState(false);
const [editingJob, setEditingJob] = useState(null);
const [showBatchForm, setShowBatchForm] = useState(false);
+ const [searchOpen, setSearchOpen] = useState(false);
+ const [searchQuery, setSearchQuery] = useState('');
const [collapsedGroups, setCollapsedGroups] = useState>(() => {
const saved = localStorage.getItem('jobGroupsCollapsed');
return saved ? JSON.parse(saved) : {};
});
+ useEffect(() => {
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if ((e.ctrlKey || e.metaKey) && e.key === 'f') {
+ e.preventDefault();
+ setSearchOpen(true);
+ }
+ };
+
+ window.addEventListener('keydown', handleKeyDown);
+ return () => window.removeEventListener('keydown', handleKeyDown);
+ }, []);
+
if (loading) {
return (
@@ -73,6 +88,14 @@ const Index = () => {
}
};
+ const filterJobs = (jobs: IndJob[]) => {
+ if (!searchQuery) return jobs;
+ const query = searchQuery.toLowerCase();
+ return jobs.filter(job =>
+ job.outputItem.toLowerCase().includes(query)
+ );
+ };
+
const sortedJobs = [...jobs].sort((a, b) => {
const priorityA = getStatusPriority(a.status);
const priorityB = getStatusPriority(b.status);
@@ -82,8 +105,8 @@ const Index = () => {
return priorityA - priorityB;
});
- const regularJobs = sortedJobs.filter(job => job.status !== 'Tracked');
- const trackedJobs = sortedJobs.filter(job => job.status === 'Tracked');
+ const regularJobs = filterJobs(sortedJobs.filter(job => job.status !== 'Tracked'));
+ const trackedJobs = filterJobs(sortedJobs.filter(job => job.status === 'Tracked'));
const totalJobs = regularJobs.length;
const totalProfit = regularJobs.reduce((sum, job) => {
@@ -197,6 +220,14 @@ const Index = () => {
return (
+
{
+ setSearchOpen(false);
+ setSearchQuery('');
+ }}
+ onSearch={setSearchQuery}
+ />