File size: 4,661 Bytes
048b72d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"""Reusable chatbot component for all personas.

Renders a styled chat interface with persona-specific context.
Uses st.session_state for message persistence within a session.
"""

import streamlit as st
from services.chat import get_chat_response, get_bot_name, get_greeting


def render_chatbot(
    persona: str,
    resident_name: str = "",
    container_key: str = "",
):
    """Render a full chatbot UI for the given persona.

    Args:
        persona: One of 'caregiver', 'family', 'executive', 'lab_admin'.
        resident_name: Optional resident name for family persona context.
        container_key: Optional unique key suffix to prevent Streamlit widget conflicts.
    """
    bot_name = get_bot_name(persona)
    session_key = f"chat_{persona}_{container_key}" if container_key else f"chat_{persona}"

    # ── Header ──
    icon_map = {
        "caregiver": "🩺",
        "family": "πŸ’™",
        "executive": "πŸ“Š",
        "lab_admin": "πŸ”¬",
    }
    icon = icon_map.get(persona, "πŸ’¬")

    st.markdown(
        f"""<div class="chat-header">
            <span class="chat-header-icon">{icon}</span>
            <span class="chat-header-title">{bot_name}</span>
            <span class="chat-header-badge">AI-Powered</span>
        </div>""",
        unsafe_allow_html=True,
    )

    # ── Initialize messages ──
    if session_key not in st.session_state:
        greeting = get_greeting(persona, resident_name)
        st.session_state[session_key] = [
            {"role": "assistant", "content": greeting}
        ]

    # ── Render message history ──
    chat_container = st.container(height=420)
    with chat_container:
        for msg in st.session_state[session_key]:
            with st.chat_message(
                msg["role"],
                avatar=icon if msg["role"] == "assistant" else None,
            ):
                st.markdown(msg["content"])

    # ── Chat input ──
    family_label = f"Ask about {resident_name}'s care..." if resident_name else "Ask about your loved one's care..."
    placeholder_map = {
        "caregiver": "Ask about vitals, medications, fall risk, handoffs...",
        "family": family_label,
        "executive": "Ask about occupancy, costs, staffing, compliance...",
        "lab_admin": "Ask about TAT, specimens, critical values, infections...",
    }
    placeholder = placeholder_map.get(persona, "Type your question...")

    if prompt := st.chat_input(placeholder, key=f"input_{session_key}"):
        # Add user message
        st.session_state[session_key].append({"role": "user", "content": prompt})

        # Get AI response
        response = get_chat_response(prompt, persona=persona)
        st.session_state[session_key].append({"role": "assistant", "content": response})

        # Rerun to show new messages
        st.rerun()

    # ── Quick suggestion chips ──
    suggestions_map = {
        "caregiver": [
            "Current vitals",
            "Shift handoff",
            "Fall risk",
            "UTI alert status",
            "Sleep analysis",
            "Outstanding tasks",
        ],
        "family": [
            "How did they eat today?",
            "How did they sleep?",
            "How's their mood?",
            "Visiting info",
            "Medications",
        ],
        "executive": [
            "Occupancy trend",
            "Financial impact",
            "Staffing metrics",
            "Fall prevention ROI",
            "Compliance score",
            "Family satisfaction",
        ],
        "lab_admin": [
            "TAT performance",
            "Specimen report",
            "Critical values",
            "Infection rates",
            "Wound AI status",
        ],
    }
    suggestions = suggestions_map.get(persona, [])

    if suggestions:
        st.markdown('<div class="suggestion-chips">', unsafe_allow_html=True)
        cols = st.columns(len(suggestions))
        for i, suggestion in enumerate(suggestions):
            with cols[i]:
                if st.button(
                    suggestion,
                    key=f"chip_{session_key}_{i}",
                    use_container_width=True,
                ):
                    st.session_state[session_key].append(
                        {"role": "user", "content": suggestion}
                    )
                    response = get_chat_response(suggestion, persona=persona)
                    st.session_state[session_key].append(
                        {"role": "assistant", "content": response}
                    )
                    st.rerun()
        st.markdown("</div>", unsafe_allow_html=True)