File size: 10,839 Bytes
513cacb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7564c8e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
513cacb
7564c8e
22afef7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
513cacb
22afef7
 
 
 
 
513cacb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7564c8e
 
 
 
 
 
513cacb
 
 
 
 
22afef7
 
 
 
 
513cacb
7564c8e
 
 
 
 
 
513cacb
 
 
7564c8e
 
 
 
 
22afef7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7564c8e
 
 
22afef7
 
 
 
 
 
 
 
 
 
 
 
 
513cacb
 
22afef7
 
 
 
 
 
 
513cacb
 
 
 
 
 
 
 
 
 
 
 
 
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
{% extends "base.html" %}

{% block title %}TalkToDoc - Provider{% endblock %}

{% block body_class %}provider-page{% endblock %}
{% block shell_class %}provider-shell{% endblock %}

{% block header %}
<div class="app-header provider">
  <div class="brand">
    <span class="brand-mark">
      <svg viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/>
      </svg>
    </span>
    <div>
      <h1>TalkToDoc</h1>
      <span class="role-tag">Provider</span>
    </div>
  </div>
</div>
{% endblock %}

{% block content %}

<div id="status-banner" role="alert" aria-live="assertive"></div>

<div class="provider-layout">

<!-- Pending list -->
<section class="step active provider" data-step="list">
  <div class="hero provider">
    <div class="hero-orb-wrap">
      <div class="hero-orb-glow"></div>
      <div class="hero-orb">
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <polyline points="20 6 9 17 4 12"/>
        </svg>
      </div>
    </div>
    <h2><span class="queue-heading-text" id="queue-heading">Messages waiting for you</span></h2>
    <p>Review what each patient said, then send your reply.</p>
  </div>

  <!-- "Active" here means "currently open in this workspace" - this app
       has no multi-provider login/claim system, so that's the only honest
       meaning available. It's a single client-side slot, not a backend
       concept. -->
  <div class="queue-tabs" role="tablist">
    <button type="button" class="queue-tab active" data-tab="waiting" role="tab" aria-selected="true">
      Waiting <span class="tab-count" id="tab-count-waiting">0</span>
    </button>
    <button type="button" class="queue-tab" data-tab="active" role="tab" aria-selected="false">
      Active <span class="tab-count" id="tab-count-active">0</span>
    </button>
    <button type="button" class="queue-tab" data-tab="completed" role="tab" aria-selected="false">
      Completed <span class="tab-count" id="tab-count-completed">0</span>
    </button>
  </div>

  <div class="card">
    <input type="text" class="search-input" id="queue-search" placeholder="Search by language or message" aria-label="Search consultations" style="margin-bottom: var(--space-4);">
    <!-- Filter chips and sort toggle only appear on the Completed tab,
         where a provider might want to narrow by language or reverse order.
         Hidden on Waiting/Active tabs via JS since filtering a short live
         queue adds friction more than value. -->
    <div id="completed-controls" style="display: none; margin-bottom: var(--space-4);">
      <div class="filter-chip-row" id="language-filter-chips" role="group" aria-label="Filter by language">
        <button type="button" class="filter-chip active" data-filter="all">All languages</button>
        <button type="button" class="filter-chip" data-filter="english">English</button>
        <button type="button" class="filter-chip" data-filter="yoruba">Yoruba</button>
        <button type="button" class="filter-chip" data-filter="hausa">Hausa</button>
        <button type="button" class="filter-chip" data-filter="igbo">Igbo</button>
        <button type="button" class="filter-chip" data-filter="pidgin">Pidgin</button>
      </div>
      <button type="button" class="sort-toggle-btn" id="sort-toggle-btn" aria-label="Toggle sort order">
        <svg id="sort-icon-asc" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display:none"><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></svg>
        <svg id="sort-icon-desc" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="19" x2="12" y2="5"/><polyline points="5 12 12 5 19 12"/></svg>
        <span id="sort-label">Newest first</span>
      </button>
    </div>
    <div id="pending-list"></div>
    <div class="empty-state" id="empty-pending" style="display: none;">
      <svg class="empty-state-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
      <p class="empty-state-title" id="empty-pending-title"></p>
      <p class="empty-state-body" id="empty-pending-body"></p>
    </div>
  </div>
</section>

