import React, { useEffect, useState } from 'react';
import './PharmacyList.css';
import { haversineKm, formatDistance } from '../utils/geo';
import { getOpenStatus } from '../utils/hours';
import {
pushSupported,
isSubscribedLocally,
subscribeToPush,
unsubscribeFromPush,
} from '../utils/notifications.js';
function PharmacyList({ pharmacies, loading, userPosition, medicine, currentUser, onLoginRequest }) {
if (loading) {
return (
);
}
if (pharmacies.length === 0) {
return (
No se encontraron farmacias con este medicamento
);
}
return (
Disponible en {pharmacies.length} {pharmacies.length === 1 ? 'farmacia' : 'farmacias'}
{pharmacies.map((pharmacy) => {
const distanceKm =
userPosition && pharmacy.latitude != null && pharmacy.longitude != null
? haversineKm(userPosition.lat, userPosition.lon, pharmacy.latitude, pharmacy.longitude)
: null;
return (
);
})}
);
}
function PharmacyCard({ pharmacy, distanceKm, medicine, currentUser, onLoginRequest, userPosition }) {
const nregistro = medicine?.nregistro || medicine?.id;
const supported = pushSupported();
const outOfStock = pharmacy.stock !== undefined && pharmacy.stock <= 0;
const showBell = Boolean(medicine && nregistro && outOfStock);
const [subscribed, setSubscribed] = useState(() =>
showBell ? isSubscribedLocally(nregistro, pharmacy.id) : false
);
const [busy, setBusy] = useState(false);
const [error, setError] = useState(null);
useEffect(() => {
if (showBell) setSubscribed(isSubscribedLocally(nregistro, pharmacy.id));
}, [nregistro, pharmacy.id, showBell]);
async function handleBell(e) {
e.stopPropagation();
if (!currentUser) {
onLoginRequest?.();
return;
}
if (!supported) {
setError('Las notificaciones requieren iOS 16.4+ y este sitio instalado como app (Compartir → Añadir a Pantalla de Inicio).');
return;
}
if (busy) return;
setBusy(true);
setError(null);
try {
if (subscribed) {
await unsubscribeFromPush(nregistro, pharmacy.id);
setSubscribed(false);
} else {
await subscribeToPush(nregistro, medicine.name, pharmacy.id);
setSubscribed(true);
}
} catch (err) {
console.error('[notify] pharmacy toggle failed:', err);
setError(err.message || 'No se pudo actualizar la suscripción');
} finally {
setBusy(false);
}
}
const openStatus = getOpenStatus(pharmacy.opening_hours);
return (
🏥 {pharmacy.name}
{distanceKm != null && (
{formatDistance(distanceKm)}
)}
{showBell && (
)}
{openStatus && (
{openStatus.label}
)}
📍 {pharmacy.address}
{pharmacy.phone && (
📞 {pharmacy.phone}
)}
{error &&
{error}
}
{pharmacy.latitude != null && pharmacy.longitude != null && (
Cómo llegar
)}
{pharmacy.price && (
€{parseFloat(pharmacy.price).toFixed(2)}
)}
{pharmacy.stock !== undefined && (
20 ? 'in-stock' : pharmacy.stock > 0 ? 'low-stock' : 'out-of-stock'}`}>
{pharmacy.stock > 20 ? '✓ En Stock' : pharmacy.stock > 0 ? `⚠ Stock Bajo (${pharmacy.stock})` : '✗ Sin Stock'}
)}
);
}
export default PharmacyList;