"""Doctor's patient list ("red zones", idea 2) and, with `?patient=`, the patient card.""" from __future__ import annotations import streamlit as st from dashboard.components import helpers as h from dashboard.components import patient_card, state, ui NAV_ICON = ":material/groups:" COLOR_FILTERS = { "Все": None, "🔴 Красные": "red", "🟡 Жёлтые": "yellow", "⚪ Нет ответа": "grey", "🟢 Стабильные": "green", } def _open(token: str) -> None: st.query_params["patient"] = token def _close() -> None: st.query_params.pop("patient", None) def render_card(token: str) -> None: st.button("Все пациенты", icon=":material/arrow_back:", type="tertiary", on_click=_close) card = state.call(lambda: state.client().patient_card(token)) if card is None: return patient_card.render(card, state.today()) def render_list() -> None: _, doctor_gen = state.doctor_names() today = state.today() patients = state.call(lambda: state.client().patients()) subtitle = "Пациенты на сопровождении между визитами — сначала те, кому нужно внимание сегодня" if today: subtitle += f" · данные на {h.short_date(today)}" head, action = st.columns([4, 1.4], vertical_alignment="bottom") with head: st.html(ui.page_header(f"Кабинет {doctor_gen}", subtitle, kicker="Красные зоны")) with action: if st.button("Подключить пациента", icon=":material/person_add:", type="primary", width="stretch"): st.switch_page(state.CONNECT_PAGE) if patients is None: return items = h.sort_patients(patients) st.html(ui.kpi_tiles(h.kpis(items))) f1, f2 = st.columns([3, 1.4], vertical_alignment="bottom") with f1: choice = st.segmented_control( "Статус", list(COLOR_FILTERS), default="Все", key="status_filter", label_visibility="collapsed" ) with f2: query = st.text_input( "Поиск", placeholder="Поиск по имени или препарату", key="patient_query", label_visibility="collapsed" ) shown = h.filter_patients(items, COLOR_FILTERS.get(choice or "Все"), query or "") head_cols = st.columns([11, 1.5]) with head_cols[0]: st.html(ui.list_header()) if not shown: st.caption("Нет пациентов с выбранным статусом") for p in shown: with st.container(key=f"prow-{p.status_color}-{p.token}"): row, btn = st.columns([11, 1.5], vertical_alignment="center") with row: st.html(ui.patient_row(p)) with btn: st.button( "Открыть", key=f"open-{p.token}", on_click=_open, args=(p.token,), type="primary" if p.status_color == "red" else "secondary", width="stretch", ) st.caption( "Цвет — уровень открытых алертов (ADR-006): 🔴 кризис · 🟡 высокий/умеренный · ⚪ только инфо · 🟢 нет. " "Риск прерывания — индекс правил (пропуски, побочки, намерение бросить, низкое настроение), не ML." ) token = st.query_params.get("patient") if token: render_card(token) else: render_list()