repairs: тип масла в блоке замены (двигатель/вариатор/АКПП)
Для отчётов СТО по замене масла (задача 4078) нужно различать двигатель и трансмиссию. В блоке «Замена масла» добавлен выбор типа oil_type (engine|cvt|akpp) и он уходит в payload create. Для вариатора/АКПП поле «следующая через (км)» скрыто — интервал задаётся по модели в отчёте СТО. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -61,6 +61,7 @@ export interface CreateOilChangePayload {
|
|||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
mileage_at_change: number | null;
|
mileage_at_change: number | null;
|
||||||
next_in_km: number;
|
next_in_km: number;
|
||||||
|
oil_type: string; // engine | cvt | akpp
|
||||||
sticker_photo_uuid: string | null;
|
sticker_photo_uuid: string | null;
|
||||||
sticker_extension: string | null;
|
sticker_extension: string | null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,11 +61,14 @@ interface PartRow {
|
|||||||
qty: number;
|
qty: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OilKind = "engine" | "cvt" | "akpp";
|
||||||
|
|
||||||
interface OilChangeState {
|
interface OilChangeState {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
mileage_at_change: number | null;
|
mileage_at_change: number | null;
|
||||||
mileage_is_dirty: boolean; // У24: мягкая подписка с шапочным
|
mileage_is_dirty: boolean; // У24: мягкая подписка с шапочным
|
||||||
next_in_km: number;
|
next_in_km: number;
|
||||||
|
oil_type: OilKind;
|
||||||
sticker: PhotoState | null;
|
sticker: PhotoState | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,6 +101,7 @@ export default function CreateRepairPage() {
|
|||||||
mileage_at_change: null,
|
mileage_at_change: null,
|
||||||
mileage_is_dirty: false,
|
mileage_is_dirty: false,
|
||||||
next_in_km: 10000,
|
next_in_km: 10000,
|
||||||
|
oil_type: "engine",
|
||||||
sticker: null,
|
sticker: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -302,6 +306,7 @@ export default function CreateRepairPage() {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
mileage_at_change: oilChange.mileage_at_change,
|
mileage_at_change: oilChange.mileage_at_change,
|
||||||
next_in_km: oilChange.next_in_km,
|
next_in_km: oilChange.next_in_km,
|
||||||
|
oil_type: oilChange.oil_type,
|
||||||
sticker_photo_uuid:
|
sticker_photo_uuid:
|
||||||
oilChange.sticker?.status === "uploaded"
|
oilChange.sticker?.status === "uploaded"
|
||||||
? oilChange.sticker.presign.photo_uuid
|
? oilChange.sticker.presign.photo_uuid
|
||||||
@@ -579,6 +584,27 @@ export default function CreateRepairPage() {
|
|||||||
</label>
|
</label>
|
||||||
{oilChange.enabled && (
|
{oilChange.enabled && (
|
||||||
<div className="mt-3 space-y-3">
|
<div className="mt-3 space-y-3">
|
||||||
|
<div>
|
||||||
|
<Label className="text-sm">Тип масла</Label>
|
||||||
|
<div className="mt-1 grid grid-cols-3 gap-2">
|
||||||
|
{([["engine", "Двигатель"], ["cvt", "Вариатор"], ["akpp", "АКПП"]] as [OilKind, string][]).map(
|
||||||
|
([v, l]) => (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
key={v}
|
||||||
|
onClick={() => setOilChange((oc) => ({ ...oc, oil_type: v }))}
|
||||||
|
className={`rounded-md border px-2 py-2 text-sm ${
|
||||||
|
oilChange.oil_type === v
|
||||||
|
? "border-primary bg-primary/10 font-medium text-primary"
|
||||||
|
: "border-input"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{l}
|
||||||
|
</button>
|
||||||
|
),
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-sm">Пробег на момент замены</Label>
|
<Label className="text-sm">Пробег на момент замены</Label>
|
||||||
<Input
|
<Input
|
||||||
@@ -594,17 +620,24 @@ export default function CreateRepairPage() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
{oilChange.oil_type === "engine" ? (
|
||||||
<Label className="text-sm">Следующая замена через (км)</Label>
|
<div>
|
||||||
<Input
|
<Label className="text-sm">Следующая замена через (км)</Label>
|
||||||
type="number"
|
<Input
|
||||||
min={0}
|
type="number"
|
||||||
value={oilChange.next_in_km}
|
min={0}
|
||||||
onChange={(e) =>
|
value={oilChange.next_in_km}
|
||||||
setOilChange((oc) => ({ ...oc, next_in_km: Number(e.target.value) || 0 }))
|
onChange={(e) =>
|
||||||
}
|
setOilChange((oc) => ({ ...oc, next_in_km: Number(e.target.value) || 0 }))
|
||||||
/>
|
}
|
||||||
</div>
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<p className="text-xs text-muted-foreground">
|
||||||
|
Интервал {oilChange.oil_type === "cvt" ? "вариатора" : "АКПП"} задаётся по модели авто в
|
||||||
|
отчёте СТО.
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-sm">Фото стикера (одно)</Label>
|
<Label className="text-sm">Фото стикера (одно)</Label>
|
||||||
<label className="mt-1 block border-2 border-dashed rounded-md p-4 text-center cursor-pointer hover:bg-accent/40">
|
<label className="mt-1 block border-2 border-dashed rounded-md p-4 text-center cursor-pointer hover:bg-accent/40">
|
||||||
|
|||||||
Reference in New Issue
Block a user