feat(frontend): integrate product search into PublicView with filter tabs

This commit is contained in:
Antoni Nuñez Romeu
2026-07-13 15:27:47 +02:00
parent 2d839b9082
commit 39868d95c6
+62 -1
View File
@@ -2,6 +2,7 @@ import React, { useState, useEffect, useMemo } from 'react';
import '../App.css'; import '../App.css';
import SearchBar from '../components/SearchBar'; import SearchBar from '../components/SearchBar';
import MedicineResults from '../components/MedicineResults'; import MedicineResults from '../components/MedicineResults';
import ProductResults from '../components/ProductResults';
import PharmacyList from '../components/PharmacyList'; import PharmacyList from '../components/PharmacyList';
import PharmacyMap from '../components/PharmacyMap'; import PharmacyMap from '../components/PharmacyMap';
import HomeView from './HomeView'; import HomeView from './HomeView';
@@ -22,6 +23,8 @@ function PublicView({
const [searchQuery, setSearchQuery] = useState(''); const [searchQuery, setSearchQuery] = useState('');
const [medicines, setMedicines] = useState([]); const [medicines, setMedicines] = useState([]);
const [products, setProducts] = useState([]);
const [searchMode, setSearchMode] = useState('all'); // 'all' | 'medicines' | 'products'
const [selectedMedicine, setSelectedMedicine] = useState(null); const [selectedMedicine, setSelectedMedicine] = useState(null);
const [pharmacies, setPharmacies] = useState([]); const [pharmacies, setPharmacies] = useState([]);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@@ -35,6 +38,7 @@ function PublicView({
const searchMedicines = async () => { const searchMedicines = async () => {
if (searchQuery.trim().length < 2) { if (searchQuery.trim().length < 2) {
setMedicines([]); setMedicines([]);
setProducts([]);
setSelectedMedicine(null); setSelectedMedicine(null);
setPharmacies([]); setPharmacies([]);
return; return;
@@ -50,6 +54,16 @@ function PublicView({
} finally { } finally {
setLoading(false); setLoading(false);
} }
try {
const productsResponse = await fetch(`/api/products/search?q=${encodeURIComponent(searchQuery)}`);
if (productsResponse.ok) {
const productsData = await productsResponse.json();
setProducts(productsData.results || []);
}
} catch (err) {
console.error('Product search error:', err);
}
}; };
const timeoutId = setTimeout(searchMedicines, 300); const timeoutId = setTimeout(searchMedicines, 300);
@@ -219,7 +233,42 @@ function PublicView({
{loading && <div className="loading">Buscando...</div>} {loading && <div className="loading">Buscando...</div>}
{searchQuery && !selectedMedicine && ( {searchQuery && (
<div className="flex gap-2 mb-4">
<button
onClick={() => setSearchMode('all')}
className={`px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${
searchMode === 'all'
? 'bg-blue-600 text-white'
: 'bg-gray-100 text-gray-600 hover:bg-gray-200'
}`}
>
Todos
</button>
<button
onClick={() => setSearchMode('medicines')}
className={`px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${
searchMode === 'medicines'
? 'bg-blue-600 text-white'
: 'bg-gray-100 text-gray-600 hover:bg-gray-200'
}`}
>
Medicamentos
</button>
<button
onClick={() => setSearchMode('products')}
className={`px-3 py-1.5 rounded-full text-sm font-medium transition-colors ${
searchMode === 'products'
? 'bg-blue-600 text-white'
: 'bg-gray-100 text-gray-600 hover:bg-gray-200'
}`}
>
Parafarmacia
</button>
</div>
)}
{searchQuery && !selectedMedicine && (searchMode === 'all' || searchMode === 'medicines') && (
<MedicineResults <MedicineResults
medicines={medicines} medicines={medicines}
onSelect={setSelectedMedicine} onSelect={setSelectedMedicine}
@@ -229,6 +278,18 @@ function PublicView({
/> />
)} )}
{(searchMode === 'all' || searchMode === 'products') && products.length > 0 && (
<div className="mt-6">
<h3 className="text-lg font-semibold mb-3">Parafarmacia y Bebé</h3>
<ProductResults
products={products}
onSelect={(product) => {
window.location.href = `/product/${product.source}/${product.id}`;
}}
/>
</div>
)}
{selectedMedicine && ( {selectedMedicine && (
<div className="selected-medicine-section"> <div className="selected-medicine-section">
<div className="medicine-info"> <div className="medicine-info">