diff --git a/mechanic-pwa/frontend/src/App.tsx b/mechanic-pwa/frontend/src/App.tsx index 661f6dc..9ab210c 100644 --- a/mechanic-pwa/frontend/src/App.tsx +++ b/mechanic-pwa/frontend/src/App.tsx @@ -39,6 +39,7 @@ export default function App() { } /> } /> } /> + } /> } /> } /> } /> diff --git a/mechanic-pwa/frontend/src/pages/repairs/CreateRepairPage.tsx b/mechanic-pwa/frontend/src/pages/repairs/CreateRepairPage.tsx index 887ba1d..261e495 100644 --- a/mechanic-pwa/frontend/src/pages/repairs/CreateRepairPage.tsx +++ b/mechanic-pwa/frontend/src/pages/repairs/CreateRepairPage.tsx @@ -15,7 +15,7 @@ * Сохранение: POST /repairs с `Idempotency-Key` (UUID v4 в state). */ import { useEffect, useMemo, useRef, useState } from "react"; -import { useNavigate, useParams } from "react-router-dom"; +import { useNavigate, useParams, useLocation } from "react-router-dom"; import { ChevronLeft, Plus, Trash2, Pencil, Camera } from "lucide-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; @@ -94,6 +94,9 @@ function uuid4(): string { export default function CreateRepairPage() { const navigate = useNavigate(); const { carId: carIdRaw } = useParams<{ carId: string }>(); + const location = useLocation(); + const isExternal = !carIdRaw; + const externalState = location.state as { plate: string; make: string | null } | null; const carId = carIdRaw ? Number(carIdRaw) : 0; // Idempotency-Key для этой формы — стабилен между ре-сабмитами (У20). @@ -120,6 +123,24 @@ export default function CreateRepairPage() { // Initial: подгрузить контекст машины. useEffect(() => { + if (isExternal) { + if (!externalState) { + // Прямой заход/рефреш без данных — возвращаем к выбору машины. + navigate("/repairs/new", { replace: true }); + return; + } + setCtx({ + id: 0, + plate: externalState.plate, + brand: externalState.make, + model: null, + mileage_starline: null, + driver_id: null, + driver_name: null, + }); + setMileage(null); + return; + } if (!carId) return; getCarContext(carId) .then((c) => { @@ -127,7 +148,8 @@ export default function CreateRepairPage() { setMileage(c.mileage_starline); }) .catch((e) => setCtxError((e as Error).message || "Не удалось загрузить машину")); - }, [carId]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [carId, isExternal]); // У24 упрощено: пробег ввода в форме теперь один — главный «Пробег (км)» // в шапке. На submit подставляется и в oil_change.mileage_at_change, чтобы @@ -307,7 +329,9 @@ export default function CreateRepairPage() { })); const result = await createRepair( { - car_id: carId, + ...(isExternal + ? { external_car: { plate: externalState!.plate, make: externalState!.make } } + : { car_id: carId }), mileage, works: works.map((w) => ({ work_catalog_id: w.work_catalog_id, @@ -385,7 +409,11 @@ export default function CreateRepairPage() {
{ctx.plate}
{[ctx.brand, ctx.model].filter(Boolean).join(" ")} - {ctx.driver_name ? ` · ${ctx.driver_name}` : ` · Без водителя`} + {isExternal + ? " · С улицы" + : ctx.driver_name + ? ` · ${ctx.driver_name}` + : " · Без водителя"}