feat(web): full desktop layout instead of a stretched phone view

- focus screens: question and context on the left, answers on the right in
  one wide card; consent text and the 0–10 scale in one wide column
- today: dashboard with tasks, this week's doses and quick actions side by
  side; meds / doctor / profile in two-column grids; welcome gets «Как это
  работает» steps
- fix: 0–10 scale no longer overflows narrow containers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-04 08:25:17 +03:00
co-authored by Claude Opus 5.5
parent f233c1e5ca
commit 40c242bb1a
10 changed files with 558 additions and 192 deletions
+53 -59
View File
@@ -322,70 +322,59 @@ export function Flow() {
const top = (
<TopBar onBack={home}>{step.kind === "choice" && step.progress && <Progress {...step.progress} />}</TopBar>
);
let body: ReactNode;
// Phone: one column. Desktop: question and context on the left, answers and actions on the right.
let lead: ReactNode;
let act: ReactNode;
switch (step.kind) {
case "consent":
body = (
lead = (
<>
<Head title={ru.flow.consentTitle} lead={[]} icon="shield" />
<div className="panel panel--scroll">
<Body texts={[...step.lead, step.title].filter(Boolean)} />
</div>
<div className="btn-row">
{step.buttons.map((b, i) => (
<button
key={b.data}
type="button"
className={i === 0 ? "btn btn--primary" : "btn btn--outline"}
disabled={dialog.busy}
onClick={() => press(b)}
>
{b.label}
</button>
))}
</div>
</>
);
act = (
<div className="btn-row btn-row--stack-desk">
{step.buttons.map((b, i) => (
<button
key={b.data}
type="button"
className={i === 0 ? "btn btn--primary" : "btn btn--outline"}
disabled={dialog.busy}
onClick={() => press(b)}
>
{b.label}
</button>
))}
</div>
);
break;
case "number":
body = (
<>
<Head title={step.title} lead={step.lead} />
<NumberScale key={stepKey} options={step.options} busy={dialog.busy} onSubmit={press} />
</>
);
lead = <Head title={step.title} lead={step.lead} icon="smile" />;
act = <NumberScale key={stepKey} options={step.options} busy={dialog.busy} onSubmit={press} />;
break;
case "actions":
body = (
<>
<div className="reminder">
<span className="tile-icon tile-icon--teal tile-icon--xl">
<Icon name="pill" size={34} />
</span>
<h1 className="h1 center">{step.title || ru.meds.reminderTitle}</h1>
<Body texts={step.lead} />
</div>
<MedActions options={step.options} busy={dialog.busy} onPress={press} />
</>
lead = (
<div className="reminder">
<span className="tile-icon tile-icon--teal tile-icon--xl">
<Icon name="pill" size={34} />
</span>
<h1 className="h1 center">{step.title || ru.meds.reminderTitle}</h1>
<Body texts={step.lead} />
</div>
);
act = <MedActions options={step.options} busy={dialog.busy} onPress={press} />;
break;
case "text":
body = (
<>
<Head title={step.title} lead={step.lead} />
<FreeText
key={stepKey}
skip={step.skip}
busy={dialog.busy}
onSend={say}
onSkip={press}
onExit={home}
/>
</>
lead = <Head title={step.title} lead={step.lead} icon="edit" />;
act = (
<FreeText key={stepKey} skip={step.skip} busy={dialog.busy} onSend={say} onSkip={press} onExit={home} />
);
break;
case "crisis":
body = (
lead = (
<>
<header className="head">
<span className="tile-icon tile-icon--teal tile-icon--xl">
@@ -393,15 +382,19 @@ export function Flow() {
</span>
<h1 className="h1">{ru.flow.supportTitle}</h1>
</header>
<div className="panel">
<Body texts={[step.text]} />
</div>
</>
);
act = (
<>
<div className="hotlines">
{resources.map((r) => (
<HotlineCard key={r.phone} r={r} />
))}
</div>
<Breathing />
<div className="panel">
<Body texts={[step.text]} />
</div>
{step.buttons.map((b) => (
<button key={b.data} type="button" className="btn btn--outline" disabled={dialog.busy} onClick={() => press(b)}>
{b.label}
@@ -423,9 +416,9 @@ export function Flow() {
);
break;
case "plan":
body = (
lead = <Head title={step.title || ru.flow.planTitle} lead={step.lead} icon="shield" />;
act = (
<>
<Head title={step.title || ru.flow.planTitle} lead={step.lead} />
<ul className="plan">
{step.lines.map((l) => (
<li key={l} className="plan__item">
@@ -441,19 +434,20 @@ export function Flow() {
);
break;
case "choice":
body = (
<>
<Head title={step.title} lead={step.lead} />
<Choice key={stepKey} options={step.options} busy={dialog.busy} onSubmit={press} />
</>
);
lead = <Head title={step.title} lead={step.lead} />;
act = <Choice key={stepKey} options={step.options} busy={dialog.busy} onSubmit={press} />;
break;
}
content = (
<div className="stack narrow" key={stepKey}>
<div className="focus" key={stepKey}>
{top}
{body}
{dialog.error && <Notice tone="danger">{ru.common.networkError}</Notice>}
<div className={`split split--${step.kind}`}>
<div className="split__lead">{lead}</div>
<div className="split__act">
{act}
{dialog.error && <Notice tone="danger">{ru.common.networkError}</Notice>}
</div>
</div>
</div>
);
}