add AI voice assistant, chat widget, inventory and pharmacy pages with API services
This commit is contained in:
+58
-8
@@ -1,4 +1,5 @@
|
||||
import { useState, useEffect, useMemo } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { Search, AlertCircle, Package, Layers, Plus, X, ChevronDown } from 'lucide-react';
|
||||
import { createColumnHelper } from '@tanstack/react-table';
|
||||
import { Table } from '../components/Table';
|
||||
@@ -73,6 +74,8 @@ const columns = [
|
||||
];
|
||||
|
||||
const Pharmacy = () => {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
const [itemsPerPage, setItemsPerPage] = useState(25);
|
||||
const [inventory, setInventory] = useState<PharmacyItem[]>([]);
|
||||
@@ -246,18 +249,52 @@ const Pharmacy = () => {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.get('action') === 'dispense') {
|
||||
setIsDispenseModalOpen(true);
|
||||
// Clean up URL after opening
|
||||
window.history.replaceState({}, '', '/pharmacy');
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Filter inventory based on search query
|
||||
// Listen for external search triggers (e.g., Voice Assistant or Chat Widget)
|
||||
useEffect(() => {
|
||||
const handleSearchEvent = (e: any) => {
|
||||
if (typeof e.detail === 'string') {
|
||||
setSearchQuery(e.detail);
|
||||
}
|
||||
};
|
||||
window.addEventListener('setPharmacySearch', handleSearchEvent);
|
||||
window.addEventListener('setSearchQuery', handleSearchEvent);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('setPharmacySearch', handleSearchEvent);
|
||||
window.removeEventListener('setSearchQuery', handleSearchEvent);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Automatically sync search query when navigating with ?search=query
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search);
|
||||
const searchParam = params.get('search');
|
||||
if (searchParam !== null) {
|
||||
setSearchQuery(searchParam);
|
||||
}
|
||||
}, [location.search]);
|
||||
|
||||
// Filter inventory based on search query with smart matching
|
||||
const filteredInventory = useMemo(() => {
|
||||
return inventory.filter(item =>
|
||||
item.medicine.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
item.subtitle.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
item.manufacture.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
);
|
||||
if (!searchQuery.trim()) return inventory;
|
||||
const cleanSearch = searchQuery.trim().toLowerCase();
|
||||
const compactSearch = cleanSearch.replace(/[\s\-_]+/g, '');
|
||||
|
||||
return inventory.filter(item => {
|
||||
const med = item.medicine.toLowerCase();
|
||||
const sub = item.subtitle.toLowerCase();
|
||||
const mfr = item.manufacture.toLowerCase();
|
||||
const compactMed = med.replace(/[\s\-_]+/g, '');
|
||||
|
||||
return med.includes(cleanSearch) ||
|
||||
sub.includes(cleanSearch) ||
|
||||
mfr.includes(cleanSearch) ||
|
||||
compactMed.includes(compactSearch);
|
||||
});
|
||||
}, [inventory, searchQuery]);
|
||||
|
||||
// Reset pagination when search changes
|
||||
@@ -337,8 +374,21 @@ const Pharmacy = () => {
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
placeholder="Search medicines, OTC, or prescriptions..."
|
||||
className="w-full py-3 bg-slate-50 border border-slate-200 hover:border-slate-300 hover:bg-slate-100/50 rounded-xl focus:bg-white focus:outline-none focus:ring-4 focus:ring-blue-500/10 focus:border-blue-500 shadow-sm placeholder:text-slate-400 transition-all text-slate-800"
|
||||
style={{ height: '46px', paddingLeft: '44px', paddingRight: '16px', fontSize: '15px' }}
|
||||
style={{ height: '46px', paddingLeft: '44px', paddingRight: searchQuery ? '40px' : '16px', fontSize: '15px' }}
|
||||
/>
|
||||
{searchQuery && (
|
||||
<button
|
||||
onClick={() => {
|
||||
setSearchQuery('');
|
||||
navigate('/pharmacy', { replace: true });
|
||||
}}
|
||||
className="absolute inset-y-0 right-0 flex items-center pr-3 text-slate-400 hover:text-slate-600 transition-colors"
|
||||
title="Clear search"
|
||||
type="button"
|
||||
>
|
||||
<X size={18} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user