diff --git a/src/components/views/ConsultationsView.tsx b/src/components/views/ConsultationsView.tsx index 18ab8e9..e36bfa3 100644 --- a/src/components/views/ConsultationsView.tsx +++ b/src/components/views/ConsultationsView.tsx @@ -1,8 +1,11 @@ -import { useState, useRef, useEffect } from 'react' +import { useState } from 'react' +import { motion, AnimatePresence } from 'framer-motion' import { ChevronDown } from 'lucide-react' import { consultations } from '@/data/consultations' import type { Consultation, ViewId } from '@/types/pmr' +// ─── Props ────────────────────────────────────────────────────────────────── + interface ConsultationsViewProps { onNavigate?: (view: ViewId, itemId?: string) => void initialExpandedId?: string @@ -10,6 +13,7 @@ interface ConsultationsViewProps { export function ConsultationsView({ initialExpandedId }: ConsultationsViewProps) { const [expandedId, setExpandedId] = useState(initialExpandedId ?? null) + const prefersReducedMotion = typeof window !== 'undefined' ? window.matchMedia('(prefers-reduced-motion: reduce)').matches : false @@ -21,10 +25,10 @@ export function ConsultationsView({ initialExpandedId }: ConsultationsViewProps) return (
-

- Consultation History +

+ Consultation Journal

- + {consultations.length} entries
@@ -44,6 +48,8 @@ export function ConsultationsView({ initialExpandedId }: ConsultationsViewProps) ) } +// ─── Consultation Entry ───────────────────────────────────────────────────── + interface ConsultationEntryProps { consultation: Consultation isExpanded: boolean @@ -57,168 +63,159 @@ function ConsultationEntry({ onToggle, prefersReducedMotion, }: ConsultationEntryProps) { - const contentRef = useRef(null) - const expandedContentRef = useRef(null) - const [height, setHeight] = useState(isExpanded ? undefined : 0) - - useEffect(() => { - if (prefersReducedMotion) { - setHeight(isExpanded ? undefined : 0) - return - } - - if (isExpanded) { - const timer = setTimeout(() => { - setHeight(undefined) - }, 200) - return () => clearTimeout(timer) - } - setHeight(0) - }, [isExpanded, prefersReducedMotion]) - - useEffect(() => { - if (isExpanded && expandedContentRef.current) { - expandedContentRef.current.focus() - } - }, [isExpanded]) - const keyCodedEntry = consultation.codedEntries[0] return (
+ {/* Collapsed header — always visible */} -
+ {/* Expandable content — height-only animation, NO opacity fade */} + {isExpanded && ( - + + + )} -
+
) } +// ─── Status Dot ───────────────────────────────────────────────────────────── + interface StatusDotProps { isCurrent: boolean } function StatusDot({ isCurrent }: StatusDotProps) { return ( - + ) } +// ─── Expanded Content ─────────────────────────────────────────────────────── + interface ExpandedContentProps { consultation: Consultation - prefersReducedMotion: boolean - contentRef: React.RefObject } -function ExpandedContent({ consultation, prefersReducedMotion, contentRef }: ExpandedContentProps) { - const opacity = prefersReducedMotion ? 1 : undefined - const transition = prefersReducedMotion ? 'none' : 'opacity 150ms ease-out' - +function ExpandedContent({ consultation }: ExpandedContentProps) { return ( -
-
+
+
+ {/* Duration */}
- Duration: - {consultation.duration} + Duration: + + {consultation.duration} +
+ {/* HISTORY */} HISTORY -

+

{consultation.history}

+ {/* EXAMINATION */} EXAMINATION
    {consultation.examination.map((item, index) => ( -
  • +
  • - - {item} + {item}
  • ))}
+ {/* PLAN */} PLAN
    {consultation.plan.map((item, index) => ( -
  • +
  • - - {item} + {item}
  • ))}
+ {/* CODED ENTRIES */} CODED ENTRIES
{consultation.codedEntries.map(entry => ( - + ))}
@@ -226,14 +223,18 @@ function ExpandedContent({ consultation, prefersReducedMotion, contentRef }: Exp ) } +// ─── Section Header ───────────────────────────────────────────────────────── + function SectionHeader({ children }: { children: React.ReactNode }) { return ( -

+

{children}

) } +// ─── Coded Entry ──────────────────────────────────────────────────────────── + interface CodedEntryProps { code: string description: string @@ -241,11 +242,8 @@ interface CodedEntryProps { function CodedEntry({ code, description }: CodedEntryProps) { return ( -
- - [{code}] - - {description} +
+ [{code}] {description}
) }