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 %}
|