feat(pwa/repairs): show price per row + total sum header

В каждой карточке ленты ремонтов справа от строки работ выводим сумму
работ (works_total из бэка, без запчастей). Шапка над лентой переехала:
слева «Итого: NNN ₽ (X ремонтов)», справа кнопка «Обновить» (раньше
была одна сверху-справа).
This commit is contained in:
2026-05-25 21:52:24 +10:00
parent 3b7b2ae56d
commit fd0ec64da9
2 changed files with 34 additions and 3 deletions
@@ -14,6 +14,7 @@ export interface FeedItem {
mechanic_name: string;
works_preview: FeedWorkBrief[];
works_extra: number;
works_total: number; // сумма работ без запчастей
photo_url: string | null;
}
@@ -83,8 +83,19 @@ export default function RepairsFeedPage() {
</header>
<main className="flex-1 container max-w-2xl py-3 space-y-2">
{/* Refresh tap-area для не-touch юзкейса; жест pull-to-refresh — в PR-8. */}
<div className="flex items-center justify-end">
{/* Итого слева — сумма работ загруженных ремонтов; Обновить справа. */}
<div className="flex items-center justify-between">
<div className="text-sm">
<span className="text-muted-foreground">Итого:</span>{" "}
<span className="font-semibold tabular-nums">
{fmtMoney(items.reduce((s, it) => s + (it.works_total || 0), 0))}
</span>
{items.length > 0 && (
<span className="text-xs text-muted-foreground ml-2">
({items.length} {pluralRepairs(items.length)})
</span>
)}
</div>
<button
type="button"
onClick={handleRefresh}
@@ -176,13 +187,32 @@ function RepairRow({ item, onOpen }: { item: FeedItem; onOpen: () => void }) {
<div className="text-xs text-muted-foreground truncate">
Механик: {item.mechanic_name}
</div>
<div className="flex items-baseline justify-between gap-2">
<WorksLine works={item.works_preview.map((w) => w.name)} extra={item.works_extra} />
<div className="text-sm font-semibold tabular-nums flex-shrink-0">
{fmtMoney(item.works_total || 0)}
</div>
</div>
</div>
</button>
);
}
function fmtMoney(n: number): string {
return new Intl.NumberFormat("ru-RU", { maximumFractionDigits: 0 }).format(Math.round(n));
}
function pluralRepairs(n: number): string {
const mod10 = n % 10;
const mod100 = n % 100;
if (mod100 >= 11 && mod100 <= 14) return "ремонтов";
if (mod10 === 1) return "ремонт";
if (mod10 >= 2 && mod10 <= 4) return "ремонта";
return "ремонтов";
}
function WorksLine({ works, extra }: { works: string[]; extra: number }) {
// У40: ellipsis в одну строку. Соединяем имена работ через «·».
if (works.length === 0) return null;