fix: UI polish for intake form, dashboard cards, and schedule (#142)
- Intake form: replace remind checkbox with bell icon + toggle switch - Intake form: smart takenBy dropdown based on medication's people - Dashboard: hide DETAILS row for pill bottles on mobile cards - Dashboard: use status-chip with icons in schedule view (past/today/future) - Dashboard: reduce spacing between icons and status chips on mobile - MedDetailModal: show package type in PACKAGE DETAILS heading - PlannerPage: show dash for bottle blisters column - Shorten Pill Bottle label in EN/DE translations - Update related tests
This commit is contained in:
@@ -439,9 +439,12 @@ export function DashboardPage() {
|
||||
? t("table.pillsCount", { count: Math.round(row.medsLeft) })
|
||||
: formatFullBlisters(stock.fullBlisters, t)}
|
||||
</span>
|
||||
<span data-label={t("table.stockDetails")} className={textClass}>
|
||||
<span
|
||||
data-label={t("table.stockDetails")}
|
||||
className={`${textClass}${med?.packageType === "bottle" ? " hide-on-card" : ""}`}
|
||||
>
|
||||
{med?.packageType === "bottle"
|
||||
? "-"
|
||||
? "—"
|
||||
: formatOpenBlisterAndLoose(
|
||||
stock.openBlisterPills,
|
||||
stock.loosePills,
|
||||
@@ -597,6 +600,9 @@ export function DashboardPage() {
|
||||
const med = meds.find((m) => m.name === item.medName);
|
||||
const medCov = coverageByMed[item.medName];
|
||||
const isEmpty = medCov ? medCov.medsLeft <= 0 : false;
|
||||
const status = medCov
|
||||
? getStockStatus(medCov.daysLeft, medCov.medsLeft, stockThresholds)
|
||||
: null;
|
||||
const itemDoseIds = expandDoseIds(item.doses);
|
||||
const allTaken = itemDoseIds.every((id) => takenDoses.has(id));
|
||||
return (
|
||||
@@ -623,6 +629,9 @@ export function DashboardPage() {
|
||||
<span className="tag subtle">
|
||||
{item.total} {t("common.pills")} {t("common.total")}
|
||||
</span>
|
||||
{status && (
|
||||
<span className={`status-chip small ${status.className}`}>{t(status.label)}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="doses-col">
|
||||
@@ -772,7 +781,9 @@ export function DashboardPage() {
|
||||
<span className="tag subtle">
|
||||
{item.total} {t("common.pills")} {t("common.total")}
|
||||
</span>
|
||||
{status && <span className={`tag ${status.className}`}>{t(status.label)}</span>}
|
||||
{status && (
|
||||
<span className={`status-chip small ${status.className}`}>{t(status.label)}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="doses-col">
|
||||
@@ -959,7 +970,9 @@ export function DashboardPage() {
|
||||
<span className="tag subtle">
|
||||
{item.total} {t("common.pills")} {t("common.total")}
|
||||
</span>
|
||||
{status && <span className={`tag ${status.className}`}>{t(status.label)}</span>}
|
||||
{status && (
|
||||
<span className={`status-chip small ${status.className}`}>{t(status.label)}</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="doses-col">
|
||||
|
||||
@@ -632,7 +632,11 @@ export function MedicationsPage() {
|
||||
<div className="card-head">
|
||||
<h3>{t("form.blisters.title")}</h3>
|
||||
<div className="blisters-actions">
|
||||
<button type="button" className="primary" onClick={() => addIntake()}>
|
||||
<button
|
||||
type="button"
|
||||
className="primary"
|
||||
onClick={() => addIntake(form.takenBy.length === 1 ? form.takenBy[0] : undefined)}
|
||||
>
|
||||
+ {t("form.blisters.addIntake")}
|
||||
</button>
|
||||
</div>
|
||||
@@ -675,25 +679,29 @@ export function MedicationsPage() {
|
||||
onChange={(e) => setIntakeValue(idx, "startTime", e.target.value)}
|
||||
/>
|
||||
</label>
|
||||
<label title={t("form.blisters.takenByTooltip")}>
|
||||
{t("form.blisters.takenByIntake")}
|
||||
<select value={intake.takenBy} onChange={(e) => setIntakeValue(idx, "takenBy", e.target.value)}>
|
||||
<option value="">{t("form.blisters.takenByEveryone")}</option>
|
||||
{existingPeople.map((person) => (
|
||||
<option key={person} value={person}>
|
||||
{person}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
<label className="inline-checkbox" title={t("form.blisters.remindTooltip")}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={intake.intakeRemindersEnabled}
|
||||
onChange={(e) => setIntakeValue(idx, "intakeRemindersEnabled", e.target.checked)}
|
||||
/>
|
||||
{form.takenBy.length === 0 ? null : (
|
||||
<label title={t("form.blisters.takenByTooltip")}>
|
||||
{t("form.blisters.takenByIntake")}
|
||||
<select value={intake.takenBy} onChange={(e) => setIntakeValue(idx, "takenBy", e.target.value)}>
|
||||
{form.takenBy.map((person) => (
|
||||
<option key={person} value={person}>
|
||||
{person}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
)}
|
||||
<div className="remind-toggle-row" title={t("form.blisters.remindTooltip")}>
|
||||
<span>🔔</span>
|
||||
</label>
|
||||
<label className="toggle-switch small">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={intake.intakeRemindersEnabled}
|
||||
onChange={(e) => setIntakeValue(idx, "intakeRemindersEnabled", e.target.checked)}
|
||||
/>
|
||||
<span className="toggle-slider"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{form.intakes.length > 1 && (
|
||||
<button type="button" className="danger" onClick={() => removeIntake(idx)}>
|
||||
|
||||
@@ -213,9 +213,7 @@ export function PlannerPage() {
|
||||
<strong>{row.plannerUsage}</strong> {t("common.pills")}
|
||||
</span>
|
||||
<span data-label={t("planner.table.blisters")}>
|
||||
{row.packageType === "bottle"
|
||||
? `${row.plannerUsage} ${t("common.pills")}`
|
||||
: `${row.blistersNeeded} × ${row.blisterSize}`}
|
||||
{row.packageType === "bottle" ? "–" : `${row.blistersNeeded} × ${row.blisterSize}`}
|
||||
</span>
|
||||
<span data-label={t("planner.table.available")}>
|
||||
{row.packageType === "bottle" ? (
|
||||
|
||||
Reference in New Issue
Block a user