import React, { useState } from 'react'; import { AlertTriangle } from 'lucide-react'; import { useBillingContext } from '../../services/BillingContext.tsx'; import { useAuthServiceContext } from '../../services'; import { resolveSubscriptionWarning } from './subscriptionWarningCopy'; import { useSponsoredBilling } from './useSponsoredBilling'; /** * The failing-card banner, at the top of every staff view. * * Spencer, 2026-08-14: *"a warning message at the top of admin view... if the card has already failed * as well as 1 retry then a warning should appear at the [top] of all staff views so everyone is aware * the subscription is about to expire and the system will stop working."* * * SEPARATE FROM `BillingGate`, deliberately. That component REPLACES the app when a subscription has * already stopped; this one sits ABOVE a working app while it still works. Folding the two together is * how a warning becomes a lockout - the practice can still see patients, and must, right up to the day * it cannot. */ export const SubscriptionWarningBanner: React.FC = () => { const { dunning, billingMode } = useBillingContext(); const { userRole, USER_ROLES } = useAuthServiceContext(); const [dismissed, setDismissed] = useState(false); const isAdmin = userRole === USER_ROLES.ADMIN; const sponsorship = useSponsoredBilling(billingMode, isAdmin && Boolean(dunning) && dunning?.stage !== 'none'); const warning = resolveSubscriptionWarning(dunning, isAdmin, sponsorship); if (!warning) return null; // Dismissal is honoured only where the copy allows it. At the all-staff stage the flag is false, // so this can never hide the banner about the system stopping. if (warning.dismissible && dismissed) return null; const isError = warning.severity === 'error'; return (
); }; export default SubscriptionWarningBanner;