<!-- Respond to a selected interaction -->
<section class="step provider" data-step="respond">
  <div class="detail-placeholder" id="detail-placeholder">
    <span class="brand-mark detail-placeholder-mark">
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
        <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/>
      </svg>
    </span>
    <p>Select a message from the list to read it and reply.</p>
  </div>

  <div id="detail-content" style="display: none;">
    <div class="card">
      <div class="workspace-meta">
        <span>Reference number: <span class="interaction-id" id="respond-interaction-id"></span></span>
        <span class="status-badge waiting" id="respond-status-badge">Waiting for your reply</span>
      </div>
      <p class="helper-text" id="respond-meta-line"></p>

      <div class="chat-thread">
        <div class="chat-bubble from-patient">
          <span class="chat-label" id="respond-language-label">Patient</span>
          <span id="respond-translated-text"></span>
        </div>
        <!-- Provider's reply, only visible in read-only (completed) mode -->
        <div class="chat-bubble from-provider" id="respond-provider-bubble" style="display:none;">
          <span class="chat-label">Your reply (translated)</span>
          <span id="respond-provider-reply-text"></span>
        </div>
      </div>

      <details class="original-transcript">
        <summary>Show original message (<span id="respond-original-language"></span>)</summary>
        <p id="respond-original-text"></p>
      </details>

      <div class="nlu-summary" id="respond-nlu-summary"></div>
    </div>

    <div class="card" id="patient-history-card" style="display: none;">
      <h3>This patient's other consultations</h3>
      <div id="patient-history-list"></div>
    </div>

    <!-- Compose area: shown only for unanswered (waiting) consultations -->
    <div id="compose-area">
      <div class="card">
        <label for="response-text-input">Your reply (in English)</label>
        <div class="chip-row" id="quick-reply-chips">
          <button type="button" class="chip" data-text="Please come in for a check-up so we can look at this properly.">Come in for a check-up</button>
          <button type="button" class="chip" data-text="Please rest and stay hydrated, drink plenty of water.">Rest and stay hydrated</button>
          <button type="button" class="chip" data-text="This doesn't sound urgent. Please monitor it and reach out again if it gets worse.">Monitor and follow up</button>
          <button type="button" class="chip" data-text="I need a bit more detail, please describe your symptoms further.">Need more detail</button>
        </div>
        <textarea id="response-text-input" rows="4" placeholder="Type your reply here"></textarea>

        <button type="button" class="btn btn-secondary" id="preview-response-btn" style="margin-top: var(--space-3); width: 100%;">
          <span class="btn-spinner spinner" style="display: none;"></span>
          <span class="btn-label">Preview what the patient will get</span>
        </button>

        <div class="preview-block" id="preview-block" style="display: none;">
          <p class="preview-label">Preview — exactly what the patient will receive</p>
          <div class="chat-bubble from-provider" id="preview-text-bubble"></div>
          <div class="audio-player">
            <audio id="preview-audio" preload="metadata"></audio>
            <div class="audio-player-controls">
              <button type="button" class="audio-btn" id="preview-audio-play-btn" aria-label="Play">
                <svg class="icon-play" viewBox="0 0 24 24" fill="currentColor"><polygon points="6 3 20 12 6 21 6 3"/></svg>
                <svg class="icon-pause" viewBox="0 0 24 24" fill="currentColor" style="display: none;"><rect x="5" y="3" width="5" height="18" rx="1"/><rect x="14" y="3" width="5" height="18" rx="1"/></svg>
              </button>
              <button type="button" class="audio-btn audio-btn-sm" id="preview-audio-replay-btn" aria-label="Replay from start">
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"/></svg>
              </button>
              <span class="audio-time" id="preview-audio-current-time">0:00</span>
              <input type="range" class="audio-seek" id="preview-audio-seek" min="0" max="0" value="0" step="0.1" aria-label="Seek audio position">
              <span class="audio-time" id="preview-audio-duration">0:00</span>
            </div>
          </div>
        </div>
      </div>

      <div class="btn-row">
        <button type="button" class="btn btn-secondary" id="back-to-list">Back</button>
        <button type="button" class="btn btn-provider" id="submit-response">
          <span class="btn-icon">
            <svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
              <polyline points="20 6 9 17 4 12"/>
            </svg>
          </span>
          <span class="btn-spinner spinner" style="display: none;"></span>
          <span class="btn-label">Send reply</span>
        </button>
      </div>
    </div>

    <!-- Read-only view: shown when a completed consultation is opened.
         No textarea, no Send button — a completed consultation is a
         record, not a work item. -->
    <div id="readonly-area" style="display: none;">
      <div class="btn-row">
        <button type="button" class="btn btn-secondary" id="back-to-list-readonly">Back</button>
      </div>
    </div>
  </div>
</section>

</div>

<div class="nav-link provider"><a href="/">Go to patient view</a></div>

{% endblock %}

{% block scripts %}
<script src="{{ url_for('static', filename='js/provider.js') }}"></script>
{% endblock %}