More changes than expected. Mobile version improvements & PWA
Build & Push Docker Images / test-backend (push) Successful in 44s
Build & Push Docker Images / test-frontend (push) Successful in 52s
Build & Push Docker Images / build-backend (push) Failing after 34s
Build & Push Docker Images / build-frontend (push) Failing after 30s
Build & Push Docker Images / test-backend (push) Successful in 44s
Build & Push Docker Images / test-frontend (push) Successful in 52s
Build & Push Docker Images / build-backend (push) Failing after 34s
Build & Push Docker Images / build-frontend (push) Failing after 30s
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
import React from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import './MedicineResults.css';
|
||||
import {
|
||||
pushSupported,
|
||||
isSubscribedLocally,
|
||||
subscribeToPush,
|
||||
unsubscribeFromPush,
|
||||
} from '../utils/notifications.js';
|
||||
|
||||
function MedicineResults({ medicines, onSelect, query }) {
|
||||
function MedicineResults({ medicines, onSelect, query, currentUser, onLoginRequest }) {
|
||||
if (medicines.length === 0 && query.length >= 2) {
|
||||
return (
|
||||
<div className="no-results">
|
||||
@@ -13,26 +19,96 @@ function MedicineResults({ medicines, onSelect, query }) {
|
||||
return (
|
||||
<div className="medicine-results">
|
||||
{medicines.map((medicine) => (
|
||||
<div
|
||||
key={medicine.id}
|
||||
className="medicine-card"
|
||||
onClick={() => onSelect(medicine)}
|
||||
>
|
||||
<div className="medicine-card-header">
|
||||
<h3>{medicine.name}</h3>
|
||||
</div>
|
||||
<div className="medicine-card-body">
|
||||
<p><strong>Active Ingredient:</strong> {medicine.active_ingredient}</p>
|
||||
<p><strong>Dosage:</strong> {medicine.dosage} • <strong>Form:</strong> {medicine.form}</p>
|
||||
</div>
|
||||
<div className="medicine-card-footer">
|
||||
<span className="view-pharmacies">View pharmacies →</span>
|
||||
</div>
|
||||
</div>
|
||||
<MedicineCard
|
||||
key={medicine.nregistro || medicine.id}
|
||||
medicine={medicine}
|
||||
onSelect={onSelect}
|
||||
currentUser={currentUser}
|
||||
onLoginRequest={onLoginRequest}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default MedicineResults;
|
||||
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('Notifications need iOS 16.4+ and this site installed as an app (Share → Add to Home Screen).');
|
||||
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 || 'Could not update subscription');
|
||||
} 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
|
||||
? 'Login to enable notifications'
|
||||
: subscribed
|
||||
? 'Stop notifications for this medicine'
|
||||
: 'Notify me when this medicine becomes available'
|
||||
}
|
||||
title={
|
||||
!currentUser
|
||||
? 'Login to enable notifications'
|
||||
: subscribed
|
||||
? 'Notifications on — click to turn off'
|
||||
: 'Notify me when this medicine is added to a pharmacy'
|
||||
}
|
||||
>
|
||||
{subscribed && currentUser ? '🔔' : '🔕'}
|
||||
</button>
|
||||
</div>
|
||||
<div className="medicine-card-body">
|
||||
<p><strong>Active Ingredient:</strong> {medicine.active_ingredient}</p>
|
||||
<p><strong>Dosage:</strong> {medicine.dosage} • <strong>Form:</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">View pharmacies →</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default MedicineResults;
|
||||
|
||||
Reference in New Issue
Block a user