feat(pwa): rename Салон→Салон перед, add Салон зад + Багажник slots

Extract photo slots to tested lib/inspectionSlots; rename interior label,
add interior-rear + trunk slots (all inspection types). 3 new tests.

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
2026-06-05 18:49:31 +03:00
co-authored by claude-flow
parent b2969f36c3
commit 416ea3391b
3 changed files with 57 additions and 24 deletions
@@ -0,0 +1,18 @@
import { slotsForType } from "@/lib/inspectionSlots";
test("Салон перед (ключ interior сохранён) + Салон зад + Багажник", () => {
const slots = slotsForType("handover");
expect(slots.find((s) => s.side === "interior")?.label).toBe("Салон перед");
expect(slots.find((s) => s.side === "interior-rear")?.label).toBe("Салон зад");
expect(slots.find((s) => s.side === "trunk")?.label).toBe("Багажник");
});
test("порядок: Салон перед → Салон зад → Багажник идут подряд", () => {
const sides = slotsForType("return").map((s) => s.side);
const i = sides.indexOf("interior");
expect(sides.slice(i, i + 3)).toEqual(["interior", "interior-rear", "trunk"]);
});
test("набор одинаков для всех типов (унифицировано)", () => {
expect(slotsForType("periodic")).toEqual(slotsForType("handover"));
});
@@ -0,0 +1,37 @@
/**
* Слоты фото осмотра авто. Вынесены из InspectionEditor, чтобы быть покрытыми
* тестами. Все типы осмотров (приёмка/выдача/плановый/ad-hoc) показывают один
* набор — фидбек: общее состояние машины фиксируем всегда.
*
* ВАЖНО: `side` — стабильный ключ слота (часть S3-ключа фото и значение
* PhotoSide на бэке). Подпись (`label`) менять можно, ключ — нет, иначе уже
* снятые фото осиротеют. Поэтому «Салон перед» имеет ключ `interior` (бывш. «Салон»).
*/
export interface InspectionSlot {
side: string;
label: string;
}
export const SLOTS_GENERAL: InspectionSlot[] = [
{ side: "front", label: "Перед" },
{ side: "rear", label: "Зад" },
{ side: "left", label: "Левый бок" },
{ side: "right", label: "Правый бок" },
{ side: "vin", label: "VIN" },
{ side: "odometer", label: "Одометр" },
{ side: "interior", label: "Салон перед" },
{ side: "interior-rear", label: "Салон зад" },
{ side: "trunk", label: "Багажник" },
{ side: "free", label: "Свободное" },
];
export const SLOT_JACK: InspectionSlot = { side: "jack", label: "Домкрат" };
// Шильдик замены масла — отдельный слот при выдаче/приёмке. Фото нужно как для
// сверки текущего пробега со следующим ТО, так и для контроля что водитель не
// клеит свой стикер.
export const SLOT_OIL_STICKER: InspectionSlot = { side: "oil-sticker", label: "Шильдик замены масла" };
export function slotsForType(_type: string): InspectionSlot[] {
return [...SLOTS_GENERAL, SLOT_JACK, SLOT_OIL_STICKER];
}
@@ -25,30 +25,8 @@ import { loadZoneLabels } from "@/data/zoneLabels";
import { damageTypeRuToEnum } from "@/data/damageVocabulary"; import { damageTypeRuToEnum } from "@/data/damageVocabulary";
import { ttImageUrl } from "@/api/vehicles"; import { ttImageUrl } from "@/api/vehicles";
const SLOTS_GENERAL: { side: string; label: string }[] = [ // Слоты фото осмотра — в @/lib/inspectionSlots (покрыто тестами).
{ side: "front", label: "Перед" }, import { slotsForType } from "@/lib/inspectionSlots";
{ side: "rear", label: "Зад" },
{ side: "left", label: "Левый бок" },
{ side: "right", label: "Правый бок" },
{ side: "vin", label: "VIN" },
{ side: "odometer", label: "Одометр" },
{ side: "interior", label: "Салон" },
{ side: "free", label: "Свободное" },
];
const SLOT_JACK = { side: "jack", label: "Домкрат" };
// Шильдик замены масла — отдельный слот при выдаче/приёмке.
// Фото нужно как для сверки текущего пробега со следующим ТО, так и для
// контроля что водитель не клеит свой стикер.
const SLOT_OIL_STICKER = { side: "oil-sticker", label: "Шильдик замены масла" };
/** Все типы осмотров (выдача/приёмка/плановый/...) показывают одинаковый
* набор слотов общих ракурсов + домкрат. Раньше «return» исключал общие
* фото в пользу скорости приёмки, но фидбек: при приёмке всё равно надо
* фиксировать общее состояние машины, как и при выдаче/осмотре. */
function slotsForType(_type: string): typeof SLOTS_GENERAL {
return [...SLOTS_GENERAL, SLOT_JACK, SLOT_OIL_STICKER];
}
const SEVERITY_LABELS: Record<string, string> = { const SEVERITY_LABELS: Record<string, string> = {
cosmetic: "косметика", cosmetic: "косметика",