feat(web): integrate consent flow, Faro gating, TSI gating, and privacy link
This commit is contained in:
@@ -12,7 +12,11 @@ import ForgotPasswordModal from './components/ForgotPasswordModal';
|
||||
import ResetPasswordView from './views/ResetPasswordView';
|
||||
import SavedNotifications from './components/SavedNotifications';
|
||||
import BottomNav from './components/BottomNav';
|
||||
import CookieBanner from './components/CookieBanner';
|
||||
import HealthConsentModal from './components/HealthConsentModal';
|
||||
import PrivacyView from './views/PrivacyView';
|
||||
import { getFaro } from './utils/faro';
|
||||
import { hasConsentChoice, getLocalConsents, saveConsents, fetchServerConsents } from './utils/consent';
|
||||
|
||||
function App() {
|
||||
const [screen, setScreen] = useState('home');
|
||||
@@ -26,6 +30,10 @@ function App() {
|
||||
const [badgeCount, setBadgeCount] = useState(0);
|
||||
const [prescriptionSearch, setPrescriptionSearch] = useState('');
|
||||
const [productScreen, setProductScreen] = useState(null);
|
||||
const [showCookieBanner, setShowCookieBanner] = useState(!hasConsentChoice());
|
||||
const [showHealthConsent, setShowHealthConsent] = useState(false);
|
||||
const [pendingTsiScan, setPendingTsiScan] = useState(null);
|
||||
const [consents, setConsents] = useState(getLocalConsents);
|
||||
const [screenSize, setScreenSize] = useState({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight
|
||||
@@ -109,6 +117,14 @@ function App() {
|
||||
return () => { cancelled = true; };
|
||||
}, [currentUser]);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentUser) {
|
||||
fetchServerConsents().then(serverConsents => {
|
||||
if (serverConsents) setConsents(serverConsents);
|
||||
});
|
||||
}
|
||||
}, [currentUser]);
|
||||
|
||||
function refreshBadgeCount() {
|
||||
if (!currentUser) return;
|
||||
fetch('/api/notifications/mine', { credentials: 'include' })
|
||||
@@ -150,6 +166,36 @@ function App() {
|
||||
window.history.replaceState({}, '', '/');
|
||||
}
|
||||
|
||||
async function handleCookieConsent(newConsents) {
|
||||
const saved = await saveConsents(newConsents);
|
||||
setConsents(saved);
|
||||
setShowCookieBanner(false);
|
||||
}
|
||||
|
||||
function handleTsiScanRequest(scanFn) {
|
||||
if (consents.health_data) {
|
||||
scanFn();
|
||||
} else {
|
||||
setPendingTsiScan(() => scanFn);
|
||||
setShowHealthConsent(true);
|
||||
}
|
||||
}
|
||||
|
||||
function handleHealthConsentAccept() {
|
||||
saveConsents({ ...consents, health_data: true });
|
||||
setConsents(prev => ({ ...prev, health_data: true }));
|
||||
setShowHealthConsent(false);
|
||||
if (pendingTsiScan) {
|
||||
pendingTsiScan();
|
||||
setPendingTsiScan(null);
|
||||
}
|
||||
}
|
||||
|
||||
function handleHealthConsentCancel() {
|
||||
setShowHealthConsent(false);
|
||||
setPendingTsiScan(null);
|
||||
}
|
||||
|
||||
function handleAdminClick() {
|
||||
setScreen('admin');
|
||||
}
|
||||
@@ -170,6 +216,7 @@ function App() {
|
||||
else setShowLogin(true);
|
||||
return;
|
||||
}
|
||||
if (tab === 'privacy') { setScreen('privacy'); return; }
|
||||
}
|
||||
|
||||
let activeView;
|
||||
@@ -232,6 +279,8 @@ function App() {
|
||||
setPrescriptionSearch(name);
|
||||
setScreen('search');
|
||||
}}
|
||||
onTsiScanRequest={handleTsiScanRequest}
|
||||
consents={consents}
|
||||
/>
|
||||
);
|
||||
break;
|
||||
@@ -246,6 +295,9 @@ function App() {
|
||||
case 'admin':
|
||||
activeView = <AdminView />;
|
||||
break;
|
||||
case 'privacy':
|
||||
activeView = <PrivacyView onBack={() => setScreen('home')} />;
|
||||
break;
|
||||
default:
|
||||
activeView = (
|
||||
<HomeView
|
||||
@@ -293,6 +345,16 @@ function App() {
|
||||
{showSaved && currentUser && (
|
||||
<SavedNotifications onClose={() => setShowSaved(false)} onNotificationChange={refreshBadgeCount} />
|
||||
)}
|
||||
|
||||
{showCookieBanner && (
|
||||
<CookieBanner
|
||||
onConsent={handleCookieConsent}
|
||||
onPrivacyClick={() => { setShowCookieBanner(false); setScreen('privacy'); }}
|
||||
/>
|
||||
)}
|
||||
{showHealthConsent && (
|
||||
<HealthConsentModal onAccept={handleHealthConsentAccept} onCancel={handleHealthConsentCancel} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user