import React, { useState, useEffect, useMemo, useRef } from 'react'; import { useTranslation } from '../../i18n'; import './AdminComponents.css'; const MAX_PHARMACY_RESULTS = 25; function normalize(s) { return (s || '').toString().toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, ''); } function PharmacyMedicineLink() { const { t } = useTranslation(); const [pharmacies, setPharmacies] = useState([]); const [medicineSearch, setMedicineSearch] = useState(''); const [medicineResults, setMedicineResults] = useState([]); const [selectedPharmacy, setSelectedPharmacy] = useState(null); const [selectedMedicine, setSelectedMedicine] = useState(null); const [pharmacyMedicines, setPharmacyMedicines] = useState([]); const [loading, setLoading] = useState(false); const [searching, setSearching] = useState(false); const [pharmacyQuery, setPharmacyQuery] = useState(''); const [pharmacyDropdownOpen, setPharmacyDropdownOpen] = useState(false); const pharmacyInputRef = useRef(null); const [formData, setFormData] = useState({ pharmacy_id: '', price: '', stock: '' }); const filteredPharmacies = useMemo(() => { const q = normalize(pharmacyQuery).trim(); if (!q) return pharmacies.slice(0, MAX_PHARMACY_RESULTS); const tokens = q.split(/\s+/).filter(Boolean); return pharmacies .filter(p => { const hay = `${normalize(p.name)} ${normalize(p.address)}`; return tokens.every(tok => hay.includes(tok)); }) .slice(0, MAX_PHARMACY_RESULTS); }, [pharmacies, pharmacyQuery]); useEffect(() => { fetchPharmacies(); }, []); useEffect(() => { if (selectedPharmacy) { fetchPharmacyMedicines(selectedPharmacy.id); } }, [selectedPharmacy]); // Buscar medicamentos en la API de CIMA mientras el usuario escribe useEffect(() => { const q = medicineSearch.trim(); if (q.length < 2) { setMedicineResults([]); setSearching(false); return; } const controller = new AbortController(); const timeoutId = setTimeout(async () => { setSearching(true); try { const response = await fetch(`/api/medicines/search?q=${encodeURIComponent(q)}`, { credentials: 'include', signal: controller.signal, }); const data = await response.json(); setMedicineResults(Array.isArray(data) ? data : []); } catch (error) { if (error.name === 'AbortError') return; console.error('Error searching medicines:', error); } finally { if (!controller.signal.aborted) setSearching(false); } }, 500); return () => { clearTimeout(timeoutId); controller.abort(); }; }, [medicineSearch]); const fetchPharmacies = async () => { try { const response = await fetch('/api/pharmacies', { credentials: 'include', }); const data = await response.json(); setPharmacies(data); } catch (error) { console.error('Error fetching pharmacies:', error); } }; const fetchPharmacyMedicines = async (pharmacyId) => { setLoading(true); try { const response = await fetch(`/api/admin/pharmacies/${pharmacyId}/medicines`, { credentials: 'include', }); const data = await response.json(); setPharmacyMedicines(data); } catch (error) { console.error('Error fetching pharmacy medicines:', error); } finally { setLoading(false); } }; const handleSubmit = async (e) => { e.preventDefault(); if (!selectedMedicine) { alert(t('admin.linkMedicine.selectMedicineFirst')); return; } try { const payload = { pharmacy_id: parseInt(formData.pharmacy_id), medicine_nregistro: selectedMedicine.nregistro, medicine_name: selectedMedicine.name, price: formData.price ? parseFloat(formData.price) : null, stock: formData.stock ? parseInt(formData.stock) : 0 }; const response = await fetch('/api/admin/pharmacy-medicines', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify(payload) }); if (!response.ok) throw new Error(t('admin.linkMedicine.linkError')); resetForm(); if (selectedPharmacy) { fetchPharmacyMedicines(selectedPharmacy.id); } alert(t('admin.linkMedicine.linkSuccess')); } catch (error) { console.error('Error linking medicine:', error); alert(t('admin.linkMedicine.linkError')); } }; const handleUpdate = async (id, price, stock) => { try { const response = await fetch(`/api/admin/pharmacy-medicines/${id}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ price, stock }) }); if (!response.ok) throw new Error(t('admin.linkMedicine.updateError')); fetchPharmacyMedicines(selectedPharmacy.id); alert(t('admin.linkMedicine.updateSuccess')); } catch (error) { console.error('Error updating:', error); alert(t('admin.linkMedicine.updateError')); } }; const handleDelete = async (id) => { if (!confirm(t('admin.linkMedicine.deleteConfirm'))) return; try { const response = await fetch(`/api/admin/pharmacy-medicines/${id}`, { method: 'DELETE', credentials: 'include' }); if (!response.ok) throw new Error(t('admin.linkMedicine.deleteError')); fetchPharmacyMedicines(selectedPharmacy.id); alert(t('admin.linkMedicine.deleteSuccess')); } catch (error) { console.error('Error deleting:', error); alert(t('admin.linkMedicine.deleteError')); } }; const resetForm = () => { setFormData({ pharmacy_id: selectedPharmacy ? selectedPharmacy.id.toString() : '', price: '', stock: '' }); setSelectedMedicine(null); setMedicineSearch(''); setMedicineResults([]); }; const selectMedicine = (medicine) => { setSelectedMedicine(medicine); setMedicineSearch(medicine.name); setMedicineResults([]); }; const pickPharmacy = (pharmacy) => { setSelectedPharmacy(pharmacy); setFormData(prev => ({ ...prev, pharmacy_id: pharmacy.id.toString() })); setPharmacyQuery(`${pharmacy.name} — ${pharmacy.address}`); setPharmacyDropdownOpen(false); }; const clearPharmacy = () => { setSelectedPharmacy(null); setFormData(prev => ({ ...prev, pharmacy_id: '' })); setPharmacyQuery(''); setPharmacyDropdownOpen(true); setTimeout(() => pharmacyInputRef.current?.focus(), 0); }; return (
{t('admin.linkMedicine.empty')}
) : ({t('admin.linkMedicine.priceLabel')} {pm.price ? `€${parseFloat(pm.price).toFixed(2)}` : t('admin.linkMedicine.undefined')} • Stock: {pm.stock || 0}