import { Download, Mail, Linkedin, MoreHorizontal } from 'lucide-react' import { useState, useRef, useEffect, useCallback } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { patient } from '@/data/patient' interface PatientBannerProps { isMobile?: boolean isTablet?: boolean isCondensed?: boolean } export function PatientBanner({ isMobile = false, isTablet = false, isCondensed = false }: PatientBannerProps) { const prefersReducedMotion = typeof window !== 'undefined' ? window.matchMedia('(prefers-reduced-motion: reduce)').matches : false if (isMobile) { return } const shouldCondense = isTablet || isCondensed return (
{shouldCondense ? ( ) : ( )}
) } function MobileBanner() { const [showOverflow, setShowOverflow] = useState(false) const menuRef = useRef(null) const handleClickOutside = useCallback((e: MouseEvent) => { if (menuRef.current && !menuRef.current.contains(e.target as Node)) { setShowOverflow(false) } }, []) useEffect(() => { if (showOverflow) { document.addEventListener('mousedown', handleClickOutside) return () => document.removeEventListener('mousedown', handleClickOutside) } }, [showOverflow, handleClickOutside]) return (

CHARLWOOD, A (Mr)

| {patient.nhsNumber}
{showOverflow && ( setShowOverflow(false)} > Download CV setShowOverflow(false)} > Email setShowOverflow(false)} > LinkedIn )}
) } function FullBanner() { return (
{/* Row 1: Name, status, badge */}

{patient.name}

{patient.status}
{patient.badge && }
{/* Row 2: Demographics with pipe separators */}
DOB:{' '} {patient.dob} | NHS No:{' '} | {patient.address}
{/* Row 3: Contact details */}
{/* Action buttons */}
} label="Download CV" href="/cv.pdf" /> } label="Email" href={`mailto:${patient.email}`} /> } label="LinkedIn" href={`https://${patient.linkedin}`} external />
) } function CondensedBanner() { return (

{patient.name}

| NHS No:{' '} |
{patient.status}
} label="Download CV" href="/cv.pdf" compact /> } label="Email" href={`mailto:${patient.email}`} compact />
) } /* --- Sub-components --- */ interface NHSNumberWithTooltipProps { condensed?: boolean } function NHSNumberWithTooltip({ condensed = false }: NHSNumberWithTooltipProps) { const [showTooltip, setShowTooltip] = useState(false) const timeoutRef = useRef | null>(null) const handleMouseEnter = () => { timeoutRef.current = setTimeout(() => setShowTooltip(true), 300) } const handleMouseLeave = () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current) timeoutRef.current = null } setShowTooltip(false) } useEffect(() => { return () => { if (timeoutRef.current) clearTimeout(timeoutRef.current) } }, []) return ( setShowTooltip(true)} onBlur={() => setShowTooltip(false)} > {patient.nhsNumber} {showTooltip && ( {patient.nhsNumberTooltip} )} ) } interface StatusDotProps { status: string } function StatusDot({ status }: StatusDotProps) { const colorClass = status === 'Active' ? 'bg-pmr-green' : 'bg-slate-400' return ( ) } interface StatusBadgeProps { badge: string } function StatusBadge({ badge }: StatusBadgeProps) { return ( {badge} ) } interface ActionButtonProps { icon: React.ReactNode label: string href: string external?: boolean compact?: boolean } function ActionButton({ icon, label, href, external, compact }: ActionButtonProps) { return ( {icon} {label} ) }