DotNet_Capstone_Project/.Net Capstone Project/dashboard28082026 updated.html

408 lines
19 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Dashboard — Clinical Insight Pro</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="css/styles.css?v=20260828a">
</head>
<body>
<div class="spinner-overlay" id="spinnerOverlay">
<div class="spinner-border text-success" role="status" style="width:3rem;height:3rem;"></div>
</div>
<nav class="navbar navbar-expand-lg navbar-ci">
<div class="container-fluid px-4">
<a class="navbar-brand" href="index.html">🩺 Clinical Insight Pro</a>
<div class="ms-auto d-flex align-items-center gap-3">
<span class="navbar-text" id="clinicianLabel">Clinician</span>
<button class="btn btn-outline-light btn-sm" id="logoutBtn">Sign out</button>
</div>
</div>
</nav>
<div class="app-shell">
<aside class="app-sidebar" id="appSidebar"></aside>
<main class="app-main">
<div class="container-fluid px-4 my-4">
<!-- Dashboard summary — click any card to browse that resource across every patient -->
<div class="stats-row" id="statsRow">
<div class="stat-card stat-patients" data-resource="patients">
<div class="stat-icon">🧑‍⚕️</div>
<div class="stat-value" id="stat_patients"></div>
<div class="stat-label">Patients</div>
<div class="stat-arrow"></div>
</div>
<div class="stat-card stat-conditions" data-resource="conditions">
<div class="stat-icon">🩺</div>
<div class="stat-value" id="stat_conditions"></div>
<div class="stat-label">Conditions</div>
<div class="stat-arrow"></div>
</div>
<div class="stat-card stat-medications" data-resource="medications">
<div class="stat-icon">💊</div>
<div class="stat-value" id="stat_medications"></div>
<div class="stat-label">Medications</div>
<div class="stat-arrow"></div>
</div>
<div class="stat-card stat-allergies" data-resource="allergies">
<div class="stat-icon">⚠️</div>
<div class="stat-value" id="stat_allergies"></div>
<div class="stat-label">Allergies</div>
<div class="stat-arrow"></div>
</div>
<div class="stat-card stat-observations" data-resource="observations">
<div class="stat-icon">📈</div>
<div class="stat-value" id="stat_observations"></div>
<div class="stat-label">Observations</div>
<div class="stat-arrow"></div>
</div>
<div class="stat-card stat-encounters" data-resource="encounters">
<div class="stat-icon">📅</div>
<div class="stat-value" id="stat_encounters"></div>
<div class="stat-label">Encounters</div>
<div class="stat-arrow"></div>
</div>
<div class="stat-card stat-careplans" data-resource="careplans">
<div class="stat-icon">📋</div>
<div class="stat-value" id="stat_careplans"></div>
<div class="stat-label">Care Plans</div>
<div class="stat-arrow"></div>
</div>
</div>
<!-- Shows what the stat cards above are currently scoped to: a selected
patient, a search match, or (hidden) totals across everyone. -->
<div id="statsScopeLabel" class="stats-scope-label d-none mb-3"></div>
<div class="row g-4">
<!-- Patient selector -->
<div class="col-lg-3">
<div class="card-ci p-3 mb-4">
<h6 class="mb-3 d-flex justify-content-between align-items-center">
Patients
<button class="btn btn-ci-primary btn-sm" id="newPatientBtn" title="Add a new patient">+ New</button>
</h6>
<input type="text" class="form-control form-control-sm mb-2" id="patientSearchInput"
placeholder="Search by name or patient ID…" autocomplete="off">
<div id="patientList" class="patient-list-scroll">Loading…</div>
<div id="patientSearchEmpty" class="text-muted-ci small text-center py-3 d-none">No patients match "<span id="patientSearchEmptyTerm"></span>".</div>
</div>
</div>
<!-- Main content -->
<div class="col-lg-9">
<div id="noPatientState" class="card-ci p-4">
<div class="d-flex justify-content-between align-items-center flex-wrap gap-2 mb-4">
<h5 class="mb-0">CDS Alert Overview — all patients</h5>
<div class="d-flex gap-2">
<select class="form-select form-select-sm" id="overallCdsMonth" style="width:auto"></select>
<select class="form-select form-select-sm" id="overallCdsYear" style="width:auto"></select>
</div>
</div>
<div class="d-flex align-items-center gap-4 flex-wrap">
<div id="overallCdsPie" style="width:180px;height:180px;border-radius:50%;flex-shrink:0"></div>
<div>
<div class="fs-5 fw-semibold mb-2" id="overallPatientCount">— patients</div>
<div id="overallCdsLegend" class="d-flex flex-column gap-2"></div>
</div>
</div>
<div id="overallCdsEmpty" class="text-muted-ci text-center py-4 d-none">No CDS alerts for this month.</div>
</div>
<div id="patientContent" class="d-none">
<!-- Patient header -->
<div class="pt-hero mb-3">
<div class="pt-avatar-lg" id="patientAvatar"></div>
<div class="flex-grow-1">
<div style="font-size:1.3rem;font-weight:600" id="patientName"></div>
<div style="opacity:0.85;font-size:0.9rem" id="patientMeta"></div>
</div>
<span class="badge-fhir">HL7 FHIR R4 · Medplum</span>
</div>
<div class="pt-info-grid mb-4">
<div class="pt-info-tile"><div class="pt-info-label">Gender</div><div class="pt-info-value" id="patientInfoGender"></div></div>
<div class="pt-info-tile"><div class="pt-info-label">Age</div><div class="pt-info-value" id="patientInfoAge"></div></div>
<div class="pt-info-tile"><div class="pt-info-label">Blood group</div><div class="pt-info-value" id="patientInfoBlood"></div></div>
<div class="pt-info-tile"><div class="pt-info-label">Mobile</div><div class="pt-info-value" id="patientInfoMobile"></div></div>
<div class="pt-info-tile"><div class="pt-info-label">Date of birth</div><div class="pt-info-value" id="patientInfoDob"></div></div>
<div class="pt-info-tile"><div class="pt-info-label">MRN</div><div class="pt-info-value" id="patientInfoMrn"></div></div>
</div>
<ul class="nav nav-pills mb-3" id="dashboardTabs">
<li class="nav-item"><button class="nav-link active" data-tab="chart">Chart</button></li>
<li class="nav-item"><button class="nav-link" data-tab="risk">Risk Assessment</button></li>
<li class="nav-item"><button class="nav-link" data-tab="cds">CDS Alerts <span id="alertCountBadge" class="badge bg-danger d-none"></span></button></li>
<li class="nav-item"><button class="nav-link" data-tab="careplans">Care Plans</button></li>
</ul>
<!-- CHART TAB -->
<div class="tab-pane" id="tab-chart">
<div class="row g-3">
<div class="col-md-6">
<div class="card-ci p-4 mb-4">
<h6 class="d-flex justify-content-between align-items-center">Active Conditions
<button class="btn btn-outline-secondary btn-sm" data-add="condition">+ Add</button>
</h6>
<div id="conditionsList" class="mt-2 chart-list-scroll"></div>
</div>
<div class="card-ci p-4">
<h6 class="d-flex justify-content-between align-items-center">Allergies &amp; Intolerances
<button class="btn btn-outline-secondary btn-sm" data-add="allergy">+ Add</button>
</h6>
<div id="allergiesList" class="mt-2 chart-list-scroll"></div>
</div>
</div>
<div class="col-md-6">
<div class="card-ci p-4 mb-4">
<h6 class="d-flex justify-content-between align-items-center">Active Medications
<button class="btn btn-outline-secondary btn-sm" data-add="medication">+ Add</button>
</h6>
<div id="medicationsList" class="mt-2 chart-list-scroll"></div>
</div>
<div class="card-ci p-4 mb-4">
<h6 class="d-flex justify-content-between align-items-center">Recent Observations
<button class="btn btn-outline-secondary btn-sm" data-add="observation">+ Add</button>
</h6>
<div id="observationsList" class="mt-2 chart-list-scroll"></div>
</div>
<div class="card-ci p-4">
<h6 class="d-flex justify-content-between align-items-center">Encounters
<button class="btn btn-outline-secondary btn-sm" data-add="encounter">+ Add</button>
</h6>
<div id="encountersList" class="mt-2 chart-list-scroll"></div>
</div>
</div>
</div>
</div>
<!-- RISK TAB -->
<div class="tab-pane d-none" id="tab-risk">
<div class="card-ci p-4 mb-4">
<h6 class="mb-3">Assessment History</h6>
<div id="riskHistoryEmpty" class="text-muted-ci text-center py-3">No risk assessments on file yet — run the questionnaire below to create the first one.</div>
<div id="riskSummaryWrap" class="d-none d-flex align-items-center gap-4 mb-4 flex-wrap">
<div id="riskSummaryPie" style="width:100px;height:100px;border-radius:50%;flex-shrink:0"></div>
<div id="riskSummaryLegend" class="d-flex flex-column gap-1"></div>
</div>
<div id="riskHistoryBody"></div>
</div>
<div class="row g-4">
<div class="col-md-5">
<div class="card-ci p-4">
<h6 class="mb-3">Risk Questionnaire</h6>
<form id="riskForm">
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="q_smoker">
<label class="form-check-label" for="q_smoker">Current smoker</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="q_family">
<label class="form-check-label" for="q_family">Family history of heart disease</label>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="q_hosp">
<label class="form-check-label" for="q_hosp">Hospitalized within the last 12 months</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="q_newCondition">
<label class="form-check-label" for="q_newCondition">New chronic condition diagnosed in the past 6 months</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="q_highHr">
<label class="form-check-label" for="q_highHr">Resting heart rate over 100 bpm</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="q_severeAllergy">
<label class="form-check-label" for="q_severeAllergy">History of severe/anaphylactic allergic reaction</label>
</div>
<div class="form-check mb-2">
<input class="form-check-input" type="checkbox" id="q_missedMeds">
<label class="form-check-label" for="q_missedMeds">Missed medication doses recently</label>
</div>
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="q_erVisit">
<label class="form-check-label" for="q_erVisit">ER or urgent care visit in the past 3 months</label>
</div>
<div class="mb-3">
<label class="form-label small">BMI</label>
<input type="number" step="0.1" class="form-control" id="q_bmi" placeholder="e.g. 28.4">
</div>
<div class="mb-3">
<label class="form-label small">Pain score (010)</label>
<input type="range" min="0" max="10" class="form-range" id="q_pain">
<div class="text-muted-ci small text-center" id="q_pain_val">0</div>
</div>
<div id="dynamicRiskQuestions"></div>
<button type="submit" class="btn btn-ci-primary w-100 mt-2">Run Risk Scoring</button>
</form>
</div>
</div>
<div class="col-md-7">
<div class="card-ci p-4 h-100" id="riskResultCard">
<h6 class="mb-3">Result</h6>
<div id="riskResultEmpty" class="text-muted-ci text-center py-5">Complete the questionnaire and run scoring to see results.</div>
<div id="riskResultBody" class="d-none">
<div class="text-center mb-3">
<div class="score-gauge" id="scoreGauge"></div>
<div class="mt-2"><span class="risk-badge" id="riskLevelBadge"></span></div>
</div>
<h6 class="mt-4">Contributing Factors</h6>
<ul id="riskFactorsList" class="small"></ul>
</div>
</div>
</div>
</div>
</div>
<!-- CDS TAB -->
<div class="tab-pane d-none" id="tab-cds">
<div class="card-ci p-4">
<div class="d-flex justify-content-between align-items-center mb-3">
<h6 class="mb-0">CDS Rules Engine</h6>
<button class="btn btn-ci-primary btn-sm" id="evaluateCdsBtn">Evaluate Encounter</button>
</div>
<div id="cdsAlertsContainer">
<div class="text-muted-ci text-center py-5">Click "Evaluate Encounter" to screen for drug-allergy conflicts and guideline gaps.</div>
</div>
</div>
</div>
<!-- CARE PLANS TAB -->
<div class="tab-pane d-none" id="tab-careplans">
<div class="card-ci p-4">
<div class="d-flex justify-content-between align-items-center mb-3">
<h6 class="mb-0">Care Plans &amp; Service Requests</h6>
<button class="btn btn-outline-secondary btn-sm" id="refreshCarePlansBtn">Refresh</button>
</div>
<div class="table-responsive">
<table class="table table-sm align-middle">
<thead>
<tr>
<th>Title</th>
<th>Triggered by</th>
<th>Status</th>
<th>Created</th>
</tr>
</thead>
<tbody id="carePlansTableBody">
<tr><td colspan="4" class="text-muted-ci text-center py-4">No care plans yet.</td></tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
<footer class="container-fluid text-center footer-ci mb-4">
Clinical Insight Pro — SMART on FHIR · HL7 FHIR R4 · Medplum · .NET 8 Web API
</footer>
<div class="toast-container position-fixed bottom-0 end-0 p-3" id="toastContainer"></div>
<!-- New Patient modal -->
<div class="modal fade" id="newPatientModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Add Patient</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="newPatientForm">
<div class="modal-body">
<div class="row g-2">
<div class="col-6"><label class="form-label small">First name</label><input required class="form-control" id="np_firstName"></div>
<div class="col-6"><label class="form-label small">Last name</label><input required class="form-control" id="np_lastName"></div>
<div class="col-6"><label class="form-label small">Date of birth</label><input required type="date" class="form-control" id="np_dob"></div>
<div class="col-6">
<label class="form-label small">Gender</label>
<select class="form-select" id="np_gender">
<option value="female">female</option>
<option value="male">male</option>
<option value="other">other</option>
<option value="unknown">unknown</option>
</select>
</div>
<div class="col-12"><label class="form-label small">Medical record number (optional)</label><input class="form-control" id="np_mrn"></div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-ci-primary">Create Patient</button>
</div>
</form>
</div>
</div>
</div>
<!-- Generic "add chart resource" modal — its fields are built dynamically
per resource type (condition/observation/allergy/medication/encounter)
by dashboard.js so one modal covers all five FHIR resource forms. -->
<div class="modal fade" id="addResourceModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="addResourceModalTitle">Add</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<form id="addResourceForm">
<div class="modal-body row g-2" id="addResourceModalBody"></div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-ci-primary">Save</button>
</div>
</form>
</div>
</div>
</div>
<!-- Resource browser — shows one resource type across every patient. Opened
by clicking a stat card. Clicking a patient chip inside it jumps to
that patient's chart. -->
<div class="modal fade" id="resourceBrowserModal" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="resourceBrowserTitle">Browse</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div id="resourceBrowserLoading" class="text-center text-muted-ci py-4 d-none">Loading…</div>
<div class="table-responsive">
<table class="table table-sm resource-browser-table">
<thead>
<tr id="resourceBrowserHead"></tr>
</thead>
<tbody id="resourceBrowserBody"></tbody>
</table>
</div>
<div id="resourceBrowserEmpty" class="text-muted-ci text-center py-4 d-none">No records found.</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="js/config.js?v=20260828a"></script>
<script src="js/sidebar.js?v=20260828a"></script>
<script src="js/api.js?v=20260828a"></script>
<script src="js/dashboard.js?v=20260828a"></script>
</body>
</html>