diff --git a/index.html b/index.html
index 2361a56..31d6c86 100644
--- a/index.html
+++ b/index.html
@@ -179,6 +179,19 @@ a{color:inherit}
.back-link:hover{color:var(--ink)}
.section-title{font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:var(--gray-500);margin:6px 0 12px}
+.devbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:14px;padding:12px;background:var(--cyan-50);border-radius:10px}
+.devlbl{font-size:13px;color:var(--gray-500);font-weight:600}
+details.edu{border:1px solid var(--gray-200);border-radius:10px;padding:0;margin-bottom:10px;overflow:hidden}
+details.edu summary{padding:13px 16px;font-weight:700;font-size:15px;cursor:pointer;list-style:none;background:var(--gray-100)}
+details.edu summary::-webkit-details-marker{display:none}
+details.edu[open] summary{border-bottom:1px solid var(--gray-200)}
+details.edu .edu-body{padding:14px 16px;font-size:14px;color:var(--gray-500)}
+details.edu .edu-body b{color:var(--ink)}
+details.edu .edu-body li{margin-bottom:6px}
+.iv-line{padding:11px 0;border-bottom:1px solid var(--gray-100)}
+.iv-line:last-child{border-bottom:none}
+.iv-line b{font-size:14px}
+.iv-line .iv-meta{font-size:12px;color:var(--gray-500);margin-top:2px}
.stat-line{display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(--gray-100);font-size:14px}
.stat-line:last-child{border-bottom:none}
@@ -225,7 +238,7 @@ a{color:inherit}
"use strict";
/* ============ ДАННЫЕ (localStorage как «БД») ============ */
-var STORE_KEY = "copd_monitor_v1";
+var STORE_KEY = "copd_monitor_v2";
function seed(){
var now = Date.now();
@@ -276,6 +289,10 @@ function seed(){
],
entries:[
entry("p3",1,8,{spo2:88,sys:142,dia:90,hr:112,rr:26,mmrc:3,cat:[3,3,2,4,4,3,2,3],meds:{"m1@08:00":{taken:false}},note:"усилилась одышка, мокрота гнойная"})
+ ],
+ interventions:[
+ {ts:Date.now()-3600000*3, text:"Связался с пациентом. Усилить О₂ до 3 л/мин, начать преднизолон 30 мг/сут 5 дней, резервный амоксиклав."},
+ {ts:Date.now()-3600000*26, text:"Пациент в красной зоне. Повторить SpO₂ через 30 мин, при <88% — госпитализация."}
]
},
{
@@ -532,6 +549,30 @@ function renderPatient(){
app.appendChild(emptyCard("Пока нет записей. Нажмите «Новая запись», чтобы начать."));
}
+ // Образование и самопомощь
+ var edu = el("div","card");
+ edu.appendChild(el("h3","","📚 Образование и самопомощь",{"style":"margin-bottom:14px"}));
+ edu.appendChild(el("div","muted","Краткие рекомендации при ХОБЛ. Нажмите, чтобы раскрыть.",{"style":"margin-bottom:12px"}));
+ edu.appendChild(eduBlock("🌬 Дыхательная гимнастика",
+ "
Диафрагмальное дыхание: одна рука на животе, вдох через нос — живот надувается; выдох через рот медленно."+
+ "Дыхание через сжатые губы: вдох носом 2 сек, выдох через губы трубочкой 4 сек. Удлиняйте выдох."+
+ "Выполняйте 5–10 минут 3–4 раза в день, особенно при одышке."));
+ edu.appendChild(eduBlock("💊 Техника ингаляции",
+ "Встряхните ДАИ, снимите колпачок, выдохните мимо ингалятора."+
+ "Обхватите мундштук губами, начинайте вдох и нажмите на баллончик одновременно."+
+ "Продолжайте медленный глубокий вдох 3–5 сек, задержите дыхание на 10 сек."+
+ "После ингаляции ГКС — прополощите рот водой."));
+ edu.appendChild(eduBlock("🚦 План действий (светофор)",
+ "🟢 Зелёная зона: всё как обычно — базисная терапия, дневник."+
+ "🟡 Жёлтая зона: SpO₂ 90–94% — спасатель, контроль, связаться с медсестрой."+
+ "🔴 Красная зона: SpO₂ <90% — кислород, бронхолитик, положение, вызов скорой."));
+ edu.appendChild(eduBlock("🚑 Когда вызывать скорую",
+ "SpO₂ < 88% держится более 5 минут или нарастает одышка."+
+ "Одышка в покое не уменьшается через 15–20 минут после бронхолитика."+
+ "Спутанность сознания, синюшность губ, боли в груди."+
+ "Температура > 38,5 °C с нарастающей одышкой."));
+ app.appendChild(edu);
+
// История
if(p.entries.length){
var hc = el("div","card");
@@ -560,6 +601,12 @@ function bpZone(s,d){
}
function mmrcTxt(m){ return ["одышки нет","при быстрой ходьбе","иду медленнее","останавливаюсь ~100м","не могу выйти из дома"][m]||"—"; }
+function eduBlock(title, html){
+ var d=el("details","edu");
+ d.innerHTML=''+title+'';
+ return d;
+}
+
function renderMedsCard(p, entry, showActions){
var c = el("div","card");
c.appendChild(el("h3","","💊 Базисные препараты",{"style":"margin-bottom:6px"}));
@@ -595,6 +642,21 @@ function markMed(p, med, time){
save(state); render(); toast("Приём отмечен: "+med.name);
}
+/* mock-чтение с прибора (имитация Bluetooth) */
+function readDevice(kind){
+ if(kind==="oxy"){
+ var v = 88+Math.floor(Math.random()*9); // 88–96
+ var hr = 64+Math.floor(Math.random()*42); // 64–105
+ $("#spo2").value=v; $("#hr").value=hr;
+ toast("Пульсоксиметр: SpO₂ "+v+"%, ЧСС "+hr);
+ } else {
+ var s=116+Math.floor(Math.random()*34); // 116–149
+ var d=74+Math.floor(Math.random()*20); // 74–93
+ $("#bpSys").value=s; $("#bpDia").value=d;
+ toast("Тонометр: АД "+s+"/"+d);
+ }
+}
+
function historyTable(p){
var t = el("table","hist");
var thead = el("thead"); thead.innerHTML='| Дата | SpO₂ | АД | ЧСС | ЧДД | mMRC | CAT | Зона |
';
@@ -633,6 +695,15 @@ function openDiaryModal(p){
// Жизненные показатели
body.appendChild(el("div","section-title","Показатели"));
+ // приборы (mock Bluetooth)
+ var devBar = el("div","devbar");
+ devBar.appendChild(el("span","devlbl","📡 Считать с прибора:"));
+ var bOxy = el("button","btn ghost sm","🩸 Пульсоксиметр");
+ bOxy.onclick=function(){ readDevice("oxy"); };
+ var bBp = el("button","btn ghost sm","🩺 Тонометр");
+ bBp.onclick=function(){ readDevice("bp"); };
+ devBar.appendChild(bOxy); devBar.appendChild(bBp);
+ body.appendChild(devBar);
var fg = el("div","form-grid");
fg.appendChild(field('spo2','number','🩸 Сатурация (SpO₂)','90',true,"%, 50–100"));
fg.appendChild(bpField());
@@ -890,6 +961,37 @@ function openPatientDetail(id){
} else {
app.appendChild(emptyCard("Нет записей по пациенту."));
}
+
+ // вмешательства и назначения врача
+ app.appendChild(interventionsCard(p));
+}
+
+function interventionsCard(p){
+ var c=el("div","card");
+ c.appendChild(el("h3","","📝 Вмешательства и назначения врача",{"style":"margin-bottom:14px"}));
+ if(!p.interventions) p.interventions=[];
+ if(p.interventions.length){
+ p.interventions.slice().reverse().forEach(function(iv){
+ var row=el("div","iv-line");
+ row.innerHTML=''+iv.text+''+fmtTime(iv.ts)+'
';
+ c.appendChild(row);
+ });
+ } else {
+ c.appendChild(el("div","muted","Пока нет записей.",{"style":"margin-bottom:12px"}));
+ }
+ var ta=el("textarea","input"); ta.id="ivText"; ta.rows=2; ta.placeholder="Записать вмешательство/назначение (напр.: «Усилить О₂ до 3 л/мин, добавить преднизолон 30 мг»)"; ta.style.marginBottom="10px"; ta.style.width="100%";
+ c.appendChild(ta);
+ var btn=el("button","btn sm","Добавить запись");
+ btn.onclick=function(){ addIntervention(p); };
+ c.appendChild(btn);
+ return c;
+}
+function addIntervention(p){
+ var ta=$("#ivText"); var t=(ta&&ta.value||"").trim();
+ if(!t){ toast("Введите текст вмешательства"); return; }
+ if(!p.interventions) p.interventions=[];
+ p.interventions.push({ts:Date.now(), text:t});
+ save(state); openPatientDetail(p.id); toast("Вмешательство записано");
}
function trendCard(p){