Shared Components
These components live in memberportal/src/components/ and are reused across multiple pages.
Sidebar​
File: components/Sidebar.tsx
The left navigation panel. It renders three groups of links:
| Group | Links |
|---|---|
| Overview | Dashboard, Chat Assistant |
| My Health | Visits, Lab Results, Medications, Conditions, Allergies, Procedures, Immunizations, Medical Records, Health Reports |
| Account | My Profile, Contact Us, Settings, Log Out |
Collapsed mode: On desktop, the sidebar can be collapsed to icon-only mode (60px wide). Each icon shows a tooltip with the link name on hover.
EHR badges: At the bottom of the sidebar, small logo badges show which EHR providers the patient is currently connected to. If none are connected, it shows "No EHR Connected".
PageHeader​
File: components/PageHeader.tsx
A reusable page header with a title and optional subtitle. Most pages use useHeader() to set the title dynamically instead of using this component directly.
EhrSourceBadge​
File: components/EhrSourceBadge.tsx
A small badge shown on health record rows to indicate which EHR system the data came from (Epic, Healow, MEDITECH, or Unknown).
It reads the identifier[].system field of the FHIR resource to determine the source:
urn:epic:→ Epic badgeurn:healow:→ Healow badgeurn:meditech:→ MEDITECH badge
ResourceChatDrawer​
File: components/ResourceChatDrawer.tsx
A slide-in drawer that opens the AI chat pre-loaded with a specific FHIR resource as context. Used on the Lab Results and other pages via the "Explain" or chat icon button.
FilterDropdown​
File: components/FilterDropdown.tsx
A reusable dropdown filter component used on list pages (Lab Results, Conditions, etc.) to filter by EHR provider, status, or other criteria.
Accepts a FilterGroup[] prop that defines which filter options to show.
StatCard​
File: components/StatCard.tsx
A summary card with a number, label, delta indicator, and icon. Currently commented out on the Dashboard but available for future use.
LineChart​
File: components/LineChart.tsx
Renders a simple line chart for showing a lab value trend over time. Used in the Lab Results page trend drawer.
Loading​
File: components/Loading.tsx
A centered loading spinner shown while pages are waiting for data. Used as the <Suspense> fallback in App.tsx.
IdleTimeoutGuard​
File: components/IdleTimeoutGuard.tsx
Wraps the entire authenticated app. Monitors user activity and shows a warning modal when the session is about to expire. Automatically signs the patient out if they do not respond.
Uses useIdleTimeout hook internally. See Contexts & Hooks for details.
ProfileDropdown​
File: components/ProfileDropdown.tsx
The patient's avatar/name shown in the top-right corner of the header. Clicking it opens a dropdown with links to Profile, Settings, and Sign Out.
MicrosoftSignInButton​
File: components/MicrosoftSignInButton.tsx
A styled "Sign in with Microsoft" button used on the Sign In page. Triggers the Microsoft SSO OAuth redirect when clicked.
ScrollToTop​
File: components/ScrollToTop.tsx
A floating button that appears when the patient scrolls down and scrolls them back to the top of the page when clicked.
ExplainLink​
File: components/ExplainLink.tsx
A small "Explain" link shown next to health record items. Clicking it opens the Chat Assistant with that specific resource pre-loaded as context. Uses URL params ?explain=ResourceType/id&topic=lab.
PatientTimeline​
File: components/PatientTimeline.tsx
A chronological timeline of all patient health events (encounters, observations, medications, procedures, documents). Currently commented out on the Dashboard but built and available.
InfoButton / InfoSection​
Files: components/InfoButton.tsx, components/InfoSection.tsx
Reusable info tooltip and section components for displaying explanatory text alongside data.
PageSizeSelector​
File: components/PageSizeSelector.tsx
A dropdown that lets patients choose how many rows to show per page in data tables (e.g., 10, 25, 50).
ChartChatLogo​
File: components/ChartChatLogo.tsx
The ChartChat logo SVG component used on the Sign In page.
NotificationBell​
File: components/NotificationBell.tsx
The bell icon in the top header bar. Shows a red badge with the unread notification count. Clicking it opens a slide-in drawer (400px wide, right side) showing all notifications.
Each notification shows:
- Colored icon based on type (green check for sync complete, orange lock for EHR expired, etc.)
- Title, message, and relative timestamp ("2m ago", "3h ago")
- Optional action button that navigates to a path (e.g., "Go to Settings →")
- Dismiss (×) button to delete the notification
Drawer header includes Mark all read and Clear all buttons.
Uses useNotifications() from NotificationContext internally.
FhirDataTable​
File: components/FhirDataTable.tsx
A generic paginated, sortable data table used by all list pages (Lab Results, Medications, Conditions, Visits, etc.). Wraps mantine-datatable's DataTable with ChartChat-specific styling.
Props​
| Prop | Description |
|---|---|
records | Array of data rows |
totalRecords | Total count for pagination display |
page / onPageChange | Current page and change handler |
pageSize | Rows per page |
sortStatus / onSortStatusChange | Current sort column/direction |
height | CSS height string (use tableHeight() from useFhirPagedData) |
columns | DataTableColumn[] column definitions |
onRowClick | Optional row click handler |
noRecordsText / noRecordsIcon | Empty state content |
Usage​
<FhirDataTable
records={paginate(sorted)}
totalRecords={sorted.length}
page={page}
onPageChange={setPage}
pageSize={pageSize}
sortStatus={sortStatus}
onSortStatusChange={setSortStatus}
height={tableHeight(sorted.length)}
columns={columns}
onRowClick={({ record }) => navigate(`/lab-results/${record.id}`)}
/>
TableToolbar​
File: components/TableToolbar.tsx
A toolbar that sits above FhirDataTable. Combines tabs, search, filters, and page size selector in one row.
Props​
| Prop | Description |
|---|---|
tabs | Array of { value, label, count } — renders tab buttons on the left. Tabs with count=0 are hidden. |
activeTab / onTabChange | Active tab state |
title | Shown instead of tabs when no tabs are defined |
pageSize / onPageSizeChange | Page size selector (right side) |
searchQuery / onSearchChange | Search input (right side) |
filterGroups / filterValues / onFilterChange | Filter dropdown (right side) |
Usage​
<TableToolbar
tabs={[
{ value: null, label: 'All', count: records.length },
{ value: 'active', label: 'Active', count: activeCount },
]}
activeTab={activeTab}
onTabChange={setActiveTab}
pageSize={pageSize}
onPageSizeChange={setPageSize}
searchQuery={searchQuery}
onSearchChange={setSearchQuery}
/>
TranslatedText​
File: components/TranslatedText.tsx
Renders a skeleton placeholder while patient-mode translations are loading, then shows the translated value (or raw fallback) once they arrive. All Mantine Text props are forwarded.
Props​
| Prop | Description |
|---|---|
showSkeleton | When true, renders a skeleton instead of text |
value | Translated string from usePatientTranslate — shown when defined |
fallback | Raw clinical value shown when no translation is available |
Usage​
<TranslatedText
showSkeleton={showSkeletons}
value={translations['conditions']?.[id]?.plain_name}
fallback={condition.code?.text ?? 'Unknown'}
size="sm"
/>
TranslatedBadge​
File: components/TranslatedBadge.tsx
Same concept as TranslatedText but renders a Mantine Badge instead of Text. Used for status fields (e.g., condition status, medication status) that need both translation and color coding.
StatCardGrid​
File: components/StatCardGrid.tsx
A responsive grid layout for displaying multiple StatCard components. Handles the grid columns and spacing so individual pages don't need to manage layout.