fix(pwa/repairs): drop duplicate mileage input under «Замена масла»
При создании/редактировании ремонта в форме был отдельный «Пробег на момент замены» внутри блока замены масла — auto-sync от шапочного с soft-dirty флагом по У24. На практике это всё равно заставляло механика вводить значение дважды, если шапочный пробег вводился вручную (StarLine недоступен): момент включения галочки случался после ручного ввода, soft-sync не успевал отработать или механик не понимал что поле автозаполнилось. Упростили: единственный пробег — «Пробег (км)» в шапке формы. На submit он же подставляется в oil_change.mileage_at_change. Поле «Следующая через» оставили — это интервал, а не значение пробега. Бэкенд не трогаем — схема та же (mileage_at_change всё ещё в payload).
This commit is contained in:
@@ -67,8 +67,6 @@ interface PartRow {
|
|||||||
|
|
||||||
interface OilChangeState {
|
interface OilChangeState {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
mileage_at_change: number | null;
|
|
||||||
mileage_is_dirty: boolean; // У24: мягкая подписка с шапочным
|
|
||||||
next_in_km: number;
|
next_in_km: number;
|
||||||
sticker: PhotoState | null;
|
sticker: PhotoState | null;
|
||||||
}
|
}
|
||||||
@@ -107,8 +105,6 @@ export default function CreateRepairPage() {
|
|||||||
const [parts, setParts] = useState<PartRow[]>([]);
|
const [parts, setParts] = useState<PartRow[]>([]);
|
||||||
const [oilChange, setOilChange] = useState<OilChangeState>({
|
const [oilChange, setOilChange] = useState<OilChangeState>({
|
||||||
enabled: false,
|
enabled: false,
|
||||||
mileage_at_change: null,
|
|
||||||
mileage_is_dirty: false,
|
|
||||||
next_in_km: 10000,
|
next_in_km: 10000,
|
||||||
sticker: null,
|
sticker: null,
|
||||||
});
|
});
|
||||||
@@ -130,13 +126,9 @@ export default function CreateRepairPage() {
|
|||||||
.catch((e) => setCtxError((e as Error).message || "Не удалось загрузить машину"));
|
.catch((e) => setCtxError((e as Error).message || "Не удалось загрузить машину"));
|
||||||
}, [carId]);
|
}, [carId]);
|
||||||
|
|
||||||
// У24: мягкая подписка пробега блока масла на шапочный.
|
// У24 упрощено: пробег ввода в форме теперь один — главный «Пробег (км)»
|
||||||
useEffect(() => {
|
// в шапке. На submit подставляется и в oil_change.mileage_at_change, чтобы
|
||||||
if (oilChange.enabled && !oilChange.mileage_is_dirty) {
|
// не заставлять механика вводить одно и то же дважды.
|
||||||
setOilChange((oc) => ({ ...oc, mileage_at_change: mileage }));
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
||||||
}, [mileage, oilChange.enabled]);
|
|
||||||
|
|
||||||
// ── Photo upload ─────────────────────────────────────────────────────────
|
// ── Photo upload ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -325,7 +317,8 @@ export default function CreateRepairPage() {
|
|||||||
oil_change: oilChange.enabled
|
oil_change: oilChange.enabled
|
||||||
? {
|
? {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
mileage_at_change: oilChange.mileage_at_change,
|
// Один источник истины — главный пробег ремонта (см. У24).
|
||||||
|
mileage_at_change: mileage,
|
||||||
next_in_km: oilChange.next_in_km,
|
next_in_km: oilChange.next_in_km,
|
||||||
sticker_photo_uuid:
|
sticker_photo_uuid:
|
||||||
oilChange.sticker?.status === "uploaded"
|
oilChange.sticker?.status === "uploaded"
|
||||||
@@ -625,21 +618,6 @@ 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>
|
|
||||||
<Input
|
|
||||||
type="number"
|
|
||||||
min={0}
|
|
||||||
value={oilChange.mileage_at_change ?? ""}
|
|
||||||
onChange={(e) =>
|
|
||||||
setOilChange((oc) => ({
|
|
||||||
...oc,
|
|
||||||
mileage_at_change: e.target.value === "" ? null : Number(e.target.value),
|
|
||||||
mileage_is_dirty: true,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<Label className="text-sm">Следующая замена через (км)</Label>
|
<Label className="text-sm">Следующая замена через (км)</Label>
|
||||||
<Input
|
<Input
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ interface PartRow {
|
|||||||
|
|
||||||
interface OilState {
|
interface OilState {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
mileage_at_change: number | null;
|
|
||||||
next_in_km: number | null;
|
next_in_km: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +59,7 @@ export default function EditRepairPage() {
|
|||||||
const [mileage, setMileage] = useState<number | null>(null);
|
const [mileage, setMileage] = useState<number | null>(null);
|
||||||
const [works, setWorks] = useState<WorkRow[]>([]);
|
const [works, setWorks] = useState<WorkRow[]>([]);
|
||||||
const [parts, setParts] = useState<PartRow[]>([]);
|
const [parts, setParts] = useState<PartRow[]>([]);
|
||||||
const [oil, setOil] = useState<OilState>({ enabled: false, mileage_at_change: null, next_in_km: null });
|
const [oil, setOil] = useState<OilState>({ enabled: false, next_in_km: null });
|
||||||
|
|
||||||
const [worksPicker, setWorksPicker] = useState<{ open: boolean; q: string; results: MechWork[] }>(
|
const [worksPicker, setWorksPicker] = useState<{ open: boolean; q: string; results: MechWork[] }>(
|
||||||
{ open: false, q: "", results: [] }
|
{ open: false, q: "", results: [] }
|
||||||
@@ -89,7 +88,6 @@ export default function EditRepairPage() {
|
|||||||
if (d.oil_change) {
|
if (d.oil_change) {
|
||||||
setOil({
|
setOil({
|
||||||
enabled: true,
|
enabled: true,
|
||||||
mileage_at_change: d.oil_change.mileage_at_change,
|
|
||||||
next_in_km: d.oil_change.next_in_km,
|
next_in_km: d.oil_change.next_in_km,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -174,7 +172,8 @@ export default function EditRepairPage() {
|
|||||||
qty: p.qty,
|
qty: p.qty,
|
||||||
})),
|
})),
|
||||||
oil_change: oil.enabled
|
oil_change: oil.enabled
|
||||||
? { enabled: true, mileage_at_change: oil.mileage_at_change, next_in_km: oil.next_in_km }
|
// Один источник истины — главный пробег ремонта.
|
||||||
|
? { enabled: true, mileage_at_change: mileage, next_in_km: oil.next_in_km }
|
||||||
: { enabled: false, mileage_at_change: null, next_in_km: null },
|
: { enabled: false, mileage_at_change: null, next_in_km: null },
|
||||||
});
|
});
|
||||||
navigate(`/repairs/${detail.id}`, { replace: true });
|
navigate(`/repairs/${detail.id}`, { replace: true });
|
||||||
@@ -343,19 +342,7 @@ export default function EditRepairPage() {
|
|||||||
Замена масла
|
Замена масла
|
||||||
</label>
|
</label>
|
||||||
{oil.enabled && (
|
{oil.enabled && (
|
||||||
<div className="mt-3 grid grid-cols-2 gap-2">
|
<div className="mt-3">
|
||||||
<div>
|
|
||||||
<Label className="text-xs">Пробег</Label>
|
|
||||||
<Input
|
|
||||||
type="number"
|
|
||||||
inputMode="numeric"
|
|
||||||
value={oil.mileage_at_change ?? ""}
|
|
||||||
onChange={(e) => setOil((o) => ({
|
|
||||||
...o, mileage_at_change: e.target.value === "" ? null : Number(e.target.value),
|
|
||||||
}))}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<Label className="text-xs">Через, км</Label>
|
<Label className="text-xs">Через, км</Label>
|
||||||
<Input
|
<Input
|
||||||
type="number"
|
type="number"
|
||||||
@@ -366,7 +353,6 @@ export default function EditRepairPage() {
|
|||||||
}))}
|
}))}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user