feat(web): two-stage questionnaires, screening result and diary by result
- Sign-in: centred ЕМИАС card without the sidebar; anonymous entry asks «Депрессия / ПТСР».
- Stage 1 is the same for everyone and follows the fixed order of the MVP questionnaire:
PHQ-2 → trauma filter/TSQ → RUS-AUDIT-S → C-SSRS → context; stage 2 only where stage 1
is positive. Starts without a profile.
- After stage 1 the patient sees a preliminary result (screening, not a diagnosis), stored
with the record; it switches on the diary modules (depression / PTSD).
- Stage 2 diary: morning (sleep, sleep quality, alcohol) and evening (mood, medication,
3 PHQ-9 items in rotation, short PCL-5); C-SSRS since last contact only under risk;
flags on weekly means against the personal norm; scheduled full scales with change
(remission, response, worsening).
- Questionnaire log: GET /me/{token}/results and the «Мои результаты» screen.
- Questionnaires centred without the sidebar and without scale names; «Продолжить позже»
goes home; confirmations are toasts; free-text comments are optional.
- Demo policy config/questionnaire_demo.yaml (INTAKE_DEMO only, not a clinical approval).
ADR-012.
Refs #77
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+52
-46
@@ -1,70 +1,76 @@
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import { AppShell } from "../components/AppShell";
|
||||
import { Icon } from "../components/Icon";
|
||||
import { telHref, useHelp } from "../components/HelpSheet";
|
||||
import { Icon, LogoMark } from "../components/Icon";
|
||||
import { ru } from "../content/ru";
|
||||
|
||||
// A1 · Выбор способа входа
|
||||
// A1 · Вход: без сайдбара, одна карточка по центру. ЕМИАС — основной путь, анонимный — по желанию
|
||||
export function Welcome() {
|
||||
const navigate = useNavigate();
|
||||
const { resources, open } = useHelp();
|
||||
const t = ru.welcome;
|
||||
const emergency = resources[0];
|
||||
|
||||
return (
|
||||
<AppShell signedIn={false}>
|
||||
<div className="stack">
|
||||
<header className="head">
|
||||
<div className="signin-page">
|
||||
<main className="signin" id="main">
|
||||
<div className="signin__brand">
|
||||
<LogoMark size={44} />
|
||||
<span>
|
||||
<span className="signin__name">{ru.product.name}</span>
|
||||
<span className="signin__tag">{ru.product.tagline}</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<section className="signin__card">
|
||||
<h1 className="h1">{t.title}</h1>
|
||||
<p className="lead">{t.lead}</p>
|
||||
</header>
|
||||
|
||||
<div className="entry-grid">
|
||||
<button type="button" className="entry entry--emias" onClick={() => navigate("/emias")}>
|
||||
<span className="entry__top">
|
||||
<span className="tile-icon tile-icon--teal">
|
||||
<Icon name="docPlus" size={26} />
|
||||
</span>
|
||||
<span className="chip chip--teal">{ru.common.recommended}</span>
|
||||
</span>
|
||||
<span className="entry__title">
|
||||
{t.emias.title}
|
||||
<Icon name="chevronRight" />
|
||||
</span>
|
||||
<span className="entry__text">{t.emias.text}</span>
|
||||
</button>
|
||||
|
||||
<button type="button" className="entry" onClick={() => navigate("/anonymous")}>
|
||||
<span className="entry__top">
|
||||
<span className="tile-icon">
|
||||
<Icon name="lock" size={26} />
|
||||
<span className="entry__title">
|
||||
{t.emias.title}
|
||||
<Icon name="chevronRight" />
|
||||
</span>
|
||||
</span>
|
||||
<span className="entry__title">
|
||||
{t.anonymous.title}
|
||||
<Icon name="chevronRight" />
|
||||
</span>
|
||||
<span className="entry__text">{t.anonymous.text}</span>
|
||||
<ul className="signin__perks">
|
||||
{t.emias.perks.map((p) => (
|
||||
<li key={p}>
|
||||
<Icon name="check" size={18} />
|
||||
{p}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<section className="how" aria-labelledby="how-title">
|
||||
<h2 id="how-title" className="h3">
|
||||
{t.howTitle}
|
||||
</h2>
|
||||
<ol className="how__list">
|
||||
{t.how.map((step, i) => (
|
||||
<li key={step.title} className="how__item">
|
||||
<span className="how__num">{i + 1}</span>
|
||||
<span>
|
||||
<span className="how__title">{step.title}</span>
|
||||
<span className="how__text">{step.text}</span>
|
||||
</span>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
<div className="divider" role="separator">
|
||||
<span>{t.or}</span>
|
||||
</div>
|
||||
|
||||
<div className="stack stack--sm">
|
||||
<button type="button" className="btn btn--ghost" onClick={() => navigate("/anonymous")}>
|
||||
<Icon name="lock" size={20} />
|
||||
{t.anonymous.title}
|
||||
</button>
|
||||
<p className="muted small center">{t.anonymous.text}</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<p className="muted small">{t.disclaimer}</p>
|
||||
</div>
|
||||
</AppShell>
|
||||
<div className="signin__foot">
|
||||
<button type="button" className="signin__sos" onClick={open}>
|
||||
<Icon name="phone" size={18} />
|
||||
{ru.help.block}
|
||||
</button>
|
||||
{emergency && (
|
||||
<a className="signin__tel" href={telHref(emergency.phone)}>
|
||||
{emergency.phone}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
<p className="muted small center">{t.disclaimer}</p>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user