Files
FarmaFinder/frontend/src/components/MedicineResults.jsx
T
2026-07-01 15:54:10 +02:00

115 lines
3.6 KiB
React

import React, { useEffect, useState } from 'react';
import './MedicineResults.css';
import {
pushSupported,
isSubscribedLocally,
subscribeToPush,
unsubscribeFromPush,
} from '../utils/notifications.js';
function MedicineResults({ medicines, onSelect, query, currentUser, onLoginRequest }) {
if (medicines.length === 0 && query.length >= 2) {
return (
<div className="no-results">
<p>No se encontraron medicamentos para "{query}"</p>
</div>
);
}
return (
<div className="medicine-results">
{medicines.map((medicine) => (
<MedicineCard
key={medicine.nregistro || medicine.id}
medicine={medicine}
onSelect={onSelect}
currentUser={currentUser}
onLoginRequest={onLoginRequest}
/>
))}
</div>
);
}
function MedicineCard({ medicine, onSelect, currentUser, onLoginRequest }) {
const nregistro = medicine.nregistro || medicine.id;
const [subscribed, setSubscribed] = useState(() => isSubscribedLocally(nregistro));
const [busy, setBusy] = useState(false);
const [error, setError] = useState(null);
const supported = pushSupported();
useEffect(() => {
setSubscribed(isSubscribedLocally(nregistro));
}, [nregistro]);
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);
setSubscribed(false);
} else {
await subscribeToPush(nregistro, medicine.name);
setSubscribed(true);
}
} catch (err) {
console.error('[notify] toggle failed:', err);
setError(err.message || 'No se pudo actualizar la suscripción');
} finally {
setBusy(false);
}
}
return (
<div className="medicine-card" onClick={() => onSelect(medicine)}>
<div className="medicine-card-header">
<h3>{medicine.name}</h3>
<button
type="button"
className={`notify-bell${subscribed && currentUser ? ' notify-bell--on' : ''}${!currentUser ? ' notify-bell--locked' : ''}`}
onClick={handleBell}
disabled={busy}
aria-pressed={subscribed && !!currentUser}
aria-label={
!currentUser
? 'Inicia sesión para activar notificaciones'
: subscribed
? 'Desactivar notificaciones para este medicamento'
: 'Notificarme cuando esté disponible'
}
title={
!currentUser
? 'Inicia sesión para activar notificaciones'
: subscribed
? 'Notificaciones activadas — clic para desactivar'
: 'Notificarme cuando este medicamento esté en una farmacia'
}
>
{subscribed && currentUser ? '🔔' : '🔕'}
</button>
</div>
<div className="medicine-card-body">
<p><strong>Principio Activo:</strong> {medicine.active_ingredient}</p>
<p><strong>Dosis:</strong> {medicine.dosage} <strong>Forma:</strong> {medicine.form}</p>
{error && <p className="notify-error" onClick={e => e.stopPropagation()}>{error}</p>}
</div>
<div className="medicine-card-footer">
<span className="view-pharmacies">Ver farmacias </span>
</div>
</div>
);
}
export default MedicineResults;