| {% 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"> |
|
|
| |
| <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> |
|
|
| |
| |
| |
| |
| <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);"> |
| |
| |
| |
| |
| <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> |
|
|
| |
| <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> |
| |
| <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> |
|
|
| |
| <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> |
|
|
| |
| |
| |
| <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 %} |
|
